Ефективност“ трябва да е първото нещо, което трябва да ни хрумне, докато създаваме уебсайт. И debouncing е само един от методите, които наистина биха помогнали за подобряване на производителността на вашия уебсайт.

Толкова е лесно за изпълнение, ако имате основни познания за Javascript. Така че в тази статия ще се опитаме да разберем премахването на отскок. Но първо нека видим как изглежда премахването на отскок, например: Спомняте ли си да сте въвели полето за търсене за онлайн магазин като Amazon, Flipkart..?? Ще забележите, че докато въвеждате знаците в полето за търсене, ще ви предложи правилните думи в зависимост от знаците, които въвеждате в полето за търсене. Как става това..?? Е, всеки път, когато знак се въведе в полето за търсене, се прави заявка за API, за да покаже подходящи думи. Е, ако забележите внимателно, ще откриете, че те не удрят API при всяко натискане на клавиш, в противен случай това ще намали производителността на уебсайта. Когато дадете пауза от няколко милисекунди, тогава се прави заявката за API. Това намалява броя на заявките, изпратени до API, и повишава производителността, като не бомбардира API с множество заявки. Друг пример може да бъде, ако искате да извлечете някои данни при натискане на бутон. Какво ще стане, ако потребителят е толкова бунтарски и реши да кликне върху бутона няколко пъти отново и отново..?? Ще отговорите ли на всички тези кликвания, за да извлечете данните, които биха направили уебсайта ви бавен..?? Искате да изпратите заявката до API само след определен интервал от време. Кажете след всеки 2 секунди, че ще отговаряте на кликванията. И това премахване на отскок може да се приложи на много места, надявам се, че разбирате същината. Сега нека видим как можем да го приложим с пример.

Сега, нека да разгледаме какво изграждаме, за да разберем премахването на отскок.

Вместо да извличаме някои данни, ние ще прилагаме премахване на отскок при събитие с движение на мишката, за да видим броя на задействанията на събитието като нормална реализация, както и като реализация с дебоункция.

Ще разделим нашата уеб страница на две секции отляво и отдясно. Ако преместим показалеца на мишката в лявата част на екрана, той ще ни покаже броя на събитията, задействани в дясната част.

Горната част на дясната секция ще ни покаже нормалното задействано събитие, а долната част ще ни покаже задействаното отклонено събитие.

В тази статия ще се съсредоточим само върху функцията за премахване на отскок, така че няма да обяснявам стиловете тук. Въпреки че връзката към хранилището на github е спомената по-долу, можете да посетите и проверите кода по всяко време.

Файловете изглеждат така:

HTML

<html>
<head>
<link rel="stylesheet" href="style.css" />
<title>Debouncing</title>
</head>
<body>
<h3>HOVER THE MOUSE IN THE LEFT GRAY AREA</h3>
<div class="container">
<div class="left-side"></div>
<div class="right-side">
<div class="normal"></div>
<div class="debounce"></div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

CSS

* {
padding: 0;
margin: 0;
}
h3 {
text-align: center;
}
.container {
display: flex;
height: 90vh;
width: 100%;
border: 2px solid black;
}
.left-side {
display: flex;
width: 20%;
border: 2px solid black;
cursor: pointer;
background-color: #8888;
}
.right-side {
display: flex;
width: 80%;
border: 2px solid black;
flex-direction: column;
}
.normal {
height: 50%;
border: 1px solid black;
display: flex;
align-items: center;
}
.debounce {
height: 50%;
border: 1px solid black;
display: flex;
align-items: center;
}
.v-line {
border-left: 2px solid red;
height: 100px;
margin-left: 2px;
}
.v2-line {
border-left: 2px solid green;
height: 100px;
margin-left: 2px;
}

Сега нека се съсредоточим върху частта с Javascript.

Нека първо изберем HTML елементите, с които ще работим:

Javascript

const leftSide = document.querySelector(".left-side")
const rightSide = document.querySelector(".right-side")
const normal = document.querySelector(".normal")
const debounce = document.querySelector(".debounce")

