performance.timing 是浏览器提供的一个对象,它包含了网页加载过程中各个关键阶段的 时间戳 数据,这些数据对于分析网页性能、识别加载瓶颈非常有用。
首屏加载时间,指的是 浏览器从相应用户输入网址,到首屏内容渲染完成的时间 ;
此时整个网页不一定全部渲染完成,但需要展示当前视窗需要的内容;
首屏加载是用户体验的重要环节。
控制台输入
(performance.timing.domComplete - performance.timing.navigationStart) / 1000
// 2.043,表示首屏加载时间是2.043秒
performance.getEntrier() // 查看每一个资源加载的时间
- navigationStart:表示浏览器开始加载当前文档的起始时间,包括重定向开始的时间。整个导航计时的基准点。
- domLoading:开始解析HTML文档并构建 DOM 树的时间。
- domComplete:记录所有资源(包括图像、样式表、脚本等)加载完毕,DOM树构建完成,且所有 load 事件处理程序待触发的时间。此时
document.readyState变为"complete"。- domContentLoadedEventEnd:“DOMContentLoaded” 事件实际触发的时间,此时浏览器已经完成了DOM解析和CSSOM构建,大部分JavaScript脚本可以开始执行。
- loadEventStart: “load” 事件即将被触发的时间,标志着所有资源(包括子框架)已完全加载。
- loadEventEnd:“load” 事件实际触发并执行完成的时间,网页加载过程至此全部结束。
- connectStart:开始建立与服务器TCP连接的时间。这包括SSL/TLS握手(如果有)的时间。
- connectEnd:完成与服务器TCP连接建立的时间。此时,TCP连接已建立,可以开始发送HTTP请求。
- requestStart:发送HTTP请求(包括请求头)到服务器的时间。至此,浏览器完成了所有前期准备工作。
- responseStart:收到第一个字节的HTTP响应的时间。服务器开始返回数据。
- TCP连接建立耗时:connectEnd - connectStart
- 请求发送到接收响应首字节的耗时(网络往返时间): responseStart - requestStart
- 页面渲染准备时间(DOMContentLoaded):domContentLoadedEventEnd - navigationStart
- 完整页面加载时间(load事件):loadEventEnd - navigationStart
按照时间顺序
Object.entries(timing).sort(([, valueA], [, valueB]) => valueA - valueB);
[
[ 'navigationStart', 1713947661293 ], // 表示**浏览器开始加载当前文档的起始时间**,包括重定向开始的时间。整个导航计时的基准点。
[ 'redirectStart', 0 ], // 收到第一个字节的HTTP响应的时间。服务器开始返回数据。
[ 'redirectEnd', 0 ], // 收到完整HTTP响应(包括所有响应头部和正文)的时间。至此,服务器端的响应过程结束。
[ 'fetchStart', 1713947661294 ], // 记录浏览器开始为当前文档请求资源(如发起网络请求或从缓存中读取)的时间。如果资源来自缓存,这个时间可能早于 navigationStart。
[ 'domainLookupStart', 1713947661301 ], // 记录浏览器开始进行 DNS 解析(如果需要)的时间。如果使用持久连接、缓存或不需要 DNS 解析(如 file: 协议或同一源重新加载),则值等于 fetchStart。
[ 'domainLookupEnd', 1713947661301 ], // 记录 DNS 解析完成的时间。如果不需要 DNS 解析,则值等于 domainLookupStart。
[ 'connectStart', 1713947661301 ], // 开始建立与服务器TCP连接的时间。
[ 'secureConnectionStart', 1713947661331 ], // 如果当前连接使用了SSL/TLS协议,记录开始安全连接协商的时间。如果未使用SSL/TLS,值为0。
[ 'connectEnd', 1713947661368 ], // 完成与服务器TCP连接建立的时间。此时,TCP连接已建立,可以开始发送HTTP请求。
[ 'requestStart', 1713947661368 ], // 发送HTTP请求(包括请求头)到服务器的时间。至此,浏览器完成了所有前期准备工作。
[ 'responseStart', 1713947661411 ], // 收到第一个字节的HTTP响应的时间。服务器开始返回数据。
[ 'responseEnd', 1713947661413 ], // 记录浏览器接收到服务器响应的最后一个字节的时间,即整个响应接收完毕。
[ 'domLoading', 1713947661423 ], // 记录浏览器开始解析 HTML 文档并构建 DOM 树的时间。
[ 'domInteractive', 1713947661454 ], // 记录 DOM 树解析完成,脚本执行完毕,且页面处于交互状态(即 document.readyState 变为 "interactive")的时间。
[ 'domContentLoadedEventStart', 1713947661707 ], // 记录 DOMContentLoaded 事件开始触发的时间,此时DOM树已构建完成,样式表已解析完成,但外部脚本可能仍在加载和执行。
[ 'domContentLoadedEventEnd', 1713947661708 ], // 记录 DOMContentLoaded 事件处理程序执行完毕的时间。
[ 'domComplete', 1713947661728 ], // 记录所有资源(包括图像、样式表、脚本等)加载完毕(不包括可能仍在加载的非关键性资源),DOM树构建完成,且所有 load 事件处理程序待触发的时间。此时 document.readyState 变为 "complete"。页面处于可交互状态。
[ 'loadEventStart', 1713947661728 ], // 记录 load 事件开始触发的时间,标志着页面加载过程基本结束。
[ 'loadEventEnd', 1713947661759 ], // 记录 load 事件处理程序执行完毕的时间,标志着整个页面加载周期的正式结束。
]
路由懒加载,解析路由时才会加载组件
const routes = [
{
path: "Blogs",
name: "ShowBlogs",
component: () => import('./components/ShowBlog.js')
}
];
import { Button } from 'antd';
假设A.js文件是一个常用的库,有多个路由使用A.js文件,这样会造成重复下载;
解决方案:在webpack的config文件中,修改CommonsChunkPlugin的配置 minChunks: 2;
将使用2次及以上的包抽离出来,放进公共依赖文件中,避免重复加载组件;
对于页面上使用的icon,可以使用在线字体图标,或者雪碧图,将众多的小图标合并到一张图上,减轻http请求的压力;
.sprite-container {
background-image: url('path/to/sprite.png');
}
.icon-example1 {
width: /* 图标宽度 */;
height: /* 图标高度 */;
background-position: /* X坐标 */px /* Y坐标 */px;
}
.icon-example2 {
width: /* 图标宽度 */;
height: /* 图标高度 */;
background-position: /* X坐标 */px /* Y坐标 */px;
}
拆完包之后,再用gzip做一下压缩,安装compression-webpack-plugin
webpack中配置压缩;