# 五.性能优化
# 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">
# 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)
)
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)
}
}
2
3
4
5
6
7
8
9
# 5.预加载
在开发中,可能会遇到这样的情况。有些资源不需要马上用到,但是希望尽早获取,这时候就可以使用预加载。
预加载其实是声明式的fetch
,强制浏览器请求资源,并且不会阻塞onload
事件,可以使用以下代码开启预加载
<link rel="preload" href="http://example.com">
预加载可以一定程度上降低首屏的加载时间,因为可以将一些不影响首屏但重要的文件延后加载,唯一缺点就是兼容性不好。
# 6.预渲染
可以通过预渲染将下载的文件预选在后台渲染,可以使用以下代码开启预渲染
<link rel="prerender" href="http://example.com">
预渲染虽然可以提高页面的加载速度,但是要确保该页面大概率被用户在之后打开,否则就是白白浪费资源去渲染。
# 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.图片的懒加载和预加载
# 预加载:
提前加载图片,当用户需要查看时可以直接从本地缓存中渲染
为什么要使用预加载:在网页加载之前,对一些主要内容进行加载,减少等待时间,给用户提供更好的体验;否则,如歌一个页面的内容过于庞大,会出现留白。
- 解决留白的方法:
- 预加载
- 使用 svg 占位图片,将一些结构快速搭建起来,等请求的数据来了之后,替换当前的占位符
- 实现预加载的方法:
- 使用 html 标签
- 使用 Image 标签
- 使用 XMLHTTPRequest 对象,但会精细控制预加载过程;
# 懒加载:
客户端优化,减少 http 请求和延迟请求数量
- 提升用户体验
- 减少无效资源的加载
- 防止并发加载资源过多会阻塞 js 的加载,影响网站的正常使用
- 原理:首先将页面上的图片的 src 属性设置为空字符串,而图片的真路径则设置带 data-original 属性中;当页面滚动的时候去监听 scroll 事件,在 scroll 事件的回调中,判断我们的懒加载的图片是否进入可视区域;如果图片在可视区域将图片的 src 属性设置为 data-original 的值,这样就可以实现延迟加载。