|
0 u4 R* v6 K' D, K! F4 I3 N/ ~ 原标题:实践指南-前端性能提升 270%cover 一、背景—当我们疲于开发一个接一个的需求时,很容易忘记去关注网站的性能,到了某一个节点,猛地发现,随着越来越多代码的堆积,网站变得越来越慢本文就是从这样的一个背景出发,着手优化网站的前端性能,并总结出一套开发习惯,让我们在日常开发时,也保持高性能,而不是又一次回过头来优化性能。 ; I3 G$ K2 S( k, n. Q' Y; u8 k
先来看看优化的成果,Lighthouse 的 Performance 评分合计提升 279%:指标名称优化前优化后提升Lighthouse Performance 评分2981279%FCP(First Contentful Paint 首次内容绘制)
' V$ [- B# T, x- I, F6 O9 o; M5 W) k 0.7s0.7sLCP(Largest Contentful Paint 最大内容绘制)6.2s2.5s248%TTI(Time to Interactive 可交互时间)10.1s2.1s480%Speed Index(速度指数)
% }& Z( F! f4 V 5.6s1.8311%TBT(Total Blocking Time 总阻塞时间)820ms120ms683%优化前后对比:
8 M: {. z* X# ~3 @; t9 c' z/ \ 优化前后对比 二、优化前—接下来就是介绍下优化前我们要做哪些事件:了解性能指标及测量工具 分析需要优化的地方 1. 了解测量工具及性能指标一开始我们只是感受到网站的页面打开时白屏时间较长,感觉性能是比较差的,那么具体有哪些性能指标需要去关注呢?
4 z0 `" H; M+ N/ c) q2 z 这里我使用的是 Chrome devtools 内置的 Lighthouse[1] ,Lighthouse 是一种开源的自动化工具,用于提高 Web 应用程序的质量 Lighthouse 会在一系列的测试下运行网页,比如不同尺寸的设备和不同的网络速度。 ' V$ A+ d. O4 a4 }: N
它还会检查页面对辅助功能指南的一致性,例如颜色对比度和 ARIA 最佳实践打开 Chrome devtools Lighthouse 即可使用在比较短的时间内,Lighthouse 可以给出这样一份报告。
; h; ]! Q1 ~% O9 ?/ Y 这份报告从 5 个方面来分析页面:性能、辅助功能、最佳实践、搜索引擎优化和 PWA。像性能方面,会给出一些常见的耗时统计。 5 e7 _- O2 [- P3 z; ]% S
优化前 1.1 PerformancePerformance 评分统计,包括了以下指标:1.1.1 FCPFCP 测量在用户导航到页面后浏览器呈现第一段 DOM 内容所花费的时间页面上的图像、非白色 元素和 SVG 被视为 DOM 内容;不包括 iframe 内的任何内容。 , P/ W1 J `0 Q1 E. V1 e
1.1.2 LCPLCP 测量视口中最大的内容元素何时呈现到屏幕上这近似于页面的主要内容对用户可见的时间需要注意的是 LCP 的计算是一个动态的过程,如下图最后的图片才是这个页面中的最大内容绘制的元素。 3 J4 F+ P4 J# T
lcp 1.1.3 TTITTI 测量页面完全交互所需的时间TTI 是如何计算的呢,如下图首先沿时间轴正向搜索时长至少为 5 秒的安静窗口(安静窗口是指没有长任务且不超过两个正在处理的网络 get 请求),然后沿时间轴反向搜索安静窗口之前的最后一个长任务,如果没有找到长任务,则在 FCP 步骤停止执行,TTI 就是安静窗口之前最后一个长任务的结束时间,如果没有找到长任务的话,则与 FCP 值相同。
* d0 X/ W8 L! M' S TTI 1.1.4 Speed IndexSpeed Index 衡量页面加载期间内容以视觉方式显示的速度Lighthouse 首先捕获浏览器中页面加载的视频,并计算帧之间的视觉进度1.1.5 TBTTBT 测量页面被阻止响应用户输入(例如鼠标点击、屏幕点击或键盘按下)的总时间。
) c) A: b% D2 w0 M2 K 通过添加 First Contentful Paint 和 Time to Interactive 之间所有长任务的阻塞部分来计算总和任何执行时间超过 50 毫秒的任务都是长任务50 毫秒后的时间量是阻塞部分。 # v/ W9 M& l4 h) \2 i5 w
例如,如果 Lighthouse 检测到一个 70 毫秒长的任务,则阻塞部分将为 20 毫秒如下图淡红色区域的时间总和就是这个页面的 TBT 分数TBT 1.2 最佳实践用于检测 Web 应用程序整体代码健康状况,包括是否包含文档类型、图片宽高比是否正确等等。 8 X* t1 c9 G) o5 `3 r% N8 Q
1.3 SEO用于检测搜索引擎对网页内容的理解程度2. 分析需要优化的地方了解了关键的性能指标后,就可以测量看看当前网站的性能了,上面看到综合评分是非常低的,Lighthouse 给出了应该从哪些地方开始优化的建议。
. t* H9 P& v6 y# w 2.1 Performance性能优化建议主要包括以下几点:减少未使用的 JS; 合理使用图片的格式,webp 或者 avif 更快; 延迟加载不在视图的图片; JS 压缩; 图片的尺寸大小应该适当; . q9 ]: p3 N4 V! y/ A u- L
减少未使用的 CSS。
- j b/ Z. A; G* M 性能优化建议 Lighthouse 诊断出的网站存在的问题:需要加载的资源太多太大,有 147 个请求,合计 11mb; 有 40 个静态资源的缓存只有 1 小时 滚动事件没有添加标记 {passive: true}) ,导致需要等待侦听器完成执行后再滚动页面; 1 r+ ?, a% X) @. `) N8 I5 M* t
图像元素没有设置明确的宽度和高度; JS 文件太多,主线程工作量太大、JS 执行时间太长; ( X8 M0 m) U% B+ p* D! e5 o5 m% q
存在的问题 2.2 最佳实践最佳实践方面有以下问题:图片的分辨率太低,清晰度不够; 没有设置 CSP 策略。
T- p6 y" t1 e9 L0 b# q 最佳实践的问题 2.3 SEOSEO 有以下问题:没有 meta deion; 图片没有 alt 属性; robots.txt 是无效的。 0 ~/ _1 W% G7 m6 f* L/ F
SEO的问题 三、优化 Performance—根据上面 Lighthouse 报告,捋一捋项目中影响性能最大的因素,包括以下几点:体积太大,达 11mb; 图片太大,图片格式也有影响 1. 体积优化1.1 代码压缩 * N# g! m4 v8 U. } c# r/ a2 I
检查是否还有压缩空间,或者有无工具库未压缩的1.2 代码分包通过 webpack-bundle-analyzer 插件分析包体积,将一些大的 npm 包和 runtimeChunk 独立分包,减小包体积。
4 A, W. l7 v6 v 1.3 组件按需加载React.lazy + Suspense 封装懒加载组件,路由级组件引入懒加载组件同时使用骨架屏作为懒加载的兜底组件,可以让用户感知加载更快在鼠标移入导航栏时预加载路由组件,可以加快页面展示。 1 d* Z1 G( ? |2 s# _1 T
1.4 工具库按需加载通过 import(xx).then(xx) 按需加载工具库1.5 静态资源上传 CDN项目内有一些 json 文件存储的静态数据,这部分文件上传至 CDN,改为 fetch 的方式按需引入。
! Z- u X; W& Z6 L; v8 i+ a: o 1.6 删除不需要的资源检查项目中引入的 mf、npm 资源,将没有使用到的删除1.7 避免重复的 npm 包引入发现业务组件库通过 npm 引入的原子组件库,而项目本身又是通过 mf 引入的原子组件库,相对于引入了 2 遍原子组件库。
" ~) o T6 ?. Y4 r7 W4 h; x; s 这时就需要改造业务组件库,也改成用 mf 的方法引入1.8 避免 esm 依赖嵌套因为 webpack 的按需加载是通过 import、export 来标记的,因此想要一个好的按需加载的效果,就需要避免依赖嵌套的问题。 , Z* `2 M9 ]' J. I3 a
1.9 图标按需加载原子组件库 mf 暴露的方式会导致只用了 1 个 icon,就会加载组件库下所有 icon 对应的 chunk,导致资源浪费新建一个 icon 的 npm 包用于 icon 的按需引入。
- U. H5 y1 A3 M# |. n 1.10 小结通过以上优化手段,体积从 11.7mb 降低至 1.1mb,降低 10.6 倍优化前:优化前 优化后:优化后 2. 图片优化1.1 图片懒加载对非首屏的图片采用图片懒加载策略1.2 图片尺寸。
7 l7 j- A' j8 F 使用图片时,设置图片的合理尺寸1.3 图片格式设置优先使用 webp 格式图片四、优化最佳实践—1. 设置 CSP 策略2. 设置合理的图片的分辨率优化项目内的图片分辨率五、优化 SEO—1. meta deion、keywords 优化。 $ f6 V. _. \: e) ]( C* a
详细的 meta deion、keywords 可以加快 SEO < metaname= "deion"content= "xx"。
6 h/ w4 V) A# p, O" F /> 2. 图片加上 alt 属性 六、优化前后对比—再来回顾下前后对比:优化前,明显的感知白屏时间长:优化前 优化后,在清缓存的情况下也能实现秒开:
! Z$ m5 i: A- z$ L3 N 优化后 整体性能提升 270%:优化前后对比 七、性能监控—为了在后续的迭代过程中,保持高性能,引入内部前端监控平台 - 烛龙[2] ,可视化的监控前端性能 第一步,加载 cdn 插件:< defersrc
- i Z& F7 Q) W7 v5 ^2 K7 C/ ^* X = "https://h5static.m.jd.com/act/jd-jssdk/latest/jd-jssdk.min.js"> 第二步,在入口文件中,初始化 cdn 插件:useEffect( 7 V z8 w0 Y$ `- z: n- i
=> { // 初始化测速组件,在这里可以打开一些控制的开关,如是否上报接口if(IS_PROD) { // @ts-ignorejmfe.profilerInit({ flag: xxx, // 这是应用ID,需要先在烛龙申请应用 1 ^2 E- H8 |, ?. @' O% P, X) }( U
autoReport: true, autoAddStaticReport: true, autoAddApiReport: true, autoAddImageReport: false, // 支持所有图片上报,如果图片多,切记关闭,否则存在性能问题
) @: D6 J5 D# G" B performanceReportTime: 8000, profilingRate: 1, }) } }, []) 第三步,查看监控数据:在烛龙平台,小工具性能评分达 96分:查看监控数据 第四步,新增告警,实时监控: ( \9 D% ~: ?8 K: U% J$ f
烛龙平台支持多维度的告警服务,增加性能指标相关的告警,在性能异动时,及时发现问题,优化性能新增告警 小结—本文详细介绍了一个前端项目优化的详细过程,从优化前的问题分析,到具体的优化措施,最终实现了前端性能提升了近 3 倍。
7 O7 z+ a5 F! I; x/ r R" u) D 同时也将性能指标落到监控平台,实现可视化的监控前端性能指标希望能对你有所帮助,感谢阅读~参考资料—[1]Lighthouse: https://developer.chrome.com/docs/lighthouse/ ! P- ^: u4 D! v6 [/ r3 Q: B, x5 I2 C
[2]烛龙: http://dra.jd.com/ [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
1 H2 @: c2 \" v6 S) C% ?2 C- l [4][5]PLUS 前端 H5 性能优化实践: http://sd.jd.com/article/2195?shareId=3946&isHideShareButton=1 END 谷歌开发全新搜索引擎Magi,由人工智能技术驱动 ]8 o. Z* O; I* X& k, r' o& N
? 活动推荐2023 年 5 月 27-28 日,GOTC 2023 全球开源技术峰会将在上海张 江科学会堂隆重举行为期 2 天的开源行业盛会,将以行业展览、主题发言、特别论坛、分论坛、快闪演讲的形式来诠释此次大会主题 ——“Open Source, Into the Future”。
7 I9 p7 `" Q) b$ b; Y2 N 与会者将一起探讨元宇宙、3D 与游戏、eBPF、Web3.0、区块链等热门技术主题,以及 OSPO、汽车软件、AIGC、开源教育培训、云原生、信创等热门话题,探讨开源未来,助力开源发展返回搜狐,查看更多。
7 c( @2 \5 X9 E) ]- W% p: |2 U+ r7 e 责任编辑: 1 f9 q2 n5 l0 F" _! A* C
+ ~% T- d% Y5 E; H2 @$ u" R; M) f
/ }5 e$ Z& Z' I
8 n2 {# j; ?7 [+ a0 ~1 S" }
! e8 q: K5 t0 l |