通用
JS
- 防抖
场景:直播间元素、聊天发送、互动、锚点、互动、锁屏(最后一次)
- 节流
滚动条虚拟列表渲染(最后一次)、
- requestIdleCallback
lottie 资源、课件资源后台下载
- requestAnimationFrame
页面向上滚动动效 弹幕放到屏幕上
- setTimeout 替代 setInterval
无网弹窗、弱音量提示
- 内存泄露
释放:URL.revokeObjectURL(this.uniqueAnimationSrc); 意外全局变量、定时器销毁、dom 删除引用还在 WeakMap
- promise 并行控制
Lottie 同时实例化个数
- 事件委托
JQ Item list 点击,不用给 每一个 li 都注册监听事件,冒泡机制
- 减少操作 dom,缓存 dom 结果
- IntersectionObserver
- 文档碎片 documentFragmentjs
const fragment = document.createDocumentFragment(); fragment.appendChild(dom); el.appendChild(fragment);
- 克隆节点,修改完再替换原始节点 el.cloneNode(true)
CSS
加载:
- 大小: 删除无用(0单位)、提取公共、异步加载、web 字体
- 减少请求:iconfont、base64
- 避免:@import
解析:
- 文件放到最上面
- 慎用 * 通配符
- 少用表达式 calc
- 避免三层嵌套
- 不要在 ID 选择器前面进行嵌套其它选择器
重绘重排
- 脱离普通文档流 absolute fixed (重排开销比较小)
- 避免 table 小的改动造成重新布局
- CSS3 硬件加速(GPU 加速)
- 使用 css3 硬件加速,可以让 transform、opacity、filters、 Will-change 这些动画不会引起回流重绘
- 比如 background-color 这些,还是会引起回流重绘的
- dom 离线处理 display: none 元素不会被渲染,减少重绘回流
- visibility: hidden 的元素只对重绘有影响,不影响重排
其他
- 使用 CSS font-display 控制字体加载和替换
- 尽量使用 css3 代替图片
https://juejin.cn/post/7077347573740077069
重绘和回流
回流:首次渲染、字体大小、resize、尺寸宽高、添加删除 dom、css hover、文字大小图片数量 getBoundingClientRect、getComputedStyle
重绘:颜色、边框、visibility background
js
- class:合并对 DOM 样式的修改,采用 css class 来修改
- 缓存:不要把 DOM 节点的属性值放在一个循环里当成循环里的变量
- requestAnimationFrame: 实现动画
- 文档碎片: documentFragment 触发一次重排
css
visibility、display: none
- 使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流(改变了布局)
- dom 离线处理 display: none 元素不会被渲染,减少重绘回流
table: 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局
CSS3 硬件加速(GPU 加速)
- 使用 css3 硬件加速,可以让 transform opacity filters Will-change 这些动画不会引起回流重绘
- 比如 background-color 这些,还是会引起回流重绘的
- 使用 transform 替代 top
为动画的 HTML 元件使用 fixed 或 absolute 的 position,那么修改他们的 CSS 是不会 reflow 的。脱离普通文档流 absolute fixed, 重排开销小
HTML
- script 的 defer async
站长工具 async 不组合其他代码 代码高亮
- 减少 iframe 使用
资源
- 加载:
- 预加载:音频预加载 new window.AudioContext().decodeAudioData 能够以二进制文件流形式去预加载音频
- 空闲加载、异步加载
- 大小:不同环境下加载不同尺寸和像素的图片,使用 media 媒体查询或者 src set 和 sizes 属性
- 图片
- img lazy='load' 懒加载
- img 空 src 图片(因为也会发起请求)
HTTP
- 大小
- 压缩、
- gzip:nginx 配置打开并且 webpack 配置 compression-webpack-plugin 生成 gzip
- 次数
- 雪碧图\base64\字体图标减少请求
- 减少请求 promise.all
- 缓存: 强缓存 cache-control 协商缓存 ETag\last-modify
- 通信
- DNS:预解析 dns-prefetch
- HTTP2:头部压缩、二进制分帧传输对头阻塞、多路复用,服务器推送
- HTTP3:QUIC UDP 对头阻塞
- HTTP1.1:长链接
- 服务器
- CDN: 公共资源 CDN、容灾
- 负载均衡
Webpack
本地构建
- dll
- 分模块构建
- happypack thread
- 缓存 hard-source、cache-loader cacheDirectory
- alias
- extensions 依次尝试添加扩展名匹配,高频放前
- noParse 无依赖的不需要解析,提高整体构建速度
- lintOnSave build 关闭
- IgnorePlugin: 不把制定模块打包进去 moment
打包
- dll
- external
- compression-webpack-plugin
- 分包 optimization splitChunk: lottie 异步加载
- preload 预加载
- prefetch 空闲时候下载
- js 压缩 terserplugin
- image-webpack-loader
- tree-shaking
- webpackChunkName 添加名称
- lodash 模块引入
骨架屏
占位图
Vue
v-if v-for data router 懒加载 nextTick element-ui keep-alive
- v-if
- 不要将所有数据放 data 中 no reactive data, object.freeze
- v-for 添加 key
- router 懒加载
- 异步更新 nextTick
- 第三方插件异步引入 element-ui
- preload
- prefetch
- keep-alive 缓存
- mixin 滥用,覆盖哪个是哪个
- 虚拟 DOM
其他
- Gift 图片做埋点
不携带 cookie 大小最小 不跨域 不阻塞页面加载 get 之后不需要获取和处理数据,服务器也不需要发送数据
工具
- Performance
- LightHouse
- FMP 首次有效绘制(First Meaningful Paint)
- TTI Time to interactive,记录从页面加载开始,到页面处于完全可交互状态所花费的时间。
- 加载性能 LCP,交互性 FID,视觉稳定性 CLS