您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
实践指南-前端性能提升 270%
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
实践指南-前端性能提升 270%
wd****
2023-07-24
IP归属:北京
8480浏览
![cover](https://img14.360buyimg.com/ling/jfs/t1/219666/3/25422/187127/642bd306F166d9f33/62ee73264ec76e6c.jpg) ## 一、背景 当我们疲于开发一个接一个的需求时,很容易忘记去关注网站的性能,到了某一个节点,猛地发现,随着越来越多代码的堆积,网站变得越来越慢。 本文就是从这样的一个背景出发,着手优化网站的前端性能,并总结出一套开发习惯,让我们在日常开发时,也保持高性能,而不是又一次回过头来优化性能。 先来看看优化的成果,Lighthouse 的 Performance 评分合计提升 279%: | 指标名称 | 优化前 | 优化后 | 提升 | | -------------------------------------------- | ------ | ------ | ---- | | Lighthouse Performance 评分 | 29 | 81 | 279% | | FCP(First Contentful Paint 首次内容绘制) | 0.7s | 0.7s | | | LCP(Largest Contentful Paint 最大内容绘制) | 6.2s | 2.5s | 248% | | TTI(Time to Interactive 可交互时间) | 10.1s | 2.1s | 480% | | Speed Index(速度指数) | 5.6s | 1.8 | 311% | | TBT(Total Blocking Time 总阻塞时间) | 820ms | 120ms | 683% | 优化前后对比: ![优化前后对比](https://img30.360buyimg.com/ling/jfs/t1/165203/31/36160/300424/642bbf22Fc6f16671/60d1c883cbc521ff.png.webp) ## 二、优化前 接下来就是介绍下优化前我们要做哪些事件: 1. 了解性能指标及测量工具 2. 分析需要优化的地方 ### 1. 了解测量工具及性能指标 一开始我们只是感受到网站的页面打开时白屏时间较长,感觉性能是比较差的,那么具体有哪些性能指标需要去关注呢? 这里我使用的是 Chrome devtools 内置的 [Lighthouse](https://developer.chrome.com/docs/lighthouse/),Lighthouse 是一种开源的自动化工具,用于提高 Web 应用程序的质量。 Lighthouse 会在一系列的测试下运行网页,比如不同尺寸的设备和不同的网络速度。它还会检查页面对辅助功能指南的一致性,例如颜色对比度和 ARIA 最佳实践。 打开 Chrome devtools Lighthouse 即可使用。 在比较短的时间内,Lighthouse 可以给出这样一份报告。 这份报告从 5 个方面来分析页面: 性能、辅助功能、最佳实践、搜索引擎优化和 PWA。像性能方面,会给出一些常见的耗时统计。 ![优化前](https://img13.360buyimg.com/ling/s800x0_jfs/t1/113682/26/36252/160266/642bbf7aFe03af0e8/3155447cded83669.png.webp) #### 1.1 Performance Performance 评分统计,包括了以下指标: ##### 1.1.1 FCP FCP 测量在用户导航到页面后浏览器呈现第一段 DOM 内容所花费的时间。页面上的图像、非白色`<canvas>`元素和 SVG 被视为 DOM 内容;不包括 iframe 内的任何内容。 ##### 1.1.2 LCP LCP 测量视口中最大的内容元素何时呈现到屏幕上。这近似于页面的主要内容对用户可见的时间。 需要注意的是 LCP 的计算是一个动态的过程,如下图最后的图片才是这个页面中的最大内容绘制的元素。 ![lcp](https://img13.360buyimg.com/ling/jfs/t1/97921/25/37599/505228/642bc02fFdb0a7617/55bdbab3841345b2.png.webp) ##### 1.1.3 TTI TTI 测量页面完全交互所需的时间。 TTI 是如何计算的呢,如下图首先延时间轴正向搜索时长至少为 5 秒的安静窗口(安静窗口是指没有长任务且不超过两个正在处理的网络 get 请求),然后沿时间轴反向搜索安静窗口之前的最后一个长任务,如果没有找到长任务,则在 FCP 步骤停止执行,TTI 就是安静窗口之前最后一个长任务的结束时间,如果没有找到长任务的话,则与 FCP 值相同。 ![TTI](https://img20.360buyimg.com/ling/jfs/t1/178971/40/34450/64381/642bc141F122ee65e/163dcf1ddabe5a63.png.webp) ##### 1.1.4 Speed Index Speed Index 衡量页面加载期间内容以视觉方式显示的速度。Lighthouse 首先捕获浏览器中页面加载的视频,并计算帧之间的视觉进度。 ##### 1.1.5 TBT TBT 测量页面被阻止响应用户输入(例如鼠标点击、屏幕点击或键盘按下)的总时间。 通过添加 First Contentful Paint 和 Time to Interactive 之间所有长任务的阻塞部分来计算总和。任何执行时间超过 50 毫秒的任务都是长任务。 50 毫秒后的时间量是阻塞部分。例如,如果 Lighthouse 检测到一个 70 毫秒长的任务,则阻塞部分将为 20 毫秒。 如下图淡红色区域的时间总和就是这个页面的 TBT 分数。 ![TBT](https://img10.360buyimg.com/ling/jfs/t1/158514/38/37114/24398/642bc1d4Fc0f18ca7/3c94635bcf517fc0.png.webp) #### 1.2 最佳实践 用于检测 Web 应用程序整体代码健康状况,包括是否包含文档类型、图片宽高比是否正确等等。 #### 1.3 SEO 用于检测搜索引擎对网页内容的理解程度。 ### 2. 分析需要优化的地方 了解了关键的性能指标后,就可以测量看看当前网站的性能了, 上面看到综合评分是非常低的,Lighthouse 给出了应该从哪些地方开始优化的建议。 #### 2.1 Performance 性能优化建议主要包括以下几点: - 减少未使用的 JS; - 合理使用图片的格式,webp 或者 avif 更快; - 延迟加载不在视图的图片; - JS 压缩; - 图片的尺寸大小应该适当; - 减少未使用的 CSS。 ![性能优化建议](https://img10.360buyimg.com/ling/s800x0_jfs/t1/217931/13/26408/85209/641aff78F14b48114/2e449063eceea125.png.webp) Lighthouse 诊断出的网站存在的问题: - 需要加载的资源太多太大,有 147 个请求,合计 11mb; - 有 40 个静态资源的缓存只有 1 小时 - 滚动事件没有添加标记`{passive: true})`,导致需要等待侦听器完成执行后再滚动页面; - 图像元素没有设置明确的宽度和高度; - JS 文件太多,主线程工作量太大、JS 执行时间太长; ![存在的问题](https://img12.360buyimg.com/ling/s800x0_jfs/t1/219688/15/27025/181094/641afff4F84ac0f8c/487d9de6f2678b4f.png.webp) #### 2.2 最佳实践 最佳实践方面有以下问题: - 图片的分辨率太低,清晰度不够; - 没有设置 CSP 策略。 ![最佳实践的问题](https://img13.360buyimg.com/ling/s800x0_jfs/t1/109028/18/33112/99796/641b03afF4073ce91/a02c61830aaeafc3.png.webp) #### 2.3 SEO SEO 有以下问题: - 没有 meta description; - 图片没有 alt 属性; - robots.txt 是无效的。 ![SEO的问题](https://img20.360buyimg.com/ling/s800x0_jfs/t1/103369/1/38905/118351/641b0489F59920b88/2b4138c95337db97.png.webp) ## 三、优化 Performance 根据上面 Lighthouse 报告,捋一捋项目中影响性能最大的因素,包括以下几点: - 体积太大,达 11mb; - 图片太大,图片格式也有影响。 ### 1. 体积优化 #### 1.1 代码压缩 检查是否还有压缩空间,或者有无工具库未压缩的。 #### 1.2 代码分包 通过 webpack-bundle-analyzer 插件分析包体积,将一些大的 npm 包和 runtimeChunk 独立分包,减小包体积。 #### 1.3 组件按需加载 React.lazy + Suspense 封装懒加载组件,路由级组件引入懒加载组件。 同时使用骨架屏作为懒加载的兜底组件,可以让用户感知加载更快。 在鼠标移入导航栏时预加载路由组件,可以加快页面展示。 #### 1.4 工具库按需加载 通过 import('xx').then(xx) 按需加载工具库。 #### 1.5 静态资源上传 CDN 项目内有一些 json 文件存储的静态数据,这部分文件上传至 CDN,改为 fetch 的方式按需引入。 #### 1.6 删除不需要的资源 检查项目中引入的 mf、npm 资源,将没有使用到的删除。 #### 1.7 避免重复的 npm 包引入 发现业务组件库通过 npm 引入的原子组件库,而项目本身又是通过 mf 引入的原子组件库,相对于引入了 2 遍原子组件库。 这时就需要改造业务组件库,也改成用 mf 的方法引入。 #### 1.8 避免 esm 依赖嵌套 因为 webpack 的按需加载是通过 import、export 来标记的,因此想要一个好的按需加载的效果,就需要避免依赖嵌套的问题。 #### 1.9 图标按需加载 原子组件库 mf 暴露的方式会导致只用了 1 个 icon,就会加载组件库下所有 icon 对应的 chunk,导致资源浪费。 新建一个 icon 的 npm 包用于 icon 的按需引入。 #### 1.10 小结 通过以上优化手段,体积从 11.7mb 降低至 1.1mb,降低 10.6 倍。 优化前: ![优化前](https://img30.360buyimg.com/ling/s800x0_jfs/t1/142577/37/35594/193379/641b205fFc53e6e7f/8054e11e4b1539d3.png.webp) 优化后: ![优化后](https://img10.360buyimg.com/ling/s800x0_jfs/t1/188969/6/33839/125463/641b1f75F09f05646/dff8da057e966e3d.png.webp) ### 2. 图片优化 #### 1.1 图片懒加载 对非首屏的图片采用图片懒加载策略。 #### 1.2 图片尺寸 使用图片时,设置图片的合理尺寸。 #### 1.3 图片格式设置 优先使用 webp 格式图片。 ## 四、优化最佳实践 ### 1. 设置 CSP 策略 ### 2. 设置合理的图片的分辨率 优化项目内的图片分辨率。 ## 五、优化 SEO ### 1. meta description、keywords 优化 详细的 meta description、keywords 可以加快 SEO。 ```html <meta name="keywords" content="xx" /> <meta name="description" content="xx" /> ``` ### 2. 图片加上 alt 属性 ```html <img src="smiley.gif" alt="Smiley face" /> ``` ## 六、优化前后对比 再来回顾下前后对比: 优化前,明显的感知白屏时间长: ![优化前](https://storage.360buyimg.com/jelly-client/1.gif) 优化后,在清缓存的情况下也能实现秒开: ![优化后](https://storage.360buyimg.com/jelly-client/2.gif) 整体性能提升 270%: ![优化前后对比](https://img30.360buyimg.com/ling/jfs/t1/165203/31/36160/300424/642bbf22Fc6f16671/60d1c883cbc521ff.png.webp) ## 七、性能监控 为了在后续的迭代过程中,保持高性能,引入内部前端监控平台 - [烛龙](http://dra.jd.com/),可视化的监控前端性能。 第一步,加载 cdn 插件: ```html <script defer src="https://h5static.m.jd.com/act/jd-jssdk/latest/jd-jssdk.min.js" ></script> ``` 第二步,在入口文件中,初始化 cdn 插件: ```jsx useEffect(() => { // 初始化测速组件,在这里可以打开一些控制的开关,如是否上报接口 if (IS_PROD) { // @ts-ignore jmfe.profilerInit({ flag: xxx, // 这是应用ID,需要先在烛龙申请应用 autoReport: true, autoAddStaticReport: true, autoAddApiReport: true, autoAddImageReport: false, // 支持所有图片上报,如果图片多,切记关闭,否则存在性能问题 performanceReportTime: 8000, profilingRate: 1, }) } }, []) ``` 第三步,查看监控数据: 在烛龙平台,小工具性能评分达 96分: ![查看监控数据](https://img20.360buyimg.com/ling/jfs/t1/113994/9/31180/710969/6437c296F2929d960/1438a222c3e1af0c.png.webp) 第四步,新增告警,实时监控 烛龙平台支持多维度的告警的服务,增加性能指标相关的告警,在性能异动时,及时发现问题,优化性能。 ## 小结 本文详细介绍了一个前端项目优化的详细过程,从优化前的问题分析,到具体的优化措施,最终实现了前端性能提升了近 3 倍。同时也将性能指标落到监控平台,实现可视化的监控前端性能指标。 希望能对你有所帮助,感谢阅读~ ## 参考资料 - [被删的前端游乐场-前端性能优化-归纳篇](https://godbasin.github.io/front-end-playground/front-end-basic/performance/front-end-performance-optimization.html#%E6%97%B6%E9%97%B4%E8%A7%92%E5%BA%A6%E4%BC%98%E5%8C%96-%E5%87%8F%E5%B0%91%E8%80%97%E6%97%B6) - [前端缓存 API 请求数据的解决方案](https://blog.csdn.net/qq_41581588/article/details/128565077) - [网易云课堂 Service Worker 运用与实践](https://mp.weixin.qq.com/s/3Ep5pJULvP7WHJvVJNDV-g) - [PLUS 前端 H5 性能优化实践](http://sd.jd.com/article/2195?shareId=3946&isHideShareButton=1)
上一篇:长连接:chatgpt流式响应背后的逻辑
下一篇:【实践篇】推荐算法PaaS化探索与实践
wd****
文章数
1
阅读量
212
作者其他文章
01
实践指南-前端性能提升 270%
一、背景当我们疲于开发一个接一个的需求时,很容易忘记去关注网站的性能,到了某一个节点,猛地发现,随着越来越多代码的堆积,网站变得越来越慢。本文就是从这样的一个背景出发,着手优化网站的前端性能,并总结出一套开发习惯,让我们在日常开发时,也保持高性能,而不是又一次回过头来优化性能。先来看看优化的成果,Lighthouse 的 Performance 评分合计提升 279%:指标名称优化前优化后提升Li
wd****
文章数
1
阅读量
212
作者其他文章
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号