Day 5性能优化和调试 | 青训营
优化 JavaScript 代码可以显著提高性能和用户体验。以下是一些常见的优化技术,包括减少重绘和重排、使用节流和防抖技术以及使用性能分析工具等:
减少重绘和重排
避免频繁的 DOM 操作,尽量一次性进行批量处理。
- 使用 CSS 类而不是直接操作样式属性,以减少重绘和重排的次数。
- 使用 documentFragment 或离线 DOM 进行复杂的 DOM 操作,最后再将其添加到文档中,以减少重排的次数。
区别
重绘(Repaint)和重排(Reflow)是与浏览器渲染页面相关的两个概念,它们在性能优化中具有重要意义。以下是它们的区别:
重绘(Repaint): 重绘指的是当元素的可见样式发生变化,但布局(位置和大小)没有改变时,浏览器会重新绘制(repaint)该元素。重绘不涉及重新计算布局,只是将新的样式应用到元素上,使其显示更新的外观。例如,改变元素的颜色或背景色。
重排(Reflow): 重排指的是当元素的布局属性发生变化,需要浏览器重新计算元素的大小和位置时,会触发重排操作。重排会涉及重新计算布局,并重新绘制受影响的元素及其子元素。例如,改变元素的宽度、高度、位置、添加或删除元素等操作都会导致重排。
重绘和重排的区别在于是否涉及布局的计算和调整。重绘只是重新绘制元素的外观,而重排不仅会重新绘制元素,还会重新计算和调整元素的布局。
在性能优化中,重排的成本比重绘高得多,因为它涉及布局的计算和调整,可能会引起整个页面的重排和重绘。频繁的重排操作会导致页面性能下降,因此在代码编写时,应尽量减少重排的发生。
避免手段
一些减少重排和重绘的技术包括:
- 使用 CSS3 的
transform
属性替代top
、left
等属性来进行位移操作,因为transform
不会引起重排。 - 在进行多次 DOM 操作时,使用文档片段(
documentFragment
)进行批量操作,最后一次性添加到文档中,减少重排次数。 - 避免频繁读取布局信息(例如使用
offsetTop
、offsetLeft
等属性),因为这会导致浏览器强制进行重排。 - 使用 CSS 类名的切换来集中修改样式,而不是直接操作样式属性。
通过减少重排和重绘的次数,可以提高页面的性能和响应速度。
使用节流和防抖技术:
节流(Throttling)
限制在一定时间间隔内执行某个操作的频率。例如,在处理滚动事件时,可以使用节流来限制处理函数的调用频率。
function throttle<T extends unknown[]>(
func: (...args: T) => void,
delay: number
): (...args: T) => void {
let timerId: NodeJS.Timeout | null;
return function (...args: T) {
if (!timerId) {
timerId = setTimeout(() => {
func.apply(this, args);
timerId = null;
}, delay);
}
};
}
function handleScroll() {
console.log('Scroll event throttled');
}
const throttledScroll = throttle(handleScroll, 200);
window.addEventListener('scroll', throttledScroll);
防抖(Debouncing)
在一系列连续事件发生后,只执行一次操作。例如,在处理输入框的输入事件时,可以使用防抖来延迟处理函数的执行,直到用户停止输入一段时间。
function debounce<T extends unknown[]>(
func: (...args: T) => void,
delay: number
): (...args: T) => void {
let timerId: NodeJS.Timeout;
return function (...args: T) {
clearTimeout(timerId);
timerId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
function handleInput() {
console.log('Input debounced');
}
const debouncedInput = debounce(handleInput, 300);
input.addEventListener('input', debouncedInput);
优化循环和迭代:
避免在循环中进行昂贵的操作,例如 DOM 操作或复杂的计算。尽量将这些操作移到循环外部或使用更高效的算法。 使用合适的循环方式,例如 for 循环比 forEach 循环更高效。
使用异步操作:
将耗时的操作(例如网络请求或计算密集型任务)放在异步函数中执行,以避免阻塞主线程。
使用性能分析工具:
使用浏览器的开发者工具(如 Chrome 开发者工具)进行性能分析,查找性能瓶颈和优化的机会。 使用 JavaScript 性能分析工具(如 Lighthouse、Webpack Bundle Analyzer、Chrome DevTools 的 Performance 面板等)进行更深入的性能分析和优化建议。
压缩和缓存:
压缩 JavaScript 代码,减小文件大小,加快下载速度。可以使用工具如 UglifyJS、Terser 等进行代码压缩。 使用浏览器缓存机制,利用缓存来减少网络请求,提高页面加载速度。
懒加载和预加载:
对于大型页面或资源密集型应用,可以使用懒加载技术,延迟加载不必要的资源,只在需要时再进行加载。 针对已知将来需要使用的资源,可以使用预加载技术,在页面加载完成后立即开始加载这些资源,以提前获取并缓存。
懒加载
随着网页发展,对检测某个(些)元素是否出现在可视窗相关的需求越来越多,比如:
- 当页面滚动时,懒加载图片或其他内容。
- 实现“可无限滚动”网站,也就是当用户滚动网页时直接加载更多内容,无需翻页。
- 对某些元素进行埋点曝光
- 滚动到相应区域来执行相应动画或其他任务。 IntersectionObserver的诞生:
IntersectionObserver:是以
new
的形式声明一个对象,接收两个参数callback
和options;
option是一个对象,包含三个属性:1.root,所监听对象的具体祖先元素。如果未传入值或值为
null
,则默认使用顶级文档的视窗(一般为html)。2.rootMargin,计算交叉时添加到根(root)边界盒bounding box的矩形偏移量, 可以有效的缩小或扩大根的判定范围从而满足计算需要。所有的偏移量均可用像素(
px
)或百分比(%
)来表达, 默认值为"0px 0px 0px 0px"。3.threshold
// 使用 Intersection Observer API 监听元素是否进入可视区域
const io = new IntersectionObserver((entries) => {
entries.forEach((item) => {
if (item.isIntersecting) {
item.target.src = item.target.dataset.src;
io.unobserve(item.target);
}
});
}, {
root: document.querySelector('.root')
});
// 遍历所有需要懒加载的元素,添加 Intersection Observer 监听
imgList.forEach((img) => io.observe(img));
我们使用 Intersection Observer API 监听带有 img
类名的元素是否进入可视区域。一旦元素进入可视区域,就会触发回调函数,加载对应的懒加载内容
预加载
一个常见的预加载场景是在页面加载完成后,预加载下一个页面所需的关键资源,以提前获取并缓存这些资源,以便在用户切换到下一个页面时能够立即使用它们
// 创建一个新的Image对象
const preloader = new Image();
// 预加载的资源URL
const nextPageResource = 'https://example.com/next-page-resource.jpg';
// 预加载资源
preloader.src = nextPageResource;
// 在需要使用预加载资源的地方,检查资源是否已加载完成
if (preloader.complete) {
// 资源已加载完成,可以立即使用
handleNextPage();
} else {
// 资源尚未加载完成,监听load事件,在加载完成后执行操作
preloader.addEventListener('load', handleNextPage);
}
// 处理下一个页面的操作
function handleNextPage() {
// 执行需要在下一个页面中使用的操作
console.log('Next page resources are ready to use!');
// ...
}
这些技术只是优化 JavaScript 代码性能的一部分,具体的优化策略和技术选择应根据具体的应用场景进行调整和实施。同时,定期进行性能测试和分析,以便了解和改进应用的性能瓶颈。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbcfbf
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13