前言
前端性能优化的定义以及为什么做性能优化
前端:是指直接面向用户的借口,并负责与用户行为发生交互 其中有:PC、移动端、终端以及其他,细分会有web,h5,Android,ios web的性能描述了Web用户在浏览器上的加载和显示速度。
Web页面生命周期的三个阶段:
1.加载:指从发出请求到渲染出完整页面的过程 2.交互:从页面加载完成到用户的整个过程 3.关闭:用户发出关闭指令后页面所做的一些清理操作
在Web页面整个生命周期中,占用更小的资源,以最快的速度运行。
了解完相关与前端的一些基础知识后,有个疑问,为什么我们要做性能优化? 答:性能是系统设计的标尺,用户在使用我们设计的产品过程中,最直观的感受就是这个系统运行的快不快,操作响应是否敏灵,以及交互逻辑是否合理,相反的如果加载时间过长,跳失率越高,页面反应越慢,订单的转化率也越低。
高扩展、高性能、高可用是我们前端产品设计的目标,其中的可扩展性=易用性+性能+稳定性。而前端的性能优化则是以这些方面为目标。
以及做性能优化,也是每个前端工程师进阶的必要能力。 不管是对我们前端工程师本身的成长有帮助,也可以帮助到我们辛苦完成的产品有更好的市场反馈。
性能优化的原则
1.非盲目性:性能优化以问题为导向,不能盲目进行优化; 2.开发敏捷性:以更少的人力去解决更重要的问题; 3.数据支撑:性能优化要以数据支撑; 4.可持续性:性能优化是可持续的;
前端性能优化的度量以及常用的检测工具
之前介绍过关于Web页面的生命周期,那么我们前端的性能优化也是根据此来开展的,从打开一个页面->用户交互->关闭一个页面。 这分为: 加载阶段:首屏时间、秒开率; 交互阶段:刷新率、反应速度;
前端性能优化的度量标准:
markdown
维度:指事物的某种固有特征
原子指标:指表达业务含义的原子量化属性且不可再分的概念合集;
复合指标:维度+原子指标;
度量周期:指标在时间维度上需要统计的前后跨度
性能指标:
scss
W3C:
DNS解析耗时;TCP连接耗时;SSL安全连接耗时;网络请求耗时;DOM解析耗时;资源加载耗时;首包时间;首次渲染/白屏时间;首次可交互时间;DOM Ready时间;页面完全加载时间。
Lighthouse:
fcp:first-contentful-paint(首屏渲染时间)
si: speed index(速度指数)
lcp: large-contentful-paint(最大内容绘制)
tti:time-to-interactive(可交互时间)
tbt: tatal-blocking-time(总阻塞时间)
cls: cumulative-layout-shift(累计布局总偏移)
不同公司还有各自的检测工具,但是基本关注的都是这几个方面;
系统性的进行前端性能优化
说了这么多,该进入本次解说的正题了,如何系统性的进行前端性能优化呢?那么先让我们来聊一下前端优化需要注意的方面。
前端优化的指导原则以及常用的解决方法
核心要素: 用户使用的环境:网络环境、设备性能;
markdown
不同设备,不同的网络,使用我们前端产品的反应时间是不同的,这个是我们没办法决定的,所以我们只能做到兼容,以及思考多场景,来面对这些不同情况,如果有最终的解决办法就是告诉用户该换设备了;
在面对不同网络环境下,我们能做的就是网络优化;
网络优化:
其中最重要的就是阻塞网页渲染的资源叫关键资源
1.减少关键资源个数;
swift
给关键资源加async defer / 内联形式
- 代码分割:使用Webpack等打包工具进行代码分割,实现按需加载。
2.减少关键资源的rtt(发送-接受的时长:csdn)
diff
升级http协议、使用http缓存、优化接口请求、使用数据缓存、dns欲解析、使用cdn、减少关键资源个数以及大小
- 使用HTTP/2:相较于HTTP/1.1,HTTP/2支持多路复用、头部压缩等特性,提高加载速度。
- 优化API请求:减少API请求次数,合并请求,使用缓存等技术降低请求开销。
3.降低关键资源大小
diff
代码分割、压缩 静态资源服务器开启gzip【gzip是一个在网络中广泛使用的数据压缩程序。在Web开发中,服务器和客户端通常会使用gzip来压缩和解压缩HTTP请求和响应,以减少传输的数据量,从而提高网页加载速度。】
- 压缩代码:使用UglifyJS、Terser等工具对JS代码进行压缩,使用CSSNano对CSS代码进行压缩。
- 图片优化:使用压缩工具(如TinyPNG)对图片进行压缩,使用适当的图片格式(如WebP)以减小文件大小。
- 使用CDN:将静态资源部署到CDN上,加速资源加载速度。
非首屏元素延迟加载:动态路由 拆分 路由命中后再次加载,在交互后再加载非首屏资源
- 懒加载:对于不需要立即显示的图片或组件,可以使用懒加载技术,只在需要时加载
代码分割、压缩、静态资源服务器开启GZip、非首屏元素延迟加载
渲染优化:
渲染优化的目的就是:提高单帧速度;根据这个目的我们可以进行以下三个操作;
1.合成线程>重绘>重排:
css
使用css合成动画,减少js对齐操作
避免强制同步布局和布局抖动 dom批处理,虚拟dom transform
ex:插入dom会出现强制同步布局 获取dom高度,
减少HTTP请求:合并CSS和JS文件,使用雪碧图等技术减少图片请求。
- 优化DOM操作:减少不必要的DOM操作,使用虚拟DOM(如React)或其他优化技术。
- 事件节流与防抖:对于高频触发的事件,如滚动、输入等,使用节流或防抖技术降低触发频率。
- 避免使用耗性能的CSS属性(如box-shadow、border-radius等),使用transform进行动画。
- 重绘与回流:减少重绘与回流,避免使用引起回流的CSS属性(如width、height等)。
- GPU加速:使用`transform: translateZ(0)`或`will-change`属性开启GPU加速。
2.避免频繁的垃圾回收:
javascript
- 使用WeakMap、WeakSet等数据结构,避免频繁的垃圾回收。
3.减少js脚本的运行时间:
markdown
- 使用V8的优化策略,如使用`new Function`代替`eval`。
- 长任务拆分
- 优化代码执行逻辑
- 耗时的计算任务移出主线程
- **web-work**插件可以提高前端算力
浏览器有GUI渲染线程与JS引擎线程,这两个线程是互斥的关系,所以我们在DOM渲染的过程中,我们需要避免出现这类情况。 当js有大量计算时,会造成 UI 阻塞,出现界面卡顿、掉帧等情况,严重时会出现页面卡死的情况,俗称假死,所以加大前端算力,以及减少不必要的js计算工作也是前端在开始设计时需要注意的,一切等到开始做性能优化时开始,不仅是对人力的损耗,也是增加了很多不必要的重新设计工作。