度量标准:
- 100毫秒的界面响应时间与60FPS
- 速度指标(Speed Index)小于1250ms
- 3G网络环境下可交互时间小于5s
- 重要文件的大小预算小于170kb
编码优化
普通代码优化
if,switch
可由object
代替
const obj = {
a:'dosome',
b:'doother'
}
数据读取:
- 变量声明的作用域,从局部到全局作用域的搜索过程,越长越慢
- 对象嵌套越深,读取速度就越慢
- 对象在原型链中存在的位置越深,找到它的速度就越慢
- 对大量计算,可移交 web worker 进行计算
CSS优化
- 尽量减少一些样式层级的级数,比如,div ul li span i { color: red}, 其实我们可以给i标签设置class,直接书写样式。
- 尽量避免开启GPU,比如 transform,transitions,opacity
- 避免使用占用过多CPU和内存的属性 比如 text-indent
- 延迟动画
DOM
- 减少DOM的访问,读取DOM时,缓存到变量中,持续使用
- 减少重绘重排,如果需要多次重绘重排,建议先脱离文档流,处理完再回归
- 善于使用事件委托
- 减少无意义的代码,比如空标签清浮动那种代码 能不用最好不要用。
- css文件链接放头部,js文件放底部
- 设置favicon.ico
- 增加必要的loading
流程控制
- 避免使用 for in,(它能枚举到原型,所以很慢)
- 恰当使用倒叙循环
- 减少迭代次数
- 基于循环的迭代比基于函数的迭代快8(没验证,肯定快)倍
- 用Map代替大量的
if else
和switch
- 使用requestAnimationFrame来代替setTimeout和setInterval
- 有多层嵌套,善用return
if(some){
}else{
}
===>
if(some){
return
}
// do else
React代码优化
- PuerCompoent
- React.memo
- useMemo,useCallBack
- componentWillUnmount, useEffect 的return 对监听,定时器进行卸载
- React的devtool 有一个选项,查看state影响的范围,做对应处理
Vue代码优化
- keep-alive
- 组件按块
const Foo = () => import('./Foo.vue')
// 把组件按组分块
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
beforeDestroy()
生命周期内清除定时器或者$once这个事件侦听器器在定义完定时器之后的位置来清除定时器
const timer = setInterval(() =>{
// 执行定时器操作
}, 500);
// 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
this.$once('hook:beforeDestroy', () => {
clearInterval(timer);
})
- computed 和 watch 区分使用场景,如需计算缓存用
computed
. - v-if 和 v-show
- vi-for 添加key
打包优化
构建优化:
dll 预编译
Tree-shaking => import { unique, implode, explode } from “array-utils”;
动态模块 => React.lazy配合suspense
缓存文件 => service worker
搜索范围 include exclude
文件压缩 gzip,
代码风格优化
- HTML 文档结构层次尽量少,最好不深于6层。
- 减少DOM查找
- 动画不在视线范围尽量停止
资源优化
- 图片压缩 可以自己写个图片压缩工具或者直接到tinypng
- 响应式图片 根据用户的窗口大小,展示不同的图片。实现方法:媒体查询,js,html5的srcset,不支持srcset的浏览器也可以正常展示src的属性。
-
- 图片格式可选用webp,avif
<img
srcset="img-320w.jpg, img-640w.jpg 2x, img-960w.jpg 3x"
src="img-960w.jpg"
alt="img"
/>
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Photo" width="450" height="350">
</picture>
- 雪碧图将多个小图片合成一个大图 => 如果开启HTTP2,这个问题可以忽略
- preload/prefetch
- script 的 defer 和 async
其他优化
- HTTP2 多路复用特性,使得可以在一个连接上同时打开多个流,双向传输数据
- gzip 基本可以压缩70%左右,在
response Headers
中查看content-encoding: gzip
- CDN 外链资源都会部署在 CDN
- 接口合并
- 接口缓存,本地缓存
- webview 离线缓存
PWA
service worker
资料: 基础 进阶 - day.js 代替 moment
优化分析工具,方法
Lighthouse
Performance
报表工具 https://crux-compare.netlify.app/
首屏优化
- cdn => 减少服务器与用户的距离
- 接口缓存 =>
- 静态文件缓存 => service worker
- 动态加载 => 页面动态加载,组件动态加载,图片懒加载
- 减少请求数量,如必要,可开启http2
- gzip压缩
- 图片格式可选用webp,avif
- SSR 服务端渲染