一、前端性能优化解析
- 首屏加载优化:打开速度变快
- 缓存优化:再次打开速度变快
- 渲染优化:操作顺滑
- 长任务拆分:动画流畅
二、首屏加载优化
如何衡量加载情况?通过首屏加载指标。
首屏加载指标:
- FP(First Paint): 首屏绘制。可能就是空壳子。
- FCP(First Content Paint):首屏内容绘制。FP到FCP之间就是js执行,太慢就会有白屏时间。
- FMP(First Meaningful Paint):首次有效绘制。主要内容的呈现时间。
- LCP(Largest Contentful Paint):最大内容渲染。加载最大内容块呈现时间。
首屏加载中用户体验相关的指标:
- INP(Interation to Next Paint):用户交互和计算整个页面响应的过程的时间。
- TTI():可交互时间。一般在ssr返回整个html,html中的交互事件还没绑定上,需要执行js去绑定的时间。
- TBT (total Blocking Time):阻塞时间从FCP到TTI的总阻塞时间。
- CLS(Cumulative Layout Shift):布局偏移情况,重排重绘次数分数。
- TTFB(Time to First Byte):首字节到达时间,请求发出后到接收到数据中间的时间。
注意:绘制是重点,要保证初次获取的内容的字节数足够小,这也是我们做按需加载的原因。讨论绘制问题基本都是围绕资源的体积来处理。
三、资源体积优化
- 图片:webp,图片压缩,图片尺寸(在合适的容器内用合适的尺寸图片 1倍图2倍3倍)
- 字体:字体子集化(用了哪些字,就最后只生成对应的字体文件),Fontmin
- 懒加载资源:图片懒加载、js异步加载。
- css、js文件压缩,打包构建阶段完成。
- 代码压缩
- 文件合并
- 文件拆分
- tree shaking
- 动态加载
- Gzip、Brotli
- SSR、SSG
四、前端开发动画卡顿的原因及具体优化方案
动画卡顿的原因:单线程,阻塞。
方案:
- 减少主线程阻塞:优化js执行,减少长任务(复杂的计算【web worker、将任务切分(react Scheduler)】)
- GPU加速:
- css属性:transform,opacity,避免引起重排的属性:定位left、top
- requestAnimationFrame 3.防抖节流
五、应用层状态管理的性能优化
Vue状态管理:
-
精简Vuex或Pinia的全局状态: 将不需要全局共享的状态移至组件内,减少全局状态更新的开销。例如:使用reactive管理局部状态,而不是在全局store中存储。
-
模块化和按需加载:将Vuex或Pinia的状态模块化,按需加载,提高性能。
-
避免多余的Getter重新计算:将计算密集的逻辑放入组件的computed或watch,而不是在store的getter中。
六、应用视图层更新优化
Vue的视图更新优化:
- 避免多余的响应式数据:只对需要响应式的数据使用 reactive或ref,静态数据不需要响应式。
- 使用 v-once和v-memo
- 拆分组件和局部更新:将大组件拆分为多个子组件,使用 keep-alive 缓存不活跃的组件,减少重新渲染的开销。
- 避免 watch 的过度使用:优化 watch 的逻辑,仅对必要的依赖进行监听,减少副作用执行。
- 使用虚拟滚动:对长列表使用虚拟滚动库(如vue-virtual-scroller)进行优化。
- 节流和防抖: 对频繁触发的事件(如滚动、输入)进行节流或防抖处理,避免多次触发重渲染。
- 事件绑定:
- 在 Vue 中使用.native 修饰符直接绑定 DOM 事件。
- 在 React中,避免在子组件上过多传递回调函数。
- 避免不必要的 DOM 操作: 减少直接操作 DOM 的次数,尽量通过框架的响应式机制处理更新。
- 异步加载和懒加载:对于路由组件、图片等使用懒加载技术,降低首次加载压力。
- 使用请求合井: 在需要多次请求时,合并请求以减少多余的网络开销。
七、性能指标采集
- 常规指标采集:Performance、Performance0bserver API和webvital
- 自定义指标:FMP 通过 Mutation0bserver来自定义计算
- 额外指标:首字节、服务端上报
八、上报
上报方式
- 实时上报:关键指标(如LCP、CLS)需要实时上报,确保及时监控。
- 批量上报:对非关键指标,利用定时任务进行批量上报,减少网络开销。
上报通道
- HTTP:通过 RESTfuI API 上报。
- 日志埋点:将性能指标写入日志,后续通过数据分析管道处理
- Kafka:在大型分布式系统中,使用Kafka 提高消息处理效率,