[Optimización de eventos desencadenantes de alta frecuencia] Acelerador de paquetes y anti-vibración

Plataforma de gestión digital
Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus
Vue sistema de permisos
dirección de blog personal del caso

Recientemente, el proyecto tiene una función de exportación de datos. Anteriormente, el back-end se procesaba sincrónicamente y el front-end realizaba un procesamiento anti-vibración. Cuando la cantidad de datos es extremadamente grande, el tiempo de respuesta es extremadamente largo. Esta vez, el backend ha sido optimizado y procesado de forma asíncrona. La respuesta es muy rápida, pero se requiere una página de descarga adicional para procesar la exportación. Esto hará que el usuario espere un tiempo para ver el archivo descargado al ingresar directamente a la descarga. página después de la descarga. , y para el back-end, aunque el anti-vibración puede controlar la frecuencia (por defecto 1s), pero quiere controlar el tiempo a unos 10s para realizar la segunda descarga. Si continúa usando anti-vibración, si establece directamente 10, hará que el primer clic no sea válido. Por supuesto, este tiempo se puede controlar dinámicamente a través de una variable, pero es un poco problemático. Así que usé la aceleración para darme cuenta de sus necesidades, lo cual es relativamente simple.

Tanto la función antivibración como la función de estrangulamiento evitan la activación frecuente en un momento determinado, pero los principios entre los dos hermanos son diferentes. Cuál usar depende de la situación real.

[Falló la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de enlace antirrobo, se recomienda guardar la imagen y cargarla directamente (img-g14fT33a-1680157020919)(./%E9%A1%B9%E7%9B %AE%E6%8F% 92%E4%BB%B6.activos/imagen-20230330101259343.png)]

La limitación de funciones y la antivibración de funciones son dos soluciones comunes para desencadenar eventos DOM con frecuencia:

  1. **Idea básica:** Ciertos códigos no se pueden ejecutar de forma continua y repetida sin interrupción.
  2. Motivos de uso : las operaciones DOM requieren más memoria y tiempo de CPU que las interacciones que no son DOM, y probar demasiadas operaciones DOM seguidas puede hacer que el navegador se cuelgue o incluso se bloquee.
  3. **Escenario de la aplicación: **Siempre que el código se ejecute periódicamente, debe limitarse. El mouse mueve el evento mousemove, la barra de desplazamiento desplaza el evento de desplazamiento, la ventana del navegador cambia el evento de cambio de tamaño, etc.
  4. Diagrama lógico de limitación antivibración

[Error en la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de enlace antirrobo, se recomienda guardar la imagen y cargarla directamente (img-z8CbQ2Ae-1680157020920)(./%E9%A1%B9%E7%9B %AE%E6%8F% 92%E4%BB%B6.activos/%E9%98%B2%E6%8A%96%E8%8A%82%E6%B5%81.png)]

5.1 Acelerador

Limitación : dentro del tiempo especificado, solo se activa una vez. Por ejemplo, si establecemos un intervalo de 500ms, dentro de este período de tiempo, no importa cuántas veces se haga clic en el botón, solo se activará una vez.

Ejemplo en la vida : un grifo gotea y puede gotear mucho al mismo tiempo, pero solo queremos que gotee cada 500 ms y mantenga esta frecuencia. Es decir, queremos que la función se llame repetidamente con una frecuencia aceptable.

Escenarios específicos : como 1. En la prisa por comprar productos, dado que innumerables personas hacen clic en el botón rápidamente, si se envía una solicitud cada vez que hacen clic, causará una gran presión en el servidor. 2. La función de exportación de datos, cuando la cantidad de datos es particularmente grande, lleva mucho tiempo procesar el backend para responder a los datos una vez que se hace clic, si se hace clic con frecuencia en el botón de exportación, puede causar que el servidor se bloquee gravemente . Si se limitan los escenarios anteriores, la cantidad de solicitudes se reducirá considerablemente, lo que reducirá la presión sobre el servidor.

Básico : Es para evitar que una función se ejecute con demasiada frecuencia y reducir algunas operaciones demasiado rápidas, similar al tiempo de recuperación de las habilidades en Glory of Kings.

5.1.1 Encapsulación de aceleradores con marcas de tiempo

/**
 * @param {*} fn  需要包装的事件回调
 * @param {*} delay 每次推迟执行的等待时间
 */
export function throttle(fn, delay = 1000) {
  // 距离上一次的执行时间
  let latestTime = 0
  return function () {
    const _this = this
    const _arguments = arguments
    const nowTime = new Date().getTime()
    // 如果距离上次执行超过了,delay才能再次执行
    if (nowTime - latestTime > delay) {
      fn.apply(_this, _arguments)
      latestTime = nowTime
    } else {
      this.$message.warning(`下载频率过高,请${Math.ceil((delay - (nowTime - latestTime)) / 1000)}秒后再次下载!`)
    }
  }
}

La versión de marca de tiempo se ejecutará primero, haga clic una vez para ejecutar inmediatamente. También es el método utilizado para optimizar la función de exportación del proyecto esta vez.

5.1.2 Encapsulando un acelerador con un temporizador

export function throttle(fn, delay = 1000) {
  let timer = null
  return function () {
    const _this = this
    const _arguments = arguments
    if (!timer) {
      timer = setTimeout(function () {
        timer = null;
        fn.apply(_this, _arguments)
      }, delay)
    }
  }
}

La versión del temporizador se ejecutará más tarde y el clic debe esperar a que se ejecute el tiempo de retraso. El anti-vibración que hice antes es así, en el caso de post-ejecución, no es bueno poner el tiempo de espera por mucho tiempo.

5.2 Antivibración (rebote)

Anti-vibración : en operación continua, no importa cuánto tiempo tome, solo si no hay más operación dentro del tiempo especificado después de una determinada operación, este tiempo se considerará válido.

Ejemplo de vida : presione un resorte, continúe presurizando, continúe presionando, solo rebotará en el último momento de soltarlo. Es decir, esperamos que la función solo se llame una vez, incluso si se llama repetidamente antes de eso, solo se llamará una vez al final.

Escenario específico : durante el proceso de ingreso de palabras clave en el cuadro de búsqueda, se solicita al servidor que coincida con los resultados de la búsqueda en tiempo real. Si no se realiza ningún procesamiento, el contenido del cuadro de entrada sigue cambiando, lo que genera el envío de solicitudes todo el tiempo. Si se realiza un procesamiento anti-vibración, el resultado es que después de que ingresamos el contenido, no hay más entradas durante un cierto período de tiempo (como 500 ms) y luego se activa la solicitud.

Núcleo : cuando el mismo evento se activa en un gran número en un corto período de tiempo, la función de devolución de llamada solo se ejecutará una vez. Evite confundir un evento con múltiples.

Función anti-vibración del paquete

/**
 * @param {*} fn  需要包装的事件回调
 * @param {*} delay 每次推迟执行的等待时间
 */
export function debounce(fn, delay = 1000){
  // 定时器
  let timer = null
  // 将debounce处理结果当作函数返回
  return function() {
    // 保留调用时的 this 上下文
    const _this = this
    // 保留调用时传入的参数
    const _arguments = arguments
    // 每次事件被触发时,都去清除之前的旧定时器
    if (timer) {
      clearTimeout(timer)
    }
    // 设立新定时器
    timer = setTimeout(function() {
      fn.apply(_this, _arguments)
    }, delay)
  }
}

5.3 Escenarios de uso común

  • Escuche el desplazamiento, el movimiento del mouse y otros eventos: aceleración (calcule la posición cada segundo)
  • Supervise la operación de cambio de tamaño de la ventana del navegador: antivibración (solo es necesario calcular una vez)
  • Verificación de la entrada de texto del teclado: antivibración (envíe una solicitud de verificación después de ingresar texto continuamente, solo verifique una vez)
  • Enviar formulario - antivibración (múltiples clics se convierten en uno)
  • buscar Buscar Lenovo, cuando el usuario está ingresando valores continuamente, use anti-vibración para ahorrar recursos de solicitud.
  • Inicie sesión, envíe mensajes de texto y otros botones para evitar que los usuarios hagan clic demasiado rápido, de modo que se envíen múltiples solicitudes y se requiera anti-vibración

Aquí, tome el evento de cambio de ventana de cambio de tamaño como ejemplo para demostrar los efectos de aceleración y anti-vibración con código nativo:

Código sin rebote ni limitación

window.onresize = function() {  
  var div = document.getElementById('mydiv')
  div.style.height = div.offsetWidth + 'px'
  console.log('resize')
}

Siga cambiando el tamaño de la ventana y observe los resultados de la impresión. . . .

Evidentemente, si el usuario sigue haciendo zoom dentro y fuera de la ventana del navegador, nuestra función de monitorización se llamará continuamente.Si la función es demasiado "pesada", es decir, como se ha descrito anteriormente, la presión sobre el navegador será muy alta, cuya la alta frecuencia de cambios puede bloquear el navegador.

Procesamiento anti-vibración

function debounce(fn, delay = 1000) {  
    var timer = null;
    return function() {
        if(timer) {
        	clearTimeout(timer)
        }
        var _arguments = arguments
        var _this = this
        timer = setTimeout(function() {
            fn.call(_this, _arguments)
        }, delay)
  }
}

function resizeDiv() {  
    var div = document.getElementById('mydiv')
    div.style.height = div.offsetWidth + 'px'
    console.log('resize');
}

window.onresize = debounce(resizeDiv)

Activar el evento, mirar la comparación entre y, resuelve ese problema, sin embargo,

Solo cambia después de soltarlo, lo que parece un poco abrupto, entonces, ¿se puede sincronizar cuando lo arrastro? ? ?

estrangulamiento

function resizeDiv(){
    var div = document.getElementById('myDiv')
    div.style.height = div.offsetWidth + "px";
}
function throttle(fn, delay = 1000){
    clearTimeout(fn.timer);
    fn.timer = setTimeout(x=>{
        fn.call();
    }, delay)
}
window.onresize = function(){
    throttle(resizeDiv)
}

El control de la frecuencia de procesamiento puede garantizar que el navegador no realice múltiples cálculos en un período de tiempo muy corto. Obviamente, el estrangulamiento de funciones es más adecuado para cambios de alta frecuencia de la ventana que anti-vibración.

Supongo que te gusta

Origin blog.csdn.net/qq_39335404/article/details/129856783
Recomendado
Clasificación