# 五.性能优化

# 1.图片优化

  • 能用 css 代替的用 css 代替
  • 使用 cdn
  • 小图用 base64
  • 雪碧图
  • 能够显示 webP 格式的浏览器尽量使用 webP 格式
  • 小图可以用 svg
  • 照片使用 jpeg

计算图片大小

对于一张 100100 像素的图片来说,图像上有 10000 个像素点,如果每个像素的值时RGBA存储的话,那么也就是说每个像素有 4 个通道,每个通道 1 个字节(8 位=1 个字节),所以该图片大小大概为 39KB(100001*4/1024)

但是在实际项目中,一张图片可能并不需要使用那么多颜色去显示,我们可以通过减少每个像素的调色板来相应缩小图片的大小。

了解了如何计算图片大小的知识,那么对于如何优化图片,相比大家已经有了 2 个思路了:

  • 减少像素点
  • 减少每个像素点能够显示的颜色

图片加载优化

1.不用图片。很多时候会使用到很多修饰类图片,其实这类修饰图片完全可以用 CSS 去代替。

2.对于移动端来说,屏幕宽度那么点,完全没有必要去加载原图浪费带宽。一般图片都用 CDN 加载,可以计算出适配屏幕的宽度,然后去请求相应剪裁好的图片。

3.小图使用 base64 格式。

4.将多个图标文件整合到一张图片中(雪碧图)

5.选择正确的图片格式

  • 对于能够显示 WebP 格式的浏览器尽量使用 WebP 格式。因为 WebP 格式具有更好的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量,缺点就是兼容性并不好。
  • 小图使用 PNG,其实对于大部分图标这类图片,完全可以使用 SVG 代替
  • 照片使用 JPEG

# 2.DNS 预解析

DNS 解析也是需要时间的,可以通过与解析的方式来预先获得域名所对应的 IP

<link rel="dns-perfetch" href="//yuchengkai.cn">
1

# 3.节流

let throttle = (fn,wait){
  let lastTime = 0
  return function(...args){
    let now = +new Date()
    if(now - lastTime > wait){
      lastTime = now
      fn.apply(this,args)
    }
  }
}
setInterval(
  throttle(()=>{
    conosle.log(1)
  },500)
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 4.防抖

let debounce = (fn, wait) => {
  let timer = 0
  return function (...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, wait)
  }
}
1
2
3
4
5
6
7
8
9

# 5.预加载

在开发中,可能会遇到这样的情况。有些资源不需要马上用到,但是希望尽早获取,这时候就可以使用预加载。

预加载其实是声明式的fetch,强制浏览器请求资源,并且不会阻塞onload事件,可以使用以下代码开启预加载

<link rel="preload" href="http://example.com">
1

预加载可以一定程度上降低首屏的加载时间,因为可以将一些不影响首屏但重要的文件延后加载,唯一缺点就是兼容性不好。

# 6.预渲染

可以通过预渲染将下载的文件预选在后台渲染,可以使用以下代码开启预渲染

<link rel="prerender" href="http://example.com">
1

预渲染虽然可以提高页面的加载速度,但是要确保该页面大概率被用户在之后打开,否则就是白白浪费资源去渲染。

# 7.懒执行

懒执行即使将某些逻辑延迟到使用时在计算。该技术可以用首屏优化,对于磨削耗时逻辑并不需要在首屏就使用的,就可以使用懒执行。懒执行需要唤醒,一般可以通过定时器或者时间的调用来唤醒。

# 8.懒加载

懒加载就是将不关键的资源延后加载。

懒加载的原理就是只加载自定义区域(通常是可视区域,但也可以是即将进入可视区域)内需要加载的东西。对于图片来说,先设置图片标签的src属性为一张占位图,将真实的图片资源放入一个自定义属性中,当年进入自定义区域是,就将自定义属性替换为src属性,这样图片就会去下载资源,实现了图片懒加载。

懒加载不仅可以用于图片,也可以使用在别的资源上。比如进入可视区域才开始播放视屏等。

# 9.CDN

CDN 的原理是尽可能的在各个地方分布机房缓存数据,这样即使我们的根服务器远在国外,在国内的用户也可以通过国内的机房迅速加载资源。

