вводить
Некоторые вычисления и обработка в браузере обходятся очень дорого. например, когда мышь отвечает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 или throttling, чтобы предотвратить частый вызов функций.
Отказаться
принцип
Функция обратного вызова выполняется через n секунд после запуска события. Retime, если событие повторно запускается в течение n секунд. В результате часто запускаемые события объединяются в одно и выполняются в конце.
Например
Лифт закроет дверь через 5 секунд и начнет работать.Если кто-то войдет, подождите 5 секунд.Если кто-то войдет в течение 5 секунд, подождите 5 секунд, чтобы перезапустить таймер... Пока не пройдет более 5 секунд, лифт лифт не начнет работать.
сцены, которые будут использоваться
При вводе данных запрашивать сервер и т.д.
выполнить
Всякий раз, когда происходит событие, сбрасывайте таймер. Пока не сработает последнее событие, функция обратного вызова будет выполнена через 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>
Результат добавления антишейка следующий:
Дроссельная заслонка
принцип
В указанное время 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>
Добавление результатов throttling-timestamp следующим образом:
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>
Добавление результатов таймера регулирования и метки времени следующим образом:
резюме
Эта статья в основном знакомит с реализацией анти-тряски и дросселирования. в,防抖
Основная идея состоит в том, что выполнение высокочастотных операций заканчивается, и только один раз через n секунд; и节流
выполняется время от времени.
Спасибо за прочтение, если есть вопросы, поправьте меня.