前端性能优化简述

111 阅读5分钟

前端性能优化主要从以下几个方面进行

网络优化

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)等等。
  • 避免不必要的计算。可以通过存储结果避免重复计算。
  • 减少函数调用开销。通过内联函数或者把函数调用移到循环体外等方式。
  • 减少内存分配和复制。避免不必要的内存分配,以及通过传入引用避免复制大对象。
  • 使用更高效的系统调用和库函数。选择对性能优化过的系统调用和库函数。
  • 多线程并行。对于可并行的任务,使用多线程可以利用多核优势。
  • 利用缓存优势。使用缓存或者直接访问内存可以减少访问延迟。
  • 减少代码路径分支。简化控制流可以提高指令预测效率。
  • 使用更优编译器优化。开启编译器优化选项