因此,我们可以将静态资源尽量使用 CDN 加载,由于浏览器对于单个域名有并发请求上限,可以考虑使用多个 CDN 域名。并且对于 CDN 加载静态资源需要注意 CDN 域名要与主站不同,否则每次请求都会带上主站的 Cookie,平白消耗流量。

# 10.减少打包时间

  • 优化 loader:babel-loader
  • 并行打包:HappyPack
  • 减少打包次数:DllPlugin
  • resolve.extensions:用来表明文件后缀列表,默认查找顺序是['.js',''.json],如果你的导入文件没有添加后缀就会按照这个顺序查找五年级。我们应该尽可能减少后缀列表长度,然后将出现频率高的后缀排在前面。
  • resolve.alias:可以通过别名的方式来映射一个路径,能让 Webpack 更快遭到路径。
  • module.noParse:如果你确定一个文件没有其他依赖,就可以使用该属性让 Webpack 不扫描该文件,这种方式对于大型的类库很有帮助。

# 11.减少文件体积

  • 代码压缩:UglifyJS
  • Scope Hoisting 会分析出模块之间的依赖关系,尽可能的把打包出来的模块合并到一个函数中去
  • Tree Shaking 可以实现删除项目中未被引用的代码

# 12.移动端的性能优化

  • 1.首屏加载和按需加载,懒加载
  • 2.资源预加载
  • 3.图片压缩处理,使用 base64 内嵌图片
  • 4.合理缓存 dom 对象
  • 5.使用 touchstart 代替 click(click 300 毫秒延迟)
  • 6.利用 transform:translateZ(0),开启硬件 GPU 加速
  • 7.不滥用 web 字体,不滥用 float(布局计算消耗性能),减少 font-size 声明
  • 8.使用 viewport 固定屏幕渲染,加速首页渲染内容
  • 9.尽量使用事件代理,避免直接事件绑定

# 13.网站性能优化

  • http 请求方面:减少请求数量和体积
    • 压缩资源,减小请求头
    • 懒加载
    • dns 预解析预先获取域名对应的 ip
    • 控制资源的 dns 解析在 2 到 4 个域名
    • 提取公共样式和组件
    • 使用雪碧图,字体图表
    • 缓存资源
    • 减少 iframe 使用
    • 避免重定向
    • 减少 DNS 查询
    • 使用 CDN
  • 代码层优化
    • 节流和防抖
    • 提取公共方法
    • 减少对字符串计算
    • 合理使用闭包
    • 按需加载
    • 首屏的 js 资源加载放在最底部
    • 少用全局变量、缓存 DOM 节点查找的结果
  • 减少重排重绘
    • css 属性读写分离
    • 减少 js 修改样式
    • dom 离线更新
    • 渲染前指定图片的大小
    • 减少 DOM 元素数量
    • 减少 DOM 操作

# 14. vue 的 spa 如何优化加载速度

  • 1.减少入口文件的体积
  • 2.静态资源本地缓存
  • 3.开启 Gzip 压缩
  • 4.使用 ssr,nuxt.js

# 15.图片的懒加载和预加载

# 预加载:

提前加载图片,当用户需要查看时可以直接从本地缓存中渲染

为什么要使用预加载:在网页加载之前,对一些主要内容进行加载,减少等待时间,给用户提供更好的体验;否则,如歌一个页面的内容过于庞大,会出现留白。

  • 解决留白的方法:
      1. 预加载
      1. 使用 svg 占位图片,将一些结构快速搭建起来,等请求的数据来了之后,替换当前的占位符
  • 实现预加载的方法:
      1. 使用 html 标签
      1. 使用 Image 标签
      1. 使用 XMLHTTPRequest 对象,但会精细控制预加载过程;

# 懒加载:

客户端优化,减少 http 请求和延迟请求数量

  • 提升用户体验
  • 减少无效资源的加载
  • 防止并发加载资源过多会阻塞 js 的加载,影响网站的正常使用
  • 原理:首先将页面上的图片的 src 属性设置为空字符串,而图片的真路径则设置带 data-original 属性中;当页面滚动的时候去监听 scroll 事件,在 scroll 事件的回调中,判断我们的懒加载的图片是否进入可视区域;如果图片在可视区域将图片的 src 属性设置为 data-original 的值,这样就可以实现延迟加载。
上次更新: 2022/6/29 上午12:09:44