当涉及到优化 JavaScript 代码以提高性能时,以下是一些常用的技巧和方法:
1_减少重绘和重排
1.1_重绘与回流概念
回流 reflow 第一次确定节点的大小和位置,称之为布局(layout),之后对节点的大小、位置修改重新计算称之为回流(重新排布局)
什么情况下引起回流?
-
比如DOM结构发生改变(添加新的节点或者移除节点);
-
比如改变了布局(修改了width、height、padding、font-size等值)
-
比如窗口resize(修改了窗口的尺寸等)
-
比如调用getComputedStyle方法获取尺寸、位置信息;
重绘repaint
第一次渲染内容称之为绘制(paint), 之后重新渲染称之为重绘(重新渲染)
什么情况下会引起重绘? 比如修改背景色、文字颜色、边框颜色、样式等;
1.2_如何减少
回流一定会引起重绘,回流是一件很消耗性能的事情,所以在开发中要尽量避免发生回流。
如何避免发生回流?
-
修改样式时尽量一次性修改, 尽量使用 CSS 类来进行样式变更,而不是直接修改元素的样式。比如通过cssText修改,比如通过添加class修改
-
尽量避免频繁的操作DOM。可以在一个DocumentFragment或者父元素中
-
尽量避免通过getComputedStyle获取尺寸、位置等信息
-
对某些元素使用position的absolute或者fixed。 虽然会引起回流,但是开销相对较小,不会对其他元素造成影响
-
使用
transform和opacity属性来实现动画效果,而不是使用top、left等属性。
2_使用节流和防抖技术
2.1_概念
防抖debounce函数
- 当事件触发时,相应的函数并不会立即触发,而是会等待一定的时间;
- 当事件密集触发时,函数的触发会被频繁的推迟;
- 只有等待了一段时间也没有事件触发,才会真正的执行响应函数;
防抖的应用场景很多,比如下面的举例
- 输入框中频繁的输入内容,搜索或者提交信息;
- 频繁的点击按钮,触发某个事件;
- 监听浏览器滚动事件,完成某些特定操作;
- 用户缩放浏览器的resize事件;
节流throttle函数
当事件触发时,会执行这个事件的响应函数;
- 如果这个事件会被频繁触发,那么节流函数会按照一定的频率来执行函数;
- 不管在这个中间有多少次触发这个事件,执行函数的频繁总是固定的;
节流的应用场景:
- 监听页面的滚动事件;
- 鼠标移动事件;
- 用户频繁点击按钮操作;
- 游戏中的一些设计;
2.2_使用
可以通过一些第三方库来实现防抖操作,比如 lodash、 underscore
推荐使用underscore
- 虽然lodash是underscore的升级版,它更重量级,功能也更多;
- 但是目前underscore还在维护,lodash已经很久没有更新了;
Underscore的官网: underscorejs.org/
Underscore安装的多种方式
(1)通过CDN直接引入
<!-- CDN引入: 网络的js文件 -->
<script src="https://cdn.jsdelivr.net/npm/underscore@1.13.4/underscore-umd-min.js"></script>
(2)下载Underscore,本地引入;可以打开该网址,然后复制压缩好的代码,直接粘贴到一个新文件 。underscorejs.org/underscore-…
<!-- 本地引入 -->
<script src="./js/underscore.js"></script>
(3)通过包管理工具(npm)管理安装。前提是电脑已经安装了Node
npm install underscore
3_优化循环和遍历
- 尽量避免在循环中进行复杂的计算或访问慢速资源(如访问 DOM)。
- 使用更高效的循环方式,如 for 循环比 forEach 更快,for...of 比 for...in 更快。
- 考虑使用 Map、Set 和对象字面量等数据结构来替代传统的数组和对象,以提高查找和访问性能。
4_懒加载(Lazy Loading)
懒加载(Lazy Loading)是一种优化技术,用于延迟网页或应用程序中非必要资源的加载。它可以提高页面加载速度和性能,特别适用于包含大量图片、视频或其他媒体元素的网页。
懒加载的基本原理是将页面上的非必要资源推迟到用户需要时再加载,而不是一次性加载所有资源。这可以通过以下几种方式实现:
- 图片懒加载:将页面上的图片的 src 属性设置为一个占位符,当图片进入可见区域时,再将真实的图片地址赋给该属性,从而实现图片延迟加载。
- 视频懒加载:类似于图片懒加载,可以将视频的 src 属性设置为一个占位符地址,当用户点击播放按钮或滚动到视频出现的位置时,再将真实的视频地址赋给该属性。
- 资源分片加载:如果网页或应用程序有大量的 JavaScript 或 CSS 文件,可以将它们分割成多个小的文件,并根据需要进行加载,在用户浏览到相关功能模块时再加载相应的文件,避免一次性加载过多的资源。
- 滚动加载:当网页内容需要分页显示时,可以使用滚动加载来延迟加载新的内容。当用户滚动到页面底部时,自动加载更多内容,提供平滑的浏览体验。
5_使用性能分析工具
在 JavaScript 中,可以使用性能分析工具来检测和优化代码的性能。以下是几个常用的性能分析工具:
-
Chrome 开发者工具:Chrome 浏览器提供了强大的开发者工具,其中的 Performance 面板可以用于分析页面加载性能、CPU 使用情况、内存占用等。通过记录和分析时间轴,可以找出性能瓶颈,并进行相应的优化。
-
Firefox 开发者工具:类似于 Chrome 的开发者工具,Firefox 也提供了一套丰富的性能分析功能。使用 Firefox 的 Performance 工具,您可以跟踪函数调用、渲染时间、布局问题等,以便识别和解决性能问题。
-
Safari Web Inspector:Safari 浏览器的 Web Inspector 工具中包含了强大的性能分析功能。通过在 Timelines 面板上记录事件,您可以详细查看每个操作的执行时间,并了解与网络、脚本和渲染相关的性能指标。
-
Lighthouse:Lighthouse 是一个开源的自动化工具,可用于检验 Web 应用程序的质量和性能。它可以作为 Chrome 开发者工具的一部分.Lighthouse 提供了有关页面性能、无障碍性、SEO 等方面的详细报告,并提供相应的改进建议。
-
WebPagetest:WebPagetest 是一个在线工具,可用于分析网页加载和性能。它提供了全球各地服务器上运行的测试,可以模拟不同网络条件下的页面加载情况,并生成详细的性能报告。