Certains événements du navigateur peuvent être déclenchés plusieurs fois rapidement sur une courte période de temps, comme le redimensionnement d'une fenêtre ou le défilement d'une page. Par exemple, si vous écoutez les événements de défilement de la fenêtre de page et que l'utilisateur continue de faire défiler la page rapidement, l'événement de défilement peut se déclencher des milliers de fois en 3 secondes, ce qui peut entraîner de graves problèmes de performances.
Si vous discutez de la création d'une application lors d'un entretien et que des événements tels que le défilement, le redimensionnement de la fenêtre ou l'appui sur des touches se produisent, assurez-vous de mentionner l'anti-rebond et la limitation des fonctions pour améliorer la vitesse et les performances de la page. L'essence de ces deux frères existe sous forme de clôture. En encapsulant la fonction de rappel correspondant à l'événement, en mettant en cache les informations temporelles sous la forme d'une variable libre, et enfin en utilisant setTimeout pour contrôler la fréquence de déclenchement de l'événement.
Throttle : La première personne a le dernier mot
L'idée centrale de l'accélérateur est la suivante : dans un certain laps de temps, non peu importe le nombre de déclencheurs dont vous disposez. Pour chaque rappel, je ne reconnais que la première fois et je réponds lorsque le délai expire.
Laissez-moi d'abord vous raconter une petite histoire : un passager vient de descendre de l'avion et avait besoin d'une voiture, alors il a appelé le seul bus de l'aéroport pour venir le chercher. Le chauffeur s'est rendu à l'aéroport en pensant qu'il était déjà venu, il devrait donc prendre quelques personnes supplémentaires pour l'accompagner, afin que le voyage en vaille la peine - j'attendrai dix minutes et je verrai. Le chauffeur a donc allumé la minuterie et a invité les invités derrière lui à monter dans le bus les uns après les autres. Pendant ces dix minutes, les passagers qui sont descendus de l'avion par l'arrière ne peuvent prendre ce bus qu'au bout de dix minutes, peu importe le nombre de passagers derrière l'avion qui ne sont pas entassés dans le bus, ce bus doit être renvoyé.
Dans cette histoire, le « conducteur » est notre manette des gaz, qui contrôle le moment du départ ; le « passager » est les tâches de rappel qui continuent d'affluer en raison de nos fréquents événements opérationnels, et il doit accepter le "conducteur" Le "timer" est l'information temporelle qui existe sous la forme d'une variable libre comme nous l'avons mentionné ci-dessus. C'est la base sur laquelle le "conducteur" décide de démarrer la voiture à laquelle correspond la dernière action de "départ". à l'exécution de la fonction de rappel.
Pour résumer, ce qu'on appelle la « limitation » est obtenue en ignorant les demandes de rappel ultérieures pendant un certain temps. Tant qu'un invité appelle pour un trajet, le chauffeur démarre un chronomètre pour lui. Dans un certain laps de temps, tous les invités suivants qui ont besoin d'un trajet devront faire la queue pour monter à bord, et personne ne pourra appeler. plus de manèges.
correspond à l'interaction réelle de la même manière : chaque fois que l'utilisateur déclenche un événement de défilement, nous démarrons le chronomètre pour cette opération de déclenchement. Pendant un certain temps, tous les événements de défilement ultérieurs seront traités comme des « passagers dans une voiture » : ils ne peuvent pas déclencher de nouveaux rappels de défilement. Jusqu'à ce qu'« une période de temps » soit atteinte, le rappel correspondant à l'événement de défilement déclenché pour la première fois sera exécuté, et les rappels de défilement ultérieurs déclenchés « dans un délai de temps » seront ignorés par le papillon des gaz.
Maintenant, implémentez un régulateur ensemble :
// fn是我们需要包装的事件回调, interval是时间间隔的阈值 function throttle(fn, interval) { // last为上一次触发回调的时间 let last = 0 // 将throttle处理结果当作函数返回 return function () { // 保留调用时的this上下文 let context = this // 保留调用时传入的参数 let args = arguments // 记录本次触发回调的时间 let now = +new Date() // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值 if (now - last >= interval) { // 如果时间间隔大于我们设定的时间间隔阈值,则执行回调 last = now; fn.apply(context, args); } } } // 用throttle来包装scroll的回调 const better_scroll = throttle(() => console.log('触发了滚动事件'), 1000)
Anti-rebond : la dernière personne a le dernier mot
L'idée centrale de anti-shake Yu : Je t'attendrai jusqu'au bout. Dans un certain laps de temps, peu importe le nombre de rappels que vous déclenchez, je ne reconnaîtrai que le dernier.
Continuez à raconter l'histoire du conducteur au volant. Cette fois, le chauffeur s'est montré plus patient. Une fois que le premier passager est monté dans le bus, le conducteur commence le chronométrage (disons dix minutes). Dans les dix minutes, si un autre passager arrive, le conducteur effacera le chronomètre et commencera à attendre encore dix minutes (attente différée). Jusqu'à ce qu'il y ait un tel passager et qu'aucun nouveau passager ne monte dans le bus pendant les dix minutes qui suivent sa montée dans le bus, le conducteur pensera que personne n'a vraiment besoin de prendre ce bus et partira.
Comparons l'accélérateur pour comprendre l'anti-rebond : dans la logique de l'accélérateur, "la première personne a le dernier mot", elle chronomètre uniquement le premier passager et exécute le rappel lorsque le temps est écoulé. Debounce estime que « la dernière personne a le dernier mot » et Debounce définira une nouvelle minuterie pour chaque nouveau passager.
Maintenant, implémentez ensemble un anti-rebond :
// fn是我们需要包装的事件回调, delay是每次推迟执行的等待时间 function debounce(fn, delay) { // 定时器 let timer = null // 将debounce处理结果当作函数返回 return function () { // 保留调用时的this上下文 let context = this // 保留调用时传入的参数 let args = arguments // 每次事件被触发时,都去清除之前的旧定时器 if(timer) { clearTimeout(timer) } // 设立新定时器 timer = setTimeout(function () { fn.apply(context, args) }, delay) } } // 用debounce来包装scroll的回调 const better_scroll = debounce(() => console.log('触发了滚动事件'), 1000)
Utilisez Throttle pour optimiser l'anti-rebond
Le problème avec l'anti-rebond est qu'il est "trop compliqué" Soyez patient. Imaginez, si l'utilisateur opère très fréquemment - il n'attend pas la fin du délai défini par l'anti-rebond avant d'effectuer l'opération suivante, donc chaque anti-rebond régénère la minuterie pour l'utilisateur et la fonction de rappel est retardée d'innombrables fois. Des retards fréquents empêcheront les utilisateurs de recevoir une réponse, et les utilisateurs auront également l'impression que « cette page est bloquée ».
Afin d'éviter l'échec, nous devons emprunter l'idée de l'accélérateur pour créer un anti-rebond "en bout de ligne" - vous pouvez attendre, mais j'ai mes principes : dans le délai, je peux régénérez le timing de votre serveur ; mais dès que le délai est écoulé, je dois donner une réponse à l'utilisateur. Cette idée de « combinaison » d'accélérateur et d'anti-rebond a été appliquée par de nombreuses bibliothèques frontales matures à la mise en œuvre de leur fonction d'accélérateur améliorée :
// fn是我们需要包装的事件回调, delay是时间间隔的阈值 function throttle(fn, delay) { // last为上一次触发回调的时间, timer是定时器 let last = 0, timer = null // 将throttle处理结果当作函数返回 return function () { // 保留调用时的this上下文 let context = this // 保留调用时传入的参数 let args = arguments // 记录本次触发回调的时间 let now = +new Date() // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值 if (now - last < delay) { // 如果时间间隔小于我们设定的时间间隔阈值,则为本次触发操作设立一个新的定时器 clearTimeout(timer) timer = setTimeout(function () { last = now fn.apply(context, args) }, delay) } else { // 如果时间间隔超出了我们设定的时间间隔阈值,那就不等了,无论如何要反馈给用户一次响应 last = now fn.apply(context, args) } } } // 用新的throttle包装scroll的回调 const better_scroll = throttle(() => console.log('触发了滚动事件'), 1000) document.addEventListener('scroll', better_scroll)
Utiliser l'anti-rebond et l'anti-rebond dans lodash dans Limitation de vue
事件节流和防抖是提高性能或降低网络开销的好方法。虽然 Vue 1曾经支持对事件的节流和防抖,但是在Vue 2中为了保持核心的简单性,删除对事件的节流和防抖的支持。因此,在Vue 2对对事件进行防抖和节流我们可以使用 lodash
来做。
安装
可以通过 yarn 或 npm 安装 lodash。
# Yarn $ yarn add lodash # NPM $ npm install lodash --save
注意:如果我们不想导入lodash
的所有内容,而只导入所需的部分,则可以通过一些Webpack构建自定义来解决问题。 还可以使用lodash.throttle
和lodash.debounce
等软件包分别安装和导入lodash
的各个部分。
throttling 方法
要对事件进行节流处理方法非常简单,只需将要调用的函数包装在lodash的_.throttle
函数中即可。
<template> <button @click="throttledMethod()">Click me as fast as you can!</button> </template> <script> import _ from 'lodash' export default { methods: { throttledMethod: _.throttle(() => { console.log('I get fired every two seconds!') }, 2000) } } </script>
debouncing 方法
尽管节流在某些情况下很有用,但一般情况我们经常使用的是防抖。 防抖实质上将我们的事件分组在一起,并防止它们被频繁触发。 要在Vue组件中使用节流,只需将要调用的函数包装在lodash的_.debounce
函数中。
<template> <button @click="throttledMethod()">Click me as fast as you can!</button> </template> <script> import _ from 'lodash' export default { methods: { throttledMethod: _.debounce(() => { console.log('I only get fired once every two seconds, max!') }, 2000) } } </script>
参考:
相关推荐:
更多编程相关知识,请访问:编程入门!!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!