面试题汇总
# 1.防抖 与 节流 --性能提升
掘金文章链接:https://juejin.cn/post/6844903669389885453
防抖与节流 都是在用户 反复触发某些事件之后,在固定时间内该函数只执行一次的操作,提升函数性能
无防抖节流的事件,造成性能浪费
<input type="text" placeholder="请输入需要的数据" >
<script>
// 需求:百度搜索框 输入数据就进行搜索
let inp = document.querySelector('input');
const search = ()=>{
console.log('请求ajax,开始搜索...');
}
//绑定事件--无防抖节流时,每次输入均会请求一次ajax【造成大量的性能浪费】
inp.addEventListener('input',search);
</script>
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 1.1 函数防抖 debounce
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
理解:固定时间内反复触发事件,只执行最后一次触发的事件,没有反复触发,就延迟触发一次
理解:英雄联盟的回城,反复按回城按钮 只会执行最后一次回城操作 .
- 加上防抖概念 实现 固定时间返回触发,只执行最后一次
// 防抖:固定时间内 只执行一次事件的执行函数
let inp = document.querySelector('input');
// 存延时器的id
var timer;
const search = ()=>{
//因为固定时间只能执行一次,每次输入都会触发这个执行函数
//如果在1s内反复触发这个事件,导致函数反复执行,只有最后一次触发可以真正发送
clearTimeout(timer)
// 等待1s请求一次
timer = setTimeout(()=>{
console.log('请求ajax,开始搜索...');
},1000)
}
//绑定事件--无防抖节流时,每次输入均会请求一次ajax【造成大量的性能浪费】
inp.addEventListener('input',search);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
将延时器 添加 到事件执行函数的外面包起来[换个语法]
let inp = document.querySelector('input');
//执行函数
const search = () => {
console.log('请求ajax,开始搜索...');
}
// 存延时器的id
var timer;
//绑定事件--无防抖节流时,每次输入均会请求一次ajax【造成大量的性能浪费】
inp.addEventListener('input', function(){
clearTimeout(timer)
timer = setTimeout(() => {
search()
}, 1000)
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
- 封装 debounce 防抖函数 实现万能方法
封装完成之后,不管是任何事件 都可以 使用这个防抖函数
debounce(事件执行函数,防抖时长)
//将延时器相关的代码封装到一个函数中:防抖函数
let inp = document.querySelector('input');
//执行函数
const search = () => {
console.log('请求ajax,开始搜索...');
}
// 封装必须使用 箭头函数 不然 this指向会出现问题
// callback:事件执行函数的函数体
// delay:延时时长
const debounce = (callback,delay)=>{
clearTimeout(callback.timer)
//借助函数也是一个对象的 直接给这个函数挂一个timer 属性
// timer 的值存在 window.callback.timer || window.search.timer
callback.timer = setTimeout(() => {
callback()
}, delay)
}
inp.addEventListener('input', function(){
debounce(search,1000)
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1.2 函数节流 throttle
规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效
理解:每间隔 一段时间,如果反复触发,只有第一次触发,没有反复触发(只触发了一次),就直接触发
理解:LOL 英雄的技能按键,只有等待CD 倒计时结束这个阶段一直反复按技能键,也不会触发技能,只有等到技能CD结束才可以触发下次
let inp = document.querySelector('input');
//执行函数
const search = () => {
console.log('请求ajax,开始搜索...');
}
const debounce = (callback,delay)=>{
// 定义时间 起点
callback.start;
// 获取当前时间-时间戳
let now = new Date().getTime();
// 如果有起点(至少是第二次触发) 且当前这个触发的时间在 起点和 固定时间范围内(终点)
if(callback.start && callback.start < now <callback.start+delay ){
// 清除所有的延时器,确保最后一次的执行
clearTimeout(callback.timer)
// 添加一个延时器,最后一次需要延时执行【确保最后一次 在下1s再次触发】
callback.timer = setTimeout(() => {
// 记录最后一次执行的时间 :为下次触发做出判断
callback.start = now;
callback()
}, delay)
}else{
// 如果时第一次触发,赋值起点时间,瞬间执行函数:防止瞬间触发 为做判断准备
callback.start = now ;
callback()
}
}
inp.addEventListener('input', function(){
debounce(search,1000)
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 1.3 使用场景
debounce
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
throttle
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
# 2.图片懒加载
# 2.vue2 mixin 和 vue3 自定义hooks
编辑 (opens new window)