执行优化
- CSS 写在头部,JS 写在尾部并异步
- 避免 img、iframe 等的 src 为空:空 src 会重新加载当前页面,影响速度和效率
- 尽量避免重置图像大小:多次重置图像大小会引发图像的多次重绘,影响性能
- 图像尽量避免使用 DataURL:DataURL 图像没有使用图像的压缩算法,文件会变大,并且要解码后再渲染,加载慢耗时长
#DataURL
DataURL:
将图片 " 嵌入 " 到 HTML 中的方法。跟传统的用 img 标记将服务器上的图片引用到页面中的方式不一样,在 Data URL 协议中,图片被转换成 base64 编码的字符串形式,并存储在 URL 中,冠以 mime-type。
优势:
- 当访问外部资源很麻烦或受限时
- 当图片是在服务器端用程序动态生成,每个访问用户显示的都不同时。
- 当图片的体积太小,占用一个 HTTP 会话不是很值得时。
- 可以减少网络请求。
- 字符串编码方便传输存储。
劣势:
- Base64 编码的数据体积通常是原数据的体积 4/3,也就是 Data URL 形式的图片会比二进制格式的图片体积大 1/3。
- Data URL 形式的图片不会被浏览器缓存,这意味着每次访问这样页面时都被下载一次。这是一个使用效率方面的问题——尤其当这个图片被整个网站大量使用的时候。
- 不能在客户端进行缓存。(如图片,只能通过 css 文件进行背景图片缓存)
- 渲染时需要 base64 解码,需要消耗 cpu 资源。
渲染优化
设置 viewport:HTML 的 viewport 可加速页面的渲染
viewport 是用户网页的可视区域。
——viewport 翻译为中文可以叫做 " 视区 "。
手机浏览器是把页面放在一个虚拟的 " 窗口 "(viewport)中,通常这个虚拟的 " 窗口 "(viewport)比屏幕宽,这样就不用把每个网页挤到很小的窗口中(这样会破坏没有针对手机浏览器优化的网页的布局),用户可以通过平移和缩放来看网页的不同部分。
参考:@viewport - CSS(层叠样式表) | MDN
减少 DOM 节点:DOM 节点太多影响页面的渲染,尽量减少 DOM 节点
优化动画
- 尽量使用 CSS3 动画
- 合理使用 requestAnimationFrame 动画代替 setTimeout
- 适当使用 Canvas 动画:5 个元素以内使用 CSS 动画,5 个元素以上使用 Canvas 动画,iOS8+ 可使用 WebGL 动画
setTimeout 与 requestAnimationFrame 的区别:
引擎层面:
setTimeout 属于 JS 引擎,存在事件轮询,存在事件队列。
requestAnimationFrame 属于 GUI 引擎,发生在渲 染过程的中重绘重排部分,与电脑分辨路保持一致。
性能层面:
当页面被隐藏或最小化时,定时器 setTimeout 仍在后台执行动画任 务。
当页面处于未激活的状态下,该页面的屏幕刷新任 务会被系统暂停,requestAnimationFrame 也会停止。
应用层面:
利用 setTimeout,这种定时机制去做动画,模拟固定时间刷新页面。
requestAnimationFrame 由浏览器专门为动画提供 的 API,在运行时浏览器会自动优化方法的调用,在特定性环境下可以有效节省了 CPU 开销。参考:# setTimeout/setInterval与requestAnimationFrame的区别
优化高频事件:scroll、touchmove 等事件可导致多次渲染
- 函数节流
- 函数防抖
- 使用 requestAnimationFrame 监听帧变化:使得在正确的时间进行渲染
- 增加响应变化的时间间隔:减少重绘次数
节流和防抖可以跳转: JS的防抖与节流
GPU 加速:使用某些 HTML5 标签和 CSS3 属性会触发 GPU 渲染,请合理使用 (过渡使用会引发手机耗电量增加)
- HTML 标签:video、canvas、webgl
- CSS 属性:opacity、transform、transition
样式优化
- 避免在 HTML 中书写 style
- 避免 CSS 表达式:CSS 表达式的执行需跳出 CSS 树的渲染
- 移除 CSS 空规则:CSS 空规则增加了 css 文件的大小,影响 CSS 树的执行
- 正确使用 display:display 会影响页面的渲染
- display:inline 后不应该再使用 float、margin、padding、width 和 height
- display:inline-block 后不应该再使用 float
- display:block 后不应该再使用 vertical-align
- display:table-* 后不应该再使用 float 和 margin
- 不滥用 float:float 在渲染时计算量比较大,尽量减少使用
- 不滥用 Web 字体:Web 字体需要下载、解析、重绘当前页面,尽量减少使用
- 不声明过多的 font-size:过多的 font-size 影响 CSS 树的效率
- 值为 0 时不需要任何单位:为了浏览器的兼容性和性能,值为 0 时不要带单位
- 标准化各种浏览器前缀
- 无前缀属性应放在最后
- CSS 动画属性只用 -webkit-、无前缀两种
- 其它前缀为 -webkit-、-moz-、-ms-、无前缀四种:Opera 改用 blink 内核,-o- 已淘汰
- 避免让选择符看起来像正则表达式:高级选择符执行耗时长且不易读懂,避免使用
js 脚本优化
- 减少重绘和回流
- 避免不必要的 DOM 操作
- 避免使用 document.write
- 减少 drawImage
- 尽量改变 class 而不是 style,使用 classList 代替 className
- 缓存 DOM 选择与计算:每次 DOM 选择都要计算和缓存
- 缓存.length 的值:每次.length 计算用一个变量保存值
- 尽量使用事件代理:避免批量绑定事件
- 尽量使用 id 选择器:id 选择器选择元素是最快的
- touch 事件优化:使用 tap(touchstart 和 touchend) 代替 click(注意 touch 响应过快,易引发误操作)
打包优化
优化 Webpack 打包速度
1、压缩 html 和 css
html-webpack-plugin 插件和 optimize-css-assets-webpack-plugin
2、使用 externals 配置提取常用库
3、使用 tree shaking 清除无用代码
4、使用 Dllplugin 插件打包第三方类库
5、使用 Happy pack 实现多线程加速编译