本文将探讨如何通过优化JavaScript代码来提高性能,包括减少重绘和重排、使用节流和防抖技术、使用性能分析工具等。
减少重绘和重排
首先需要了解一下重绘和重排的概念:
重排(Reflow)
重排,也称为回流,是指浏览器重新计算元素的几何属性(如位置、大小等)并重新排列页面元素的过程。当DOM结构发生变化,或者元素的样式变化影响到元素的布局时,就会触发重排。
触发重排的情况:
- 添加或删除可见的DOM元素。
- 元素位置、大小或内容发生变化。
- 页面尺寸变化,如调整浏览器窗口大小。
- 元素的字体大小变化。
- 计算元素的
offsetTop、offsetLeft、scrollTop、scrollLeft、clientTop、clientLeft、getComputedStyle()等属性。
重绘(Repaint)
重绘是指在元素的几何属性没有变化,但是元素的外观发生变化(如颜色、阴影、边框颜色等)时,浏览器需要重新绘制元素以反映这些变化。
触发重绘的情况:
- 改变元素的背景色、文本颜色。
- 改变元素的边框样式或颜色。
- 应用CSS动画或过渡效果。
- 改变元素的透明度。
解决方法
- 减少DOM操作:批量处理DOM操作,避免在循环中直接操作DOM。
- 使用文档碎片(DocumentFragment) :在添加多个元素到DOM时,使用
DocumentFragment来减少重排次数。 - 使用CSS类控制元素样式:使用CSS类来控制元素的样式,而不是直接通过JavaScript修改样式属性。
- 优化JavaScript动画:使用
requestAnimationFrame()来优化动画,减少重绘和重排。这个方法专门设计用于高效、一致地处理动画帧,以获得流畅的用户体验。 - 使用硬件加速:在某些情况下,可以通过
transform和opacity属性来利用硬件加速,从而减少重绘和重排。 - 避免复杂的选择器和深层的DOM结构:复杂的CSS选择器和深层的DOM结构会增加重排的计算成本。
使用节流和防抖技术
浏览器的 resize、scroll、keypress、mousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能。
为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用 防抖(debounce) 和 节流(throttle) 的方式来减少调用频率。
节流
节流限制函数在指定的时间间隔内最多执行一次,无论触发了多少次事件。
function throttled(fn, delay) {
let timer = null
let starttime = Date.now()
return function () {
let curTime = Date.now() // 当前时间
let remaining = delay - (curTime - starttime) // 从上一次到现在,还剩下多少多余时间
let context = this
let args = arguments
clearTimeout(timer)
if (remaining <= 0) {
fn.apply(context, args)
starttime = Date.now()
} else {
timer = setTimeout(fn, remaining);
}
}
}
防抖
防抖技术确保在事件触发后,只有在一定时间内没有再次触发事件时,才执行一次函数。
function debounce(func, wait, immediate) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout); // timeout 不为null
if (immediate) {
let callNow = !timeout; // 第一次会立即执行,以后只有事件执行后才会再次触发
timeout = setTimeout(function () {
timeout = null;
}, wait)
if (callNow) {
func.apply(context, args)
}
}
else {
timeout = setTimeout(function () {
func.apply(context, args)
}, wait);
}
}
}
性能分析工具
PageSpeed Insights
- PageSpeed Insights(PSI)是由谷歌提供的一款免费工具,专门用于评估网站性能并提供改进建议。使用方法非常简单,只需访问其官方网站,输入要测试的网页的URL,然后点击“分析”按钮即可。
- PSI能够针对移动设备和桌面设备生成网页的实际性能报告,并提供关于如何改进相应网页的建议。
- PSI会报告两项指标,即FCP和DCL,并根据这些指标在所有网页加载速度分布图中的位置为其指定一个类别:快、中等、慢。
Lighthouse
- LightHouse能生成一个包括页面性能、PWA(Progressive Web apps,渐进式 Web 应用)、可访问性、最佳实践、SEO 的报告清单提供参考。