1.图片优化
除了传统的图片懒加载手段,还可以使用WebP图片格式替换。
WebP是Google开发的一种新的图片格式,它支持有损压缩、无损压缩和透明度,压缩后的文件大小比JPEG、PNG等都要小。所以可以节省带宽,减少页面载入时间,节省用户的流量。
由于可能存在兼容性问题,需要在替换之前进行兼容性试探:
const supportWebp = () => new Promise(resolve => {
const image = new Image()
image.onerror = () => resolve(false)
image.onload = () => resolve(image.width === 1)
image.src = 'src'
}).catch(() => false)
2.按需加载
资源打包配置不合理会影响性能表现,可以借助构建工具对资源进行合并打包,但要注意bundle.js文件体积,需要进行逆向代码拆分。
工程方面涉及的性能优化还包括雪碧图、合理设置缓存策略、使用prefetch或preload进行预加载、以tree shaking手段为主进行代码瘦身等。
3.动画效果
- CSS3动画会比基于js实现的动画效率高。考虑开启GPU加速。
- 优先使用资源消耗最低的transform和opacity。
- 使用will-change属性。
- 独立合成层,减少绘制区域。
- 批量进行样式变换,减少布局抖动。
- 如果只能使用js实现动画,考虑使用requestAnimationFrame 和 requestIdleCallback API。
4.布局抖动
是指DOM元素被js反复读写,导致文档多次无意义重排。
var h1 = element1.clientHeight
element1.style.height = (h1 * 2) + 'px'
var h2 = element2.clientHeight
element2.style.height = (h2 * 2) + 'px'
浏览器会合并(batch)当前操作,统一进行重排。但在当前操作完成前从DOM元素中获取值,就会迫使浏览器提早执行布局操作,被称为强制同步布局。代码优化:
var h1 = element1.clientHeight
var h2 = element2.clientHeight
element1.style.height = (h1 * 2) + 'px'
element2.style.height = (h2 * 2) + 'px'
也可以使用requestAnimationFrame来更新重绘,当你需要更新屏幕画面时调用此方法,浏览器在下次重绘前会统一执行回调函数。
var h1 = element1.clientHeight
requestAnimationFrame(() => {
element1.style.height = (h1 * 2) + 'px'
})
var h2 = element2.clientHeight
requestAnimationFrame(() => {
element2.style.height = (h2 * 2) + 'px'
})
如果浏览器兼容性不支持requestAnimationFrame,可以自己代码模拟实现:
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (callback, element) => {
const id = window.setTimeout(() => {
callback()
}, 1000/60)
return id
}
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = id => {
clearTimeout(id)
}
}
按照每秒钟60次屏幕刷新频率,并使用setTimeout模拟。
5.事件委托
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
如果要给每个li元素绑定点击事件,直接绑定不仅代码相对繁琐,而且会造成性能负担,应该使用事件委托。
window.onload = () => {
const ul = document.getElementsByTagName('ul')[0]
ul.onclick = e => {
const currentEvent = e || window.event
cosnt target = currentEvent.target || currentEvent.srcElement
if (target.nodeName.toLowerCase() === 'li') {
//
}
}
}
6.防抖、节流
两者并不会减少事件的触发,而是减少事件触发时回调函数的执行次数。
- 防抖:把短时间内的多个连续调用归并为一次,只触发一次回调。
- 节流:使短时间内的函数调用以一个固定频率间隔执行。