内容简介:浏览器中某些计算和处理非常昂贵。比如当鼠标响应下面来看一个例子,根据输入框输入的数据发送ajax请求:普通处理结果如下:
浏览器中某些计算和处理非常昂贵。比如当鼠标响应 resize , touchmove , scroll 等操作时,绑定的函数触发的频率会很高,如果该函数稍微复杂一些,响应速度会远远跟不上触发频率,便会出现卡顿,延迟,假死等现象。
下面来看一个例子,根据输入框输入的数据发送ajax请求:
<!DOCTYPE html>
<html>
<head>
<title>普通处理</title>
</head>
<body>
<div>
普通处理:<input type="text" id="index"/>
</div>
<script>
window.onload = () => {
function ajax (data) {
console.log(new Date().toLocaleTimeString() + ' - ' + data)
}
document.querySelector('#index').addEventListener('keyup', e => {
ajax(e.target.value)
})
}
</script>
</body>
</html>
复制代码
普通处理结果如下:
如上图所见,在输入时会不断的发送请求,非常浪费资源。为优化性能,我们可以使用防抖或节流来防止函数被高频调用。
防抖Debounce
原理
在事件被触发n秒后,再去执行回调函数。如果n秒内该事件被重新触发,则重新计时。结果就是将频繁触发的事件合并为一次,且在最后执行。
例如
电梯5秒后会关门开始运作,如果有人进来,等待5秒,5秒之内又有人进来,5秒等待重新计时...直至超过5秒,电梯才开始运作。
使用场景
input输入数据时请求服务器等。
实现
每当事件触发,就去重置定时器。直至最后一次事件被触发,n秒后再去执行回调函数。
<!DOCTYPE html>
<html>
<head>
<title>加入防抖</title>
</head>
<body>
<div>
加入防抖:<input type="text" id="debounce"/>
</div>
<script>
window.onload = () => {
function ajax (data) {
console.log(new Date().toLocaleTimeString() + ' - ' + data)
}
function debounce (fn, delay) {
return args => {
clearTimeout(fn.id)
fn.id = setTimeout(() => {
fn.call(this, args)
}, delay)
}
}
const debounceAjax = debounce(ajax, 1000)
document.querySelector('#debounce').addEventListener('keyup', e => {
debounceAjax(e.target.value)
})
}
</script>
</body>
</html>
复制代码
加入防抖结果如下:
节流Throttle
原理
规定一个时间n,n秒内,将触发的事件合并为一次并执行。
例如
电梯等第一个人进来之后,5秒后准时运作,不等待,若5秒内还有人进来,也不重置。
使用场景
resize , touchmove 移动DOM,上拉列表加载数据等。
1.定时器
<!DOCTYPE html>
<html>
<head>
<title>加入节流-定时器</title>
</head>
<body>
<div>
加入节流-定时器:<input type="text" id="throttle"/>
</div>
<script>
window.onload = () => {
function ajax (data) {
console.log(new Date().toLocaleTimeString() + ' - ' + data)
}
function throttle (fn, delay) {
return args => {
if (fn.id) return
fn.id = setTimeout(() => {
fn.call(this, args)
clearTimeout(fn.id)
fn.id = null
}, delay)
}
}
const throttleAjax = throttle(ajax, 1000)
document.querySelector('#throttle').addEventListener('keyup', e => {
throttleAjax(e.target.value)
})
}
</script>
</body>
</html>
复制代码
加入节流-定时器结果如下:
2.时间戳
<!DOCTYPE html>
<html>
<head>
<title>加入节流-时间戳</title>
</head>
<body>
<div>
加入节流-时间戳:<input type="text" id="throttle"/>
</div>
<script>
window.onload = () => {
function ajax (data) {
console.log(new Date().toLocaleTimeString() + ' - ' + data)
}
function throttle (fn, delay) {
let last = 0
return args => {
let now = Date.now()
if (now > last + delay) {
fn.call(fn, args)
last = now
}
}
}
const throttleAjax = throttle(ajax, 1000)
document.querySelector('#throttle').addEventListener('keyup', e => {
throttleAjax(e.target.value)
})
}
</script>
</body>
</html>
复制代码
加入节流-时间戳结果如下:
3.定时器 & 时间戳
<!DOCTYPE html>
<html>
<head>
<title>加入节流-定时器 & 时间戳</title>
</head>
<body>
<div>
加入节流-定时器 & 时间戳:<input type="text" id="throttle"/>
</div>
<script>
window.onload = () => {
function ajax (data) {
console.log(new Date().toLocaleTimeString() + ' - ' + data)
}
function throttle(fn, delay) {
let last
return args => {
let now = Date.now()
if (last && now < last + delay) {
clearTimeout(fn.id)
fn.id = setTimeout(() => {
fn.call(this, args)
last = now
}, delay)
} else {
fn.call(this, args)
last = now
}
}
}
const throttleAjax = throttle(ajax, 1000)
document.querySelector('#throttle').addEventListener('keyup', e => {
throttleAjax(e.target.value)
})
}
</script>
</body>
</html>
复制代码
加入节流-定时器 & 时间戳结果如下:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ACM国际大学生程序设计竞赛题解
赵端阳//袁鹤 / 电子工业 / 2010-7 / 39.00元
随着各大专院校参加ACM/ICPC热情的高涨,迫切需要有关介绍ACM国际大学生程序设计竞赛题解的书籍。《ACM国际大学生程序设计竞赛题解(2)》根据浙江大学在线题库的部分题目,经过分类、筛选、汇编,并进行了解答(个别特别简单或者特别复杂的题目未选择),比较详细地分析和深入浅出地讲解了解题的方法和用到的算法。题目的类型包括基础编程、模拟、字符串处理、搜索、动态规划、回溯、图论、几何和数学题。 ......一起来看看 《ACM国际大学生程序设计竞赛题解》 这本书的介绍吧!