浏览器中某些计算和处理要比其他的昂贵很多,例如DOM操作、AJAX请求等。
函数节流的基本思想是,某些代码不可以没有间断的情况下连续重复执行。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次条用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。目的是只有再执行函数的请求停止了一段时间之后才执行。以下是该模式的基本形式:
var processor = {timeoutId: null,// 实际进行处理的方法performProcessing: function () {// 实际执行的代码},// 初始处理调用的方法process: function () {clearTimeout(this.timeoutId)var _this = thisthis.timeoutId = setTimeout(function () {_this.performProcessing()}, 100)}
}// 尝试开始执行
processor.process()
以上这个方法时间间隔设置为100ms,如果100ms内调用了多次process(),实际上仍然只会被调用一次。
这个模式可以使用throttle()函数来简化,这个函数可以自动进行定时器的设置和清除。如下:
function throttle(method, context) {clearTimeout(method.tId)methods.tId = setTimeout(function () {method.call(context)}, 100)
}
节流的使用场景
节流在resize事件中是最常用的。改变页面布局频繁相当于操作DOM,会消耗大量CPU资源。例如,一个div元素需要保持它的高度始终等于宽度。实现代码如下:
window.onresize = function () {var div = document.getElementById('myDiv')div.style.height = div.offsetWidth + 'px'
}
这段代码如果该元素上有非常复杂的CSS,这个过程的计算将会很复杂。使用throttle()函数来优化:
function resizeDiv() {var div = document.getElementById('myDiv')div.style.height = div.offsetWidth + 'px'
}window.onresize = function() {throttle(resizeDiv)
}
只要代码是周期性执行的,都应该使用节流,但是不能控制请求执行的速率。