性能优化与调试
JavaScript是目前最为流行的Web编程语言。它为网页提供了丰富的交互和动态效果,同时也为Web开发者提供了许多有用的工具和技术。然而,随着网页和应用程序的复杂性不断增加,JavaScript的性能问题也变得越来越突出。因此,在Web应用程序的开发过程中,必须考虑如何优化JavaScript的性能,以提高应用程序的响应速度和用户体验。以下是总结的一些性能优化与调试技巧
1.减少重绘和重排
浏览器在下载完页面的所有组件——html,js,css,图片等之后,会解析并生成两个内部数据结构—— DOM树,渲染树一旦DOM树和渲染树构建完成,浏览器就开始绘制页面元素(paint)。重排发生的条件: 添加或删除可见的DOM元素位置变化,元素尺寸改变,内容改变,页面渲染器初始化,浏览器窗口尺寸变化,出现滚动条时会触发整个页面的重排,重排必定重绘。
减少重绘和重排的操作:
(1)减少使用以下几何属性
offsetTop, offsetLeft,...
scrollTop, scrollLeft, ...
clientTop, clientLeft, ...
大多数浏览器通过队列化修改并批量执行来优化重排过程,然而获取布局信息的操作会导致队列强制刷新。
(2)减少DOM操作
// 不推荐写法(频繁操作DOM)
const container = document.getElementById('container');
for (let i = 0; i < 1000; i++) {
const element = document.createElement('div');
element.textContent = 'Item ' + i;
container.appendChild(element);
}
// 推荐写法(合并DOM操作)
const container = document.getElementById('container');
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const element = document.createElement('div');
element.textContent = 'Item ' + i;
fragment.appendChild(element);
}
container.appendChild(fragment);
频繁的DOM操作会导致重绘和重新布局,影响性能。建议将多个DOM操作合并为一个操作,或者使用DocumentFragment来批量插入DOM元素。
2.节流和防抖技术
(1)防抖
任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。加入了防抖以后,当你在频繁的输入时,并不会发送请求,只有当你在指定间隔内没有输入时,才会执行函数。如果停止输入但是在指定间隔内又输入,会重新触发计时。
<input type="text" name="" id="" />
<script>
//防抖:用户触发事件,只要最后一次事件的操作
let inp = document.querySelector('input')
inp.oninput = debounce (function() {
console.log(this.value)
},500)
//闭包原理
function debounce(fn,delay) {
let t = null //因为闭包,t不会被销毁
return function () { //return返回值是一个内部函数
if(t !== null) {
clearInterval(t)
}
t = setTimeout(()=> {
fn.call(this);//this通过call改变成和debounce函数一样的指向
},delay);
}
}
防抖实现原理就是利用定时器,函数第一次执行时设定一个定时器,并且通过闭包缓存起来,之后调用时发现已经设定过定时器就清空之前的定时器,并重新设定一个新的定时器,如果存在没有被清空的定时器,当定时器计时结束后触发函数执行。
(2)节流
规定在一个单位时间内只能触发一次函数,如果在单位时间内触发多次,只执行一次。比如两秒内的点击事件,无论点多少次,两秒内只执行一次。
<style>
body {
height: 2000px;
}
</style>
<body>
<script>
//节流:控制执行次数
//控制高频事件的执行次数
window.onscroll = throttle(function () {
console.log('111')
}, 500)
//闭包原理
function throttle(fn, delay) {
let flag = true
return function () {
//return返回值是一个内部函数
if (flag) {
setTimeout(() => {
fn.call(this) //this通过call改变成和debounce函数一样的指向
flag =true
}, delay)
}
flag = false
}
}
</script>
</body>
就是通过一个布尔类型变量来判断是否可执行回调,当变量为true时,生成一个定时器,同时将变量取反通过闭包保存起来,当定时器执行完回调后,再将变量变为true,在变量为期false间,调用节流函数不会生成定时器。
3.性能分析工具
1. Chrome开发者工具:Chrome的开发者工具可以帮助我们检查代码执行时间、内存使用情况、网络请求等,十分方便。在使用过程中,我们可以使用Performance面板来查看性能分析信息。同时,还可以使用Memory和Network面板来监控内存和网络请求。2. JSLint和JSHint:JSLint和JSHint是两个质量工具,可以帮助我们检查JavaScript代码中的错误和潜在问题。在检查过程中,还可以自定义配置文件,以帮助我们更好地发现问题和优化代码。
3. Slow:YSlow是Yahoo出品的一款性能优化工具,可以帮助我们评估网站的性能,并给出相应的建议。在使用过程中,它会根据一系列的规则来检查网站的性能,并给出一些改进建议。
4. Firebug:Firebug是Firefox浏览器的一款插件,可以帮助我们查看JavaScript代码的执行速度、内存使用情况等。它还可以检查页面的HTML、CSS、JavaScript、网页结构、网络请求等。
5. WebPageTest:WebPageTest是一款在线性能分析工具,可以帮助我们测试网站在不同网络条件下的加载速度、渲染速度、响应时间等。它提供了多个测试服务器,可以根据不同的测试需求选择相应的测试服务器。