前端性能优化策略

138 阅读4分钟

网络层面优化

  1. http2
    • 解析速度快。
    • 多路复用,多个请求可以共用一个TCP连接。
    • 头部压缩,更小的负载体积。
  2. 静态资源使用CDN

将资源分发到CDN的边缘网络节点,用户请求资源时就近返回节点上缓存的资源,不需要每个用户的请求都回源站获取,避免网络拥塞、缓解源站压力,保证用户访问资源的速度和体验。

  1. 充分利用http缓存

HTML:使用协商缓存。CSS&JS&图片:使用强缓存,文件命名带上hash值。

  1. DNS预解析

适用于网页引用了大量其他域名的资源。dns-prefetch需慎用,多页面重复DNS预解析会增加重复DNS查询次数。

// 用meta标签来告知浏览器, 当前页面要做DNS预解析。
<meta http-equiv="x-dns-prefetch-control" content="on" />

// 在页面header中使用link标签来强制对DNS预解析。
<link rel="dns-prefetch" href="https://www.baidu.com/" />
  1. 自托管第三方资源

第三方资源官方的cdn比较慢的情况下可以考虑自托管三方资源,根据项目实际情况进行使用。

资源体积优化

  1. 单独打包css及压缩css代码
    • webpack默认将js代码和css代码打包到一个文件,可使用mini-css-extract-plugin插件单独打包css会减少整包的体积。
    • 可使用css-minimizer-webpack-plugin插件压缩css代码
  2. 路由懒加载Suspense + React.lazy
  3. 代码分割optimization.splitChunks

webpack默认会将所有模块代码打包在一起,这种规则的优点是能减少页面的HTTP请求数,缺点是页面初始代码包过大影响首屏渲染性能,无法有效应用浏览器缓存,分包可避免代码修改整个bundle缓存失效。

  1. 三方依赖单独使用cdn引入,使用externals属性单独配置。
  2. 压缩代码

如果使用的是webpack v5或更高版本,是开箱自带的功能,如果是v5以下或者希望自定义配置,可安装terser-webpack-plugin实现压缩。

  1. 开启gzip压缩
  2. 三方依赖的按需引入

如果直接引入整个插件,会导致项目的体积过大,可以只引入需要使用的内容,以达到减小项目体积的目的。

import lodash -> import lodash/get
  1. 使用支持Tree Shaking的三方依赖
import lodash -> import lodash-es
  1. 替换更小的库

使用dayjs替换moment。

  1. 减少不必要的三方依赖的使用

yarn why查看依赖被引用的情况。可根据项目实际情况减少三方依赖的使用。

  1. 使用时动态引入模块,不在首页就加载(组件懒加载)

比如xlsx下载文件,在使用的时候再加载。

const buttonClick = async() => {
  // 使用时异步引入xlsx模块
  const xlsx = await import('xlsx');
  xlsx.writeFile(wb, filename)
}

项目内代码层面优化

  1. 使用iconfont代替图片图标

字体图标就是将图标制作成一个字体,使用时就跟字体一样,可以设置属性例如font-size、color等,非常方便,并且字体图标是矢量图,不会失真。还有一个优点是生成的文件特别小,无论是加载还是打包所消耗的资源都相对较小一些。

  1. 长列表优化
    • 滚动加载更多
    • 虚拟列表
    • 分页
  2. 减少DOM的操作,尽可能的合并DOM操作
  3. 长任务使用Web Workers
  4. 事件委托
  5. 合理使用节流防抖
  6. 骨架屏优化白屏时长

图片优化

  1. 图片懒加载

当图片出现在可视区域或者即将出现在可视区域时再加载图片,避免一次性加载全部图片。

  1. 图片压缩

一些图片适当降低图片质量时,通常是看不出来区别的,可以使用image-webpack-loader进行图片压缩。

  1. 使用webp图片

webp的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha透明以及动画的特性,在JPEG和PNG上的转化效果都相当优秀、稳定和统一。

  1. 尽量使用CSS代替图片

一些简单的图片效果如果可以通过CSS效果实现则进行用CSS来实现,可以减小请求次数或者打包体积大小。