• 首屏加载慢


    1 查看首屏加载时间

    performance.timing 是浏览器提供的一个对象,它包含了网页加载过程中各个关键阶段的 时间戳 数据,这些数据对于分析网页性能、识别加载瓶颈非常有用。

    首屏加载时间,指的是 浏览器从相应用户输入网址,到首屏内容渲染完成的时间
    此时整个网页不一定全部渲染完成,但需要展示当前视窗需要的内容;
    首屏加载是用户体验的重要环节。

    控制台输入

    (performance.timing.domComplete - performance.timing.navigationStart) / 1000
    // 2.043,表示首屏加载时间是2.043秒
    
    performance.getEntrier() // 查看每一个资源加载的时间
    
    • 1
    • 2
    • 3
    • 4
    • 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 事件处理程序执行完毕的时间,标志着整个页面加载周期的正式结束。
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2 解决方案

    2.1 减少入口文件体积(重要)

    路由懒加载,解析路由时才会加载组件

    const routes = [
      {
        path: "Blogs",
        name: "ShowBlogs",
        component: () => import('./components/ShowBlog.js')
      }
    ];
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.2 静态资源本地缓存

    • 后端返回资源:采用http缓存;
    • 前端合理利用localStorage;
    • CDN静态资源缓存:react、react-dom、react-router-dom、axios;

    2.3 UI框架按需加载(重要)

    • element-UI、antd按需引入;
     import { Button } from 'antd';
    
    • 1

    2.4 避免组件重复打包(重要)

    假设A.js文件是一个常用的库,有多个路由使用A.js文件,这样会造成重复下载;
    解决方案:在webpack的config文件中,修改CommonsChunkPlugin的配置 minChunks: 2;
    将使用2次及以上的包抽离出来,放进公共依赖文件中,避免重复加载组件;

    2.5 图片资源压缩(重要)

    对于页面上使用的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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.6 开启GZip压缩

    拆完包之后,再用gzip做一下压缩,安装compression-webpack-plugin
    webpack中配置压缩;

  • 相关阅读:
    (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
    华为设备链路聚合基础
    C++Qt开发——SMTP协议
    洛谷 Equalize the Remainders
    Vite3 + Vue2.7 环境搭建(TS)
    Mysql免安装版的root密码是多少
    【工具】idea 设置自动渲染注释
    Vue3 + Naive-ui Data Table 分页页码显示不全
    0077__浅析C++临时对象的产生相关问题
    右键菜单添加 Open Git Bash
  • 原文地址:https://blog.csdn.net/weixin_45678402/article/details/138162240