前端性能优化不论是在面试中还是在理论开发过程中,都是每一个前端开发工程师都必不可少的能力。本文总结自己多年开发教训中对前端性能优化的了解,心愿对大家有所帮忙,因波及的优化方向较多,针对某些细节不再具体阐明,大家有趣味的可深刻理解,话不多说,注释开始。
重要性
一个好的前端我的项目性能十分重要,特地是面向 ToC 的用户,好的用户体验能够极大的进步业务转化率,从而性能的好坏关乎到业务的营收。对于一个商业性公司只有是和钱相干,都是极其敏感且重要的。
度量形式
2020 年 Google 提出了新一代 Web 性能体验指标 Core Web Vitals,其中包含了 LCP、FID、CLS 三大指标。
- Largest Contentful Paint (LCP): 掂量加载体验:为了提供良好的用户体验,LCP 应该在页面首次开始加载后的 2.5 秒内产生。
- First Input Delay (FID): 掂量可交互性,为了提供良好的用户体验,页面的 FID 该当小于 100 毫秒。
- Cumulative Layout Shift (CLS): 掂量视觉稳定性,为了提供良好的用户体验,页面的 CLS 应放弃小于 0.1。
针对这些指标间接能够通过浏览器开发工具中的 Lighthouse 得出是否达到规范。通过这样的形式得出的论断疾速直观,对本来网站无侵入,不影响实在用户的性能。然而也有毛病,不反对简单的业务逻辑场景,监测的数据量太小,不能还原大部分实在用户的应用状况。
所以为了失去实在且全面的数据,大部分的公司都会开发一套监测计划,或者应用第三方监测平台,这样会对网站有肯定的性能影响,然而可通过更全面的性能数据分析可优化的方向。
性能优化方向
基于下面的三个体验指标,咱们能够从页面加载的生命周期进行优化,页面加载前的预处理,加载过程中,页面渲染时,用户界面交互等几个阶段,上面将针对不同的阶段进行优化,大家可依据本人我的项目的状况针对性的抉择优化。
加载前的预处理
- 应用 dns-prefetch、preconnect 缩小 DNS 解析,建设 TCP 连贯以及执行 TLS 握手工夫,dns-prefetch: 告知浏览器对指定域名进行 DNS 解析。当后续申请该域名资源时可省掉 DNS 解析的工夫。preconnect: 告知浏览器与指定域名的服务器建设连贯。当后续申请该域名资源时,可间接应用已建设好的连贯,省掉了 DNS+TCP+TLS 的工夫
<link rel="dns-prefetch" href="https://s1.static.com">
<link rel="preconnect" href="https://s1.static.com">
- 应用 preload/prefetch 让浏览器提前加载须要的资源,preload 能够指明哪些资源是在页面加载实现后即刻须要的,浏览器在主渲染机制染指前就进行预加载,这一机制使得资源能够更早的失去加载并可用,且更不易阻塞页面的初步渲染,进而晋升性能;prefetch 其利用浏览器闲暇工夫来下载或预取用户在不久的未来可能拜访的文档。切记不要将 preload 和 prefetch 进行混用,它们实用于不同的场景,如对同一个资源同时应用 preload 和 prefetch 会造成不必要的二次下载。
<link href="xx.js" rel="prefetch">
<!--as 示意指定资源类型 -->
<link href="xx.js" rel="preload" as="script">
加载过程中
1. 尽可能的减小资源的大小
- 业务代码自身尽可能的不要反复,进步组件化的应用,提醒代码的复用率,这里不止是 JS,CSS 款式也是一样
- 压缩动态资源,个别脚手架都默认会解决,自建我的项目可查看是否有压缩
- html 中的 DOM 层级管制不要太深以及缩小不必要的 DOM 应用,尽可能施展伪元素及 CSS 的应用
- 查看我的项目的依赖包是否有反复援用的状况,不同的依赖包可能援用了同一个不同版本的包,可通过 webpack-bundle-analyzer 插件剖析查看
- UI 组件库或其余库应用 babel-plugin-import 插件进行按需加载
- 组件按需加载,应用 AsyncComponent 仅加载首屏组件
- 动静导入第三方比拟大的模块,import(‘/modules/echart.js) .then((module) => {}),但不要滥用,结合实际场景应用
- 减小第三方库的大小,如 Moment.js/lodash 等,应用轻量级别代替计划或者本人从新实现
- 对首评秒开要求较高的,可对首屏申请的接口进行拆分,疾速响应首屏须要用到的字段,其余的数据异步加载
- 应用 tree shaking,当咱们在我的项目中引入其余模块时,他会主动将咱们用不到的代码,或者永远不会执行的代码摇掉,在 Uglify 阶段查出,不打包到 bundle 中
- HTTP 头部 Cookie 的精简,去除不必要的 Cookie,动态资源做独立域名部署,防止申请携带 Cookie
- HTTP 头部开启 gzip 压缩,可大大减小网络传输的数据量
- HTTP 头部开启 keep-alive
- 降级 HTTP 到 2.0,2.0 的头部压缩,缩小了数据传输量,可能节俭音讯头占用的网络的流量,且还有多路复用等劣势
2. 尽可能的缩小资源的次数
- JS/CSS 数量不可太扩散,防止一下发动太多的申请,必要将局部资源合并在一起,缩小申请的数量。然而在合并的过程中需要在体积和数量之间衡量,并不是越少越好,可将最大的体积管制在一个范畴内进行合并
- 局部小体量级别的 JS/CSS 可内联到 HTML 中,缩小申请数量
- 减小预检申请 OPTIONS 的发动,可通过服务端设置 Access-Control-Max-Age 字段或改为发动简略申请
- 勾销有效申请,表单提交频繁点击,路由切换时还有未实现的申请。这些都会产生有效申请,对服务器和用户体验都是不好的
-
缓存策略
- 开启 http 强缓存与协商缓存,对于不同类型的资源应用不同的缓存策略
- 动态资源开启 CDN 服务
- 对于不常变动的数据包含内部 JS/CSS 资源,可进行前端浏览器缓存,缩小申请,但此类缓存需设定好革除及更新的机制
3. 其余资源优化
- 图片 webp 应用,对于反对的设施应用 webp
- 图片裁剪,针对应用场景进行相应的裁剪
- 大图不要打包在我的项目中,上传到独自的动态资源服务器或是 CDN 中
- 图片上传前进行压缩,切记不要应用原图
- 设置图片标签尺寸大小,避免图片加载中导致页面布局抖动,影响 CLS 指标的数值
- 超出屏幕外的图片开启懒加载
- 对于我的项目中大量的小图标可应用 iconfont 字体计划
- 应用第三方字体库时尽可能按需文字生成
- 加载字体的时候会导致页面文字有肯定的闪动抖动,可在进入须要用到的页背后应用 preload 提前进行加载
页面渲染时
- 开启骨架屏,晋升用户体验,防止加载到渲染过程中都是白屏阶段
- 对于大量列表的滚到应用虚构列表
- 尽量多应用 CSS3 动画
- 应用 requestAnimationFrame 监听帧变动,使得在正确的工夫进行渲染
- 正当应用 CSS,防止通配符,最大化款式继承,少用标签选择器,缩小过深嵌套等
用户界面交互
- 缩小页面重排、重绘
- 防抖节流的应用
- 正当应用 requestAnimationFrame 动画代替 setTimeout
- 开启 GPU 减速,CSS 中可应用以下属性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、webGL、Video)来触发 GPU 渲染
- 缩小 JavaScript 脚本执行工夫,把一些和 DOM 操作无关且耗时的工作放到 Web Workers 中去执行
- 对将来某个工夫内须要执行动画的元素,将其标记为 will-change,这样渲染引擎会将该元素独自生成一个图层
最初
本文对前端性能优化的方向列举了不少,除此之外也还有很多是没有波及到的,比方小程序内,Vue/React 框架中非凡的其余优化,配合 App 原生能力优化等。以上优化方向的阐明就较为简洁,具体的实操及原理有趣味的同学能够多钻研,面对这么多的方向优化,到底如何抉择呢。
没有所谓的相对优化,都须要联合以后我的项目的利用场景及对我的项目全量的性能剖析,找到某个方向的有余,针对性的优化,抉择适合的计划。心愿大家都能找到本人适合的优化方向,把我的项目优化的妥妥的。看完本文如果感觉有用,记得点个赞反对,珍藏起来说不定哪天就用上啦~
专一前端开发,分享前端相干技术干货,公众号:南城大前端(ID: nanchengfe)
参考
新一代 Web 性能体验指标
前端性能优化之申请优化