防抖
现在有这样一个场景,给出一个
button,每次点击这个button就会发送请求,像这样:
如图,我点击了这个
button五次,执行了五次发送请求,乍一看似乎没什么问题,但是,如果在真实的业务场景中,这样发送一起请求,还没有等到结果返回回来就再次发送请求,这样必然会有大量的性能上的开销,并且也会造成返回结果出错的问题。为了解决这个问题,引入防抖(debounce)的概念: 现在点击这个
button,函数并不会立即执行,而是给出这样一个间隔delay,如果在这个间隔以内没有再次触发事件那么就执行函数,如果在这个间隔以内再次触发这个事件,那么就将当前的间隔取消,重新开始计时。
function Done(){
console.log("发送请求")
}
function debounce(func,delay){
let timer;
return function(){
const context=this;
const args=arguments;
clearTimeout(timer);
timer = setTimeout(function () {
func.apply(context,args);//闭包,特别注意this的变化
},delay);
}
}
btn1.addEventListener("click",debounce(Done,1000));
节流
节流通常指在一段时间内只调用一次事件处理函数,还是已上方发送请求为例,点击这个
button会发送一个请求,假设这个函数执行需要花1s的事件,那么在这段事件内我们只希望能够运行这一次函数,避免多次请求。 节流通常有两种写法
//通过setTimeout
function trottle1(func,delay){
let timer;
return ()=>{
if(timer) return;
let context=this;
let args=arguments;
timer=setTimeout(()=>{
func.apply(context,args);
timer=null;
},delay);
}
}
//通过new Date()
function trottle2(func,delay){
let pre=0;
return ()=>{
let now=new Date();
if(now-pre>delay){
func();
pre=now;
}
}
}
document.addEventListener("click",trottle2(Done,1000))
懒加载
网页内容如下图所示
网页如果包含大量图片,并且网速较差,那么就会影响网页渲染速度
一个优化思想就是调整图片的src属性,只有需要的时候才给出正确的url
我们将所有的src属性改写成data_src,需要的时候再进行修改
//低性能版
//事件累积
const imgs=document.querySelectorAll("img");
window.addEventListener("scroll",(e)=>{
imgs.forEach((img)=>{
const imgTop=img.getBoundingClientRect.top;//距离dom顶部距离
if(imgTop<window.innerHeight){
const data_src=img.getAttribute("data_src");
img.setAttribute("src",data_src);
}
})
})
//视口交叉
const imgs=document.querySelectorAll("img");
const observer=new IntersectionObserver((entries)=>{
entries.forEach((entry)=>{
if(entry.isIntersecting){
const img=entry.target;
const data_src=img.getAttribute("data_src");
img.setAttribute("src",data_src) ;
}
})
})
imgs.forEach((img)=>{
observer.observe(img);
})