Сега нека направим нашите две различни функции, едната за нормално обработване на събития, а другата за обработка на неотклонени събития:

function makeNormalRequest() {
normal.innerHTML += `<div class='v-line'></div>`
}
function makeDebouncedRequest() {
debounce.innerHTML += `<div class='v2-line'></div>`
}

Не се притеснявайте, че и двете функции изглеждат сходни. Все още не сме добавили магията. Тези функции са просто добавяне на вертикална линия в дясната част на екрана въз основа на броя пъти, когато събитието „преместване на мишката“ е задействано.

Сега нека добавим събитие за движение на мишката и за двете функции:

leftSide.addEventListener("mousemove", () => {
   makeNormalRequest()
   makeDebouncedRequest()
})

Горният код просто обвързва „mousemove“ eventListener с елемента leftSide. И сега всеки път, когато показалецът на мишката се премести в секцията от лявата страна, и двете от тези функции „makeNormalRequest()“ и „makeDebouncedRequest()“ ще бъдат задействани.

Към момента, ако се опитаме да преместим показалеца на мишката в лявата секция, ще имаме едни и същи резултати и за двете:

Сега нека поръсим нашата магия за премахване на рикошетите в това приложение.

Ще създадем функция за прилагане на deboucning на функцията „makeDebouncedRequest()“. Ще наречем тази функция „debouncedFunction

Нека видим как изглежда тази функция:

1. const debouncedFunction = (fn, delay) => {
2.   let timer
3.   return () => {
4.    clearTimeout(timer)
5.    timer = setTimeout(() => {
6.      fn()
7.    }, delay)
8.  }
9. }

Тази функция „debouncedFunction“ е просто проста функция от по-висок ред. Функция от по-висок ред е функция, която може да приема функции като параметри или може да връща функция, или може да прави и двете.

Това, което „debouncedFunction“ прави, е просто да вземе функция и забавяне като параметри и да върне „анонимна функция“.

Сега нека се съсредоточим върху анонимната функция, която се връща от „debouncedFunction“. Можем ясно да видим на ред 5, че сме използвали метод setTimeout и вътре в този setTimeout сме извикали нашата функция, която се получава като параметър, след предоставеното забавяне. И сега можем да видим, че сме присвоили този метод setTimeout на променлива с име „timer“. Защо направихме това..?? Направихме това, защото можем да изчистим setTimeout по-късно. И защо трябва да изчистим setTimeout..?? Е, трябва да изчистим setTimeout, защото ако не го направим, няма да намалим тригерите за събития. Тъй като всеки път, когато се направи нова заявка за задействане на събитието, тя ще отиде в опашката и след закъснението всички тези заявки ще бъдат направени и това ще се противопостави на цялата цел на прилагането на debouncing. Ето защо нулираме setTimeout всеки път, когато се направи нова заявка. Сега се надявам, че тази „debouncedFunction“ ще има смисъл.

Сега нека хвърлим нашата магия с една последна магическа линия, за да може всичко да работи:

makeDebouncedRequest = debouncedFunction(makeDebouncedRequest, 300)

Тук, в този ред, ние просто предадохме функцията „makeDebouncedRequest“ и забавяне от 300 ms като параметри на „debouncedFunction“, която ще върне анонимна функция с setTimeout на предоставеното забавяне. И тази анонимна функция се съхранява в променливата „makeDebouncedRequest“. Точно като „функционален израз“. И сега тази променлива „makeDebouncedRequest“ се извиква от eventListener, който сме добавили към елемента leftSide. Нарочно кръстихме променливата на израза на функцията по същия начин като името на функцията, за да можем да я предадем на eventListener без никакви притеснения.

И сега, ако преместим показалеца на мишката в лявата секция, получаваме нещо подобно:

Забележка:

Червената лента представлява нормални тригери за събития, а зелените ленти представляват деактивирани тригери за събития.

Щракнете, за да видите демонстрацията за премахване на отскок

Щракнете, за да посетите хранилището на github