常见的前端性能优化方案 , 它可以防止JS高频渲染页面时出现的视觉抖动(卡顿):比如
如果内容的渲染速度过快,都可能会造成抖动效果,并且连带会浪费性能。
这个时候就可以适用防抖来进行优化
防抖优化之后的效果可以通过一些具体的网站来进行确认,比如12306,他就是通过防抖进行的优化:
let timeId
document.querySelector('.search-city').addEventListener('input', function () {
// 2. 清除已开启的定时器
clearTimeout(timeId)
// 1. 开启定时器,保存定时器id
timeId = setTimeout(() => {
renderCity(this.value)
}, 500)
})
实际开发中一般不需要手写防抖,因为已经有库里面提供了对应的方法,可以直接调用,也可以自己手写实现debounce
,一会咱们就从这两个方面进行讲解:
lodash
工具库中的debounce
方法(常用)debounce
的实现原理(高频面试题)_.debounce(func, [wait=0], [options=])
func
(Function): 要防抖动的函数。[wait=0]
(number): 需要延迟的毫秒数。[options=]
(Object): 选项对象。[options.leading=false]
(boolean): 指定在延迟开始前调用。[options.maxWait]
(number): 设置 func
允许被延迟的最大值。[options.trailing=true]
(boolean): 指定在延迟结束后调用。(Function): 返回新的 debounced(防抖动)函数。
注意:
lodash
那么直接使用它提供的debounce
即可,不仅可以实现防抖,原函数中的this
和参数
均可以正常使用。手写实现debounce
函数,实现lodash
中debounce
方法的核心功能。
func
(Function): 要防抖动的函数。[wait=0]
(number): 需要延迟的毫秒数。this
可以正常使用function debounce(func, wait = 0) {
let timeId
// 防抖动的新函数
return function (...args) {
let _this = this
clearTimeout(timeId)
timeId = setTimeout(function () {
// 通过apply调用原函数,并指定this和参数
func.apply(_this, args)
}, wait)
}
}
常见的前端性能优化方案 , 它可以防止高频触发事件造成的性能浪费:比如
ajax
提交到服务器适用场景: 在触发频率高的事件中, 执行耗费性能操作 , 连续触发 , 单位时间内只有一次生效。
优化之前: 每当触发事件就会执行业务逻辑。
优化之后: 触发事件之后延迟执行逻辑,在逻辑执行完毕之前无法再次触发。
使用节流将播放器记录时间的例子优化:
核心步骤:
1.开启定时器,并保存 id
2.判断是否已开启定时器,若已开启,则直接返回
3.定时器执行时 , id设置为空
// 播放器案例优化之后代码
let timeId
video.addEventListener('timeupdate', function () {
if (timeId !== undefined) {
return
}
timeId = setTimeout(() => {
console.log('timeupdate触发')
localStorage.setItem('currentTime', this.currentTime)
timeId = undefined
}, 3000)
})
实际开发中一般不需要手写节流,因为已经有库里面提供了对应的方法,可以直接调用,也可以自己手写实现throttle
,一会咱们就从这两个方面进行讲解:
lodash
工具库中的throttle
方法(常用)throttle
的实现原理(高频面试题)_.throttle(func, [wait=0], [options=])
func
(Function): 要节流的函数。[wait=0]
(number): 需要节流的毫秒。[options=]
(Object): 选项对象。[options.leading=true]
(boolean): 指定在节流开始前调用。[options.trailing=true]
(boolean): 指定在节流结束后调用。(Function): 返回节流的函数。
注意:
options.leading=true
默认为true
,开始时触发节流函数,一般设置为false
。lodash
那么直接使用它提供的throttle
即可,不仅可以实现节流,原函数中的this
和参数
均可以正常使用。// 播放器案例使用`lodash` 优化之后的结果如下
const func = function (e) {
console.log('timeupdate触发')
console.log('e:', e)
localStorage.setItem('currentTime', this.currentTime)
}
const throttleFn = _.throttle(func, 1000, { leading: false })
video.addEventListener('timeupdate', throttleFn)
手写实现throttle
函数,实现lodash
中throttle
方法的核心功能。
func
(Function): 要节流的函数。[wait=0]
(number): 需要节流的毫秒。this
可以正常使用// 节流工具函数
function throttle(func, wait = 0) {
let timeId
return function (...args) {
if (timeId !== undefined) {
return
}
const _this = this
timeId = setTimeout(() => {
func.apply(_this, args)
timeId = undefined
}, wait)
}
}