Heim > Web-Frontend > View.js > Wie kann man Shake-and-Drossel-Ereignisse in Vue verhindern?

Wie kann man Shake-and-Drossel-Ereignisse in Vue verhindern?

青灯夜游
Freigeben: 2020-10-13 13:34:01
nach vorne
2570 Leute haben es durchsucht

Wie kann man Shake-and-Drossel-Ereignisse in Vue verhindern?

Einige Browserereignisse können in kurzer Zeit mehrmals schnell ausgelöst werden, z. B. das Ändern der Fenstergröße oder das Herunterscrollen der Seite. Wenn Sie beispielsweise auf Seitenfenster-Scroll-Ereignisse hören und der Benutzer weiterhin schnell auf der Seite nach unten scrollt, kann das Scroll-Ereignis innerhalb von 3 Sekunden tausende Male ausgelöst werden, was zu schwerwiegenden Leistungsproblemen führen kann.

Wenn Sie während eines Interviews über die Erstellung einer Anwendung sprechen und Ereignisse wie Scrollen, Fenstergrößenänderung oder Tastendrücke auftreten, erwähnen Sie unbedingt Entprellen und Funktionsdrosselung, um die Seitengeschwindigkeit und -leistung zu verbessern. Die Essenz dieser beiden Brüder liegt in der Form des Abschlusses. Durch Umschließen der dem Ereignis entsprechenden Rückruffunktion, Zwischenspeichern der Zeitinformationen in Form einer freien Variablen und schließlich Verwenden von setTimeout zum Steuern der Auslösehäufigkeit des Ereignisses.

Throttle: Die erste Person hat das letzte Wort

Die zentrale Idee von Throttle ist: Innerhalb eines bestimmten Zeitraums, egal wie viele Rückrufe Sie auslösen, werde ich nur den ersten erkennen und nach Ablauf des Timers geben eine Antwort.

Lassen Sie mich zunächst eine kleine Geschichte erzählen: Ein Passagier stieg gerade aus dem Flugzeug und brauchte ein Auto, also rief er den einzigen Flughafenbus am Flughafen an, um ihn abzuholen. Der Fahrer fuhr zum Flughafen und dachte, er sei schon gekommen, also solle er noch ein paar Leute mitnehmen, damit sich die Fahrt lohnt – ich warte zehn Minuten und schaue mal. Also schaltete der Fahrer den Timer ein und begrüßte die Gäste hinter ihm, einer nach dem anderen in den Bus einzusteigen. Während dieser zehn Minuten können die Passagiere, die hinten aus dem Flugzeug ausgestiegen sind, nur diesen Bus nehmen. Nach zehn Minuten muss dieser Bus weggeschickt werden, egal wie viele Passagiere hinter dem Flugzeug nicht überfüllt sind.

In dieser Geschichte ist der „Fahrer“ unser Gashebel, der den Zeitpunkt der Abfahrt steuert; der „Passagier“ sind die Rückrufaufgaben, die aufgrund unserer häufigen Betriebsereignisse weiterhin anfallen, und er muss die Vereinbarungen des übernehmen „Fahrer“ und „Timer“ sind die Zeitinformationen, die in Form einer freien Variablen vorliegen. Sie sind die Grundlage für die Entscheidung des „Fahrers“, das Auto endgültig zu starten. entspricht der Ausführung der Callback-Funktion.

Zusammenfassend lässt sich sagen, dass die sogenannte „Drosselung“ dadurch erreicht wird, dass nachfolgende Rückrufanfragen für einen bestimmten Zeitraum ignoriert werden. Solange ein Gast eine Fahrt wünscht, startet der Fahrer einen Timer für ihn. Innerhalb einer bestimmten Zeitspanne müssen sich alle nachfolgenden Gäste, die eine Fahrt benötigen, anstellen, um an dieser Fahrt teilzunehmen, und niemand kann anrufen mehr Fahrten.

Es entspricht der tatsächlichen Interaktion: Immer wenn der Benutzer ein Scroll-Ereignis auslöst, starten wir den Timer für diesen Auslösevorgang. Für einen bestimmten Zeitraum werden alle nachfolgenden Scroll-Ereignisse als „Passagiere in einem Auto“ behandelt – sie können keine neuen Scroll-Rückrufe auslösen. Bis „ein Zeitraum“ erreicht ist, wird der Rückruf ausgeführt, der dem zum ersten Mal ausgelösten Scroll-Ereignis entspricht, und nachfolgende Scroll-Rückrufe, die „innerhalb eines Zeitraums“ ausgelöst werden, werden von der Drosselklappe ignoriert.

Jetzt gemeinsam einen Gashebel umsetzen:

// 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)
Nach dem Login kopieren

Debounce: Der Letzte hat das letzte Wort

Der zentrale Gedanke von Anti-Shake ist: Ich werde bis zum Ende auf dich warten. Innerhalb einer bestimmten Zeitspanne werde ich, egal wie viele Rückrufe Sie auslösen, nur den letzten wiedererkennen.

Erzählen Sie weiter die Geschichte des fahrenden Fahrers. Diesmal war der Fahrer geduldiger. Nachdem der erste Fahrgast in den Bus eingestiegen ist, beginnt der Fahrer mit der Zeitmessung (z. B. zehn Minuten). Wenn innerhalb von zehn Minuten ein anderer Passagier auftaucht, löscht der Fahrer den Timer und wartet weitere zehn Minuten (verzögertes Warten). Solange es keinen solchen Fahrgast gibt und in den nächsten zehn Minuten seit dem Einsteigen keine neuen Fahrgäste in den Bus einsteigen, wird der Fahrer denken, dass niemand diesen Bus wirklich nehmen muss, und wird wegfahren.

Vergleichen wir Throttle, um die Entprellung zu verstehen: In der Throttle-Logik hat „die erste Person das letzte Wort“, es misst nur den ersten Passagier und führt den Rückruf aus, wenn die Zeit abgelaufen ist. Debounce glaubt, dass „die letzte Person das letzte Wort hat“ und Debounce stellt für jeden neuen Passagier einen neuen Timer ein.

Jetzt gemeinsam eine Entprellung implementieren:

// 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)
Nach dem Login kopieren

Verwenden Sie Throttle, um die Entprellung zu optimieren

Das Problem mit der Entprellung ist, dass sie „zu geduldig“ ist. Stellen Sie sich vor, wenn der Benutzer sehr häufig arbeitet, wartet er nicht auf das Ende der durch Entprellen eingestellten Verzögerungszeit, bevor er den nächsten Vorgang ausführt, sodass bei jeder Entprellung der Timer für den Benutzer neu generiert wird und die Rückruffunktion unzählige Male verzögert wird. Häufige Verzögerungen führen dazu, dass Benutzer keine Antwort erhalten und außerdem den Eindruck haben, dass „diese Seite hängen bleibt“.

Um eine Selbstzerstörung zu vermeiden, müssen wir uns die Idee der Drosselung ausleihen, um eine „End-Line“-Entprellung zu erzeugen – Sie können warten, aber ich habe meine Prinzipien: Innerhalb der Verzögerungszeit kann ich den Timer regenerieren für Sie; aber solange die Verzögerungszeit abgelaufen ist, muss ich dem Benutzer eine Antwort geben. Diese „Kombination“-Idee aus Drosselung und Entprellung wurde von vielen ausgereiften Front-End-Bibliotheken auf die Implementierung ihrer erweiterten Drosselungsfunktion angewendet:

// 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(&#39;触发了滚动事件&#39;), 1000)

document.addEventListener(&#39;scroll&#39;, better_scroll)
Nach dem Login kopieren

Verwendung von Entprellung und Drosselung in Lodash in Vue

事件节流和防抖是提高性能或降低网络开销的好方法。虽然 Vue 1曾经支持对事件的节流和防抖,但是在Vue 2中为了保持核心的简单性,删除对事件的节流和防抖的支持。因此,在Vue 2对对事件进行防抖和节流我们可以使用 lodash 来做。

安装

可以通过 yarn 或 npm 安装 lodash。

# Yarn
$ yarn add lodash
# NPM
$ npm install lodash --save
Nach dem Login kopieren
注意:如果我们不想导入lodash的所有内容,而只导入所需的部分,则可以通过一些Webpack构建自定义来解决问题。 还可以使用lodash.throttlelodash.debounce等软件包分别安装和导入lodash的各个部分。

throttling 方法

要对事件进行节流处理方法非常简单,只需将要调用的函数包装在lodash的_.throttle函数中即可。

<template>
  <button @click="throttledMethod()">Click me as fast as you can!</button>
</template>

<script>
import _ from &#39;lodash&#39;

export default {
  methods: {
    throttledMethod: _.throttle(() => {
      console.log(&#39;I get fired every two seconds!&#39;)
    }, 2000)
  }
}
</script>
Nach dem Login kopieren

debouncing 方法

尽管节流在某些情况下很有用,但一般情况我们经常使用的是防抖。 防抖实质上将我们的事件分组在一起,并防止它们被频繁触发。 要在Vue组件中使用节流,只需将要调用的函数包装在lodash的_.debounce函数中。

<template>
  <button @click="throttledMethod()">Click me as fast as you can!</button>
</template>

<script>
import _ from &#39;lodash&#39;

export default {
  methods: {
    throttledMethod: _.debounce(() => {
      console.log(&#39;I only get fired once every two seconds, max!&#39;)
    }, 2000)
  }
}
</script>
Nach dem Login kopieren

参考:

相关推荐:

2020年前端vue面试题大汇总(附答案)

vue教程推荐:2020最新的5个vue.js视频教程精选

更多编程相关知识,请访问:编程入门!!

Das obige ist der detaillierte Inhalt vonWie kann man Shake-and-Drossel-Ereignisse in Vue verhindern?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:segmentfault.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage