前言
在浏览器中,JavaScript负责实现动态的交互效果和复杂的业务逻辑,因此,JavaScript代码的性能也会影响到用户体验和页面加载速度。所以,掌握一些性能优化和调试技巧对于前端开发人员而言是十分必要的,提高JavaScript代码的运行效率和质量也应该是一个前端开发人员书写一段代码时的目标。
我们将从以下三个方面分析JS的性能优化与调试技巧:
- 减少重绘和重排
- 节流和防抖技术
- 性能分析工具
利用Javascript减少重绘和重排
- 重绘
重绘是指当元素的外观发生变化,但不影响布局时,浏览器重新绘制元素的过程。例如,改变元素的颜色、背景、边框等.
- 重排
重排是指当元素的尺寸、位置或者显示状态发生变化,导致布局发生变化时,浏览器重新计算元素的几何属性,并重新布局页面的过程。例如,改变元素的宽高、边距、定位、显示隐藏等。
特别值得注意的是:重排一定会引起重绘,但重绘不一定会引起重排。重排比重绘更耗费性能,因为它会影响到后续元素的布局和渲染。
-
为了减少重绘和重排,我们可以采取以下的措施:
- 尽量避免频繁地修改元素的样式属性,尤其是影响布局的属性。如果需要修改多个属性,可以使用requestAnimationFrame 或者 setTimeout 将修改操作放在一次回调函数中执行,或者使用 documentFragment 或者display:none 先将元素从文档流中移除,再进行批量修改,最后再插入文档流中。
- 尽量避免使用表格布局,因为表格中的任何一个元素发生变化都会导致整个表格重新布局。
- 在非必要的情况下,尽量避免使用CSS表达式(expression),因为它会在每次页面染时都重新计算值,导致性能下降。
- 尽量使用 transform、 opacity 、 filter 等不影响布局的属性来实现动画效果,而不是使用left 、top 、 width.height 等影响布局的属性
- 尽量使用绝对定位或者固定定位的元素来实现动画效果,因为它们不会影响其他元素的布局。
- 尽量避免在低层级的元素上使用 z-index 属性,因为它会创建一个新的层叠上下文 (stacking context)导致该元素及其子元素重新渲染.
使用节流和防抖技术
- 节流(throtle) 和防抖 (debounce) 是两种常用的优化技术,它们可以减少函数的执行频率,从而提高性能。
- 节流是指在一定时间间隔内,只执行函数的第一次或最后一次调用,忽略中间的调用。
- 例如,我们可以使用节流来优化窗的 resize 事件或者鼠标的 mousemove 事件,避免在短时间内触发过多的回调函数。
- 防抖是指在一定时间间隔内,只执行函数的最后一次调用,取消前面的调用。例如,我们可以使用防抖来优化输入框的keyup 事件或者按钮的 cick 事件,避免在用户输入或点击过程中触发过多的回调函数。
- 我们可以使用以下的方法
- 使用 setTimeout 和 clearTimeout 来控制函数的执行时间。例如,我们可以在函数开始时设置一个定时器,在定时器到期后执行函数,并清除定时器,或者我们可以在函数结束时设置一个定时器,在定时器到期后执行函数,并取消前面的定时器。
- 使用Date.now()或者 performance.now() 来获取当前时间戳,并与上一次执行时间进行比较。例如,我们可以在函数开始时获取当前时间戳,并与上一次执行时间进行比较,如果超过了设定的时间间隔,则执行函数,并更新上一次执行时间:或者我们可以在函数结束时获取当前时间戳,并与上一次执行时间进行比较,如果没有超过设定的时间间隔,则延迟执行函数,并更新上一次执行时间。
- 使用第三方库或者工具来实现节流和防抖功能。例如,我们可以使用lodash、underscore等库中提供的 _.throttle和.debounce 方法来简化代码; 或者我们可以使用Chrome DevTools中提供的Throttling和Debounce工具来模拟网络延迟和用户输入。
防抖和节流的意义?
- 节流可以保证在一定时间间隔内至少执行一次函数,避免因为频繁触发事件而导致页面卡顿- 或者响应延迟.
- 防抖可以保证在一定时间间隔内只执行一次函数,避免因为重复触发事件而导致不必要的计算或者请求。
- 节流和防抖都可以提高页面的性能和用户体验,减少资源的浪费和网络的拥堵。
性能分析工具的使用
性能分析工具可以帮助我们检测和优化JavaScript代码的性能,它们可以提供以下一些功能:
- 记录和展示代码的执行过程和时间,比如主线程的事件循环、每个事件循环的任务、每个任务的调用栈、每个函数的耗时等。
- 定位和高亮代码中的性能瓶颈和问题,比如内存泄露、过多的重绘和重排、低效的循环和函数等。
- 提供一些优化建议和解决方案,比如使用缓存、节流和防抖、减少全局变量、使用直接量等.