前端性能优化主要从以下几个方面进行
网络优化
1、开启 Gzip 压缩, 以减小文件体积, 加快加载速度。可以通过配置 web 服务器来实现。
2、合并文件以减少 HTTP 请求数。可以使用 webpack 等工具对 js、css 文件进行合并并压缩。
3、使用 CDN 加载静态资源文件,加速文件加载速度,并可分散部分 Origin 服务器流量。
4、添加缓存头,通过 Expires 或 Cache-Control 来利用浏览器缓存,避免重复请求文件。
5、对图片和字体文件开启镜像站点,加速资源加载。
6、代码分割,避免初次加载全部代码,可以按路由拆分 bundle 加快渲染速度。
7、预加载资源,对可能需要的资源提前加载,加速使用时的速度。
8、减少重定向次数,避免多次 Http 请求往返。
9、优化请求头部,移除不必要的头信息。
10、正确使用 HTTP 缓存策略,区分强缓存和协商缓存,设置缓存过期时间。
图片优化
1、选择合适的图片格式
- 使用新型图形格式如 WebP、SVG 等能显著减小图片体积
- JPEG 对有损压缩效果好,适合照片
- PNG 无损压缩,适合图标、截图等
2、图片大小控制合适
- 不要加载过大的图片,根据实际效果需求确定加载分辨率
- 响应式网站可以加载不同大小图片
3、对可视区域外的图片进行懒加载,提高初始加载速度
4、使用 CSS Sprite 技术,将小图片整合到一张大图中,使用 background position 进行切割,可减少 Http 请求, 加快显示速度
5、使用工具或脚本自动对图片进行无损/有损压缩
6、启用 CDN 和缓存策略,避免重复下载相同图片
7、图片格式转换,将其他格式图片转成 WebP 等优化效果更好的格式
8、利用 CSS3 代替图片,通过 CSS3 特效实现的图标、形状等也可以减少请求图片。
代码优化
1、避免过多的 DOM 操作,优化 DOM 访问
- 利用缓存变量获取DOM节点,避免多次查询
- 批量修改节点,合并多次 DOM 修改操作
- 绑定事件时避免直接访问 DOM,可以事件代理
- 使用虚拟 DOM,减少实际 DOM 操作次数
2、 避免布局抖动
- CSS 中避免使用 table 布局,可能导致整体重排
- 拆分 DOM 更新为多个小块,避免大规模同步更新布局
- 动画实现上优先选择 transform 和 opacity 来触发重绘/重排范围
3、避免复杂计算和循环操作
- 选择更优的算法,避免 O(n^2) 等复杂度算法
- 背景运行复杂逻辑,分段提供结果
- 节流/防抖控制函数调用频率,避免高频计算
4、减少内存使用和占用
- 及时释放不再需要的内存占用
- 处理的数据量比较大时进行分批处理,避免内存占满
- 监控内存泄漏情况
5、动画性能优化
- 使用 requestAnimationFrame
- 使用性能更好的 CSS animation
- 选择合适的动画效果复杂度,做好降级处理
6、代码压缩与合并
- 压缩文件体积,减少加载时间
- 合并小文件以减少请求数,加速下载速度
懒加载
1、为需要懒加载的图片、组件等添加一个通用的 lazy 标识 2、使用 IntersectionObserver API 来监听这些元素的可见性。可以封装一个观察者组件,在元素可见时加载资源并移除 lazy 标识 3、在 CSS 中, 为有 lazy 标识的节点添加样式 hidden 掉,防止构建文档树时加载资源 4、针对图片可以使用一个低质量的占位图,防止布局移动;等加载完成后,再将真实数据赋值给图像 src 进行显示 5、使用 memory cache 存储常访问的懒加载资源 6、在当前页面资源加载完成时,也可以预加载下一页的懒加载资源
关键渲染路径(Critical Rendering Path)优化
1、减少关键资源数量和大小
- 代码压缩、图片优化、第三方代码隔离等
- 只加载初始界面需要的关键 CSS/JS
2、关键资源加载优化
- 资源按序加载,先加载关键 CSS 再加载 JS
- 设置资源加载优先级,如设置预加载、预渲染指令
- 使用 CDN 加速加载
3、CSS放前、JS放后
- CSS 放在 HTML head 中,会阻塞页面渲染
- JS尽量放在
</body>前,避免阻塞文档解析
3、缩短执行逻辑
- 避免长时间运行的 JS 逻辑,拆分为异步加载
- 预编译 Handlebars、JSX 模板,避免客户端编译
4、预加载资源
- 使用
<link rel="preload/prefetch">预加载关键资源 - 使用 HTTP 2.0 Server Push 技术,推送所需资源
5、减少重排/重绘
- 避免DOM频繁读写,合并操作到一次 redraw 流程
- 开启GPU加速,promotion 列表内容到 GPU 层
6、代码层面优化
- 避免过深层级、避免复杂选择器 DOM 查询等
- 使用更高效的算法和数据结构。选择合适的数据结构和算法可以大大提高代码的执行效率。
- 优化循环代码。对迭代次数多的循环代码进行优化,例如减少不必要的循环,使用更优的循环方式(for vs while)等等。
- 避免不必要的计算。可以通过存储结果避免重复计算。
- 减少函数调用开销。通过内联函数或者把函数调用移到循环体外等方式。
- 减少内存分配和复制。避免不必要的内存分配,以及通过传入引用避免复制大对象。
- 使用更高效的系统调用和库函数。选择对性能优化过的系统调用和库函数。
- 多线程并行。对于可并行的任务,使用多线程可以利用多核优势。
- 利用缓存优势。使用缓存或者直接访问内存可以减少访问延迟。
- 减少代码路径分支。简化控制流可以提高指令预测效率。
- 使用更优编译器优化。开启编译器优化选项