前端开发体验及性能优化
第一类:提高开发体验及优化生产代码
1. 使用webpack
- Debug:
- 使用Source Map,让开发或上线时代码报错能有更加准确的错误提示。
- 提升打包构建速度:
- 使用HotModuleReplacement让开发时只重新编译打包更新变化了的代码,不变的代码使用缓存,从而使更新速度更快。
- 使用OneOf让资源文件一旦被某个loader处理了,就不会继续遍历了,打包速度更快。
- 使用Include/Exclude排除或只检测某些文件,处理的文件更少,速度更快。
- 使用Cache对eslint和babel处理的结果进行缓存,让第二次打包速度更快。
- 使用Thead多进程处理eslint和babel任务,速度更快。
- 注意:进程通信都有开销的(600ms左右延迟),要在比较多代码处理时使用才有效。webpack5默认开启多进程模式!
- 减少代码体积
- 使用Tree Shaking剔除了没有使用的多余代码,让代码体积更小。
- 使用@babel/plugin-transform-runtime插件对babel进行处理,让辅助代码从中引入,而不是每个文件都生成辅助代码,从而体积更小。
- 使用Image Minimizer 对项目中图片进行压缩,体积更小,速度更快。
- 注意:项目中图片如果都是在线链接,那么就不需要压缩。只有本地项目静态资源图片才需要进行压缩。
- 优化代码性能:
- 使用Code Split对代码进行分割成多个js文件,从而使单个文件体积更小,并行加载js速度更快。通过import动态导入语法进行按需加载,从而达到需要使用时才加载该资源,不用时不加载资源。
- 使用Preload/Prefetch对代码进行提前加载,等未来需要使用时就能直接使用,从而用户体验更好。
- 使用Network Cache能对输出资源文件进行更好的命名,将来好做缓存,从而用户体验更好。
- 使用Core-js对js进行兼容性处理,让我们代码能运行在低版本浏览器。
- 使用PWA能让代码离线也能访问,从而提升用户体验。
第二类: 明显改善页面第一次加载的速度,减少白屏等待的时间
1. 使用骨架屏技术
- 服务器骨架屏: 页面首屏内容是基于服务器渲染的
- 前端骨架屏: 在真实内容渲染出来之前,我们给予相关位置用“色框”占位
2. 减少 HTTP 请求的次数和大小
- CSS/JS 都要做合并压缩,尽可能合并为一个 CSS 和一个 JS
- 图片的合并压缩,例如:雪碧图(CSS Sprit)
- 使用图片 BASE64 来加快图片的渲染!
- 图片一定要做延迟加载
- 使用字体图片和矢量图,来代替位图!!
- 音视频资源也要设置延迟加载 preload='none'
- 数据的异步加载
- 开启服务器端的 GZIP 压缩,可以让访问的资源压缩 60%
3. 渲染页面中的优化
- 因为<script>会阻碍 GUI 渲染,所以:把其放在页面末尾,或者设置 async/defer!
- 因为<Link>是异步加载 CSS 资源,所以建议放在页面开始,尽快获取样式资源!!
- 不要使用 import 导入 CSS,因为其会阻碍 GUI 的渲染!
- 样式代码较少的情况下,使用<style>内嵌式,尤其是移动端开发!
4. 在网络传输中的优化
- 减少 cookie 的内容大小,因为只要向服务器发送请求,不论服务器是否需要,总会在请求头中把 cookie 传递给服务器,如果 cookie 比较大,会让所有的请求都变慢
- 资源分服务器部署,例如:web 服务器,图片服务器,数据服务器,这样可以降低服务器压力,提高服务器的并发,让资源能更加合理的被利用;但是也会导致 DNS 解析次数增加,此时可以基于 DNS Prefetch 来优化 DNS 解析!!
- 基于 HTTP/2.0 来代替 HTTP/1.1
- 基于新的二进制格式,让传输的内容更加丰富健壮
- header 压缩,让传输速度更快
- 服务端推送,可以减少 HTTP 请求次数
- 多路复用,让传输速度更快,避免线头阻塞
- 基于 Connection:keep-alive 保持 TCP 通道长链接, THTTP/1.1 版本会自动开启
- 开启 CDN,地域分布式服务器部署
- 对于静态资源文件采取“强缓存和协商缓存”,对于不经常更新的数据请求,设置数据缓存!
第三类:提高页面运行时候的性能
1. 减少循环嵌套,降低时间复杂度;避免出现死循环/死递归
2. 使用事件委托来优化事件绑定,性能可以提高 40%+
3. 减少 DOM 的回流(重排)和重绘
- 样式分离读写「渲染队列机制」
- 批量新增元素「字符串拼接,文档碎片」
- 基于 transform/opacity 等方式操作样式
- 把需要频繁修改样式的元素(例如:JS 实现动画)脱离文档流
- ......
4. 使用函数的防抖和节流处理高频触发操作
5. 合理使用闭包,避免内存泄漏,以及手动释放无用内存!
6. 减少页面冗余代码,提高代码的重复使用率「也就是尽可能的做封装处理」
7. 尽可能不要使用 for/in 循环,因为其消耗性能
8. 避免使用 eval/with 等消耗性能的代码
9. 能用 CSS3 处理的动画坚决不用 JS「JS 动画尽可能基于 requestanimationframe 来代替定时器」