入手点:
资源加载上
- 缩小首页渲染时间:关键资源的数量和大小做限制
- 删除不必要的代码和注释包括空格,尽量做到最小化文件
- 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。打包的时候用 ModuleConcatenationPlugin 开启 Scope Hoisting 作用域提升,提升代码在浏览器中的执行速度
- 利用浏览器的缓存机制
- 按需加载
DOM 操作页面刷新次数上
- 减少http请求次数
- 用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能。
- 当需要设置的样式很多时设置 className 而不是直接操作 style。
- 事件委托,减少操作 DOM 的机会
图片相关
优化图片着手点:
- 减少像素点
- 减少每个像素点能够显示的颜色
具体方案:
- 修饰类图片用 css 代替
- 用 CDN 加载图片
- 小图片转位 base64 格式
- 雪碧图:将多个图标文件整合到一张图片中
- 选择正确的图片格式
照片使用 JPEG 格式
小图片使用 PNG 格式,甚至是 SVG 格式
如果条件允许,可以用兼容性并不好的 WebP 格式,其具有更好的图片压缩算法因此体积更小而且具有肉眼识别无差异的图片质量
DNS(Domain Name System) 预解析
<link rel="dns-prefetch" href="//protein.cn">
DNS 的解析也是需要时间的,可以通过预解析预先获得域名对应的 IP 提高网页的载入速度
节流 --- 控制频率
所谓节流就是连续触发事件,但是在 n 秒内只执行一次,节流会稀释函数的执行频率
场景:滚动事件会发起网络请求,但是我们不希望用户在滚动过程中一直发起请求,而是隔一段时间发起一次,这就需要节流
// fun 是用户传入需要防抖的函数 wait 是等待时间
const throttle = ((fun, wait = 50) => {
// 上次函数执行的时间
let lastTime = 0
return function(...args) {
// 当前时间
let nowTime = + new Date()
// 将当前时间和上一次函数执行时间做对比,如果差值大于等待时间就执行函数
if(nowTime - lastTime > wait) {
lastTime = nowTime
fun.apply(this, args)
}
}
})
setInterval(throttle(() => {
console.log('----------')
}, 500), 0)
防抖 --- 控制次数
所谓防抖就是事件在 n 秒内只能执行一次,如果在 n 秒内又触发了事件,则从新计算函数执行时间
场景:有一个按钮点击触发请求事件,但是我们不希望每次点击都发起请求,而是用户点击一段时间之后没有再次点击的情况下发起请求,这种情况需要防抖
// fun 是用户传入需要防抖的函数 wait 是等待时间
const debounce = ((fun, wait = 500) => {
// 缓存一个定时器 task
let task = null
// 这里定义的是用户每次实际调用的防抖函数
// 如果已经设置了定时器就清空上一次的定时器
// 开始一个新的定时器,延时执行用户传入的方法
let taskFun = (() => {
if(task) clearTimeout(task)
task = setTimeout(() => {
fun()
}, wait)
})
taskFun()
})
let testFun = (() => {
return console.log('==========')
})
debounce(testFun, 2000)
预加载
针对一些不需要马上用到,但是又希望尽早获取的资源使用预加载
<link rel="preload" href="http://protein.com">
预加载是声明式的 fetch 强制浏览器的加载但是不会阻塞 onload 事件
预加载可以降低首屏的加载时间,因为可以将一些不影响首屏但是重要的文件延后加载,缺点是兼容性不好
预渲染
可以将下载的文件预先在后台进行渲染
<link rel="prerender" href="http://protein.com">
可以提高页面的渲染速度,但是要保证大概率被用户点开,不然也是浪费资源去渲染
懒执行
将某些逻辑延迟到使用时再计算。该技术可以用于首屏优化,对于某些耗时逻辑并不需要在首屏就使用的,就可以使用懒执行。懒执行需要唤醒,一般可以通过定时器或者事件的调用来唤醒。
懒加载
将不关键的资源延后加载:图片懒加载,表格懒加载
CDN
原理:尽可能的在各个地方分布机房缓存数据,这样即使我们的根服务器远在国外,在国内的用户也可以通过国内的机房迅速加载资源。
我们可以将静态资源尽量使用 CDN 加载,由于浏览器对于单个域名有并发请求上限,可以考虑使用多个 CDN 域名。并且对于 CDN 加载静态资源需要注意 CDN 域名要与主站不同,否则每次请求都会带上主站的 Cookie,平白消耗流量。