Aceleración predeterminada del desplazamiento de la rueda

Sahel Sharify
Sahel Sharify

Para mejorar el rendimiento del desplazamiento y el zoom de wheel, se recomienda a los desarrolladores que registren los objetos de escucha de eventos wheel y mousewheel como pasivos pasando la opción {passive: true} a addEventListener(). Si registras los objetos de escucha de eventos como pasivos, se le indicará al navegador que los objetos de escucha de la rueda no llamarán a preventDefault() y que el navegador podrá desplazarse y acercar o alejar la imagen de forma segura sin bloquear a los objetos de escucha.

El problema es que, en la mayoría de los casos, los objetos de escucha de eventos de la rueda son pasivos conceptualmente (no llames a preventDefault()), pero no se especifican de forma explícita como tales, lo que requiere que el navegador espere a que finalice el control del evento de JS antes de comenzar a desplazarse o aplicar zoom, aunque no sea necesario esperar. En Chrome 56, corregimos este problema para touchstart y touchmove. Luego, Safari y Firefox adoptaron ese cambio. Como puedes ver en el video de demostración que hicimos en ese momento, el comportamiento dejó el comportamiento, ya que se produjo un retraso notable en la respuesta al desplazamiento. Ahora, en Chrome 73, aplicamos la misma intervención a los eventos wheel y mousewheel.

La intervención

Nuestro objetivo con este cambio es reducir el tiempo que se tarda en actualizar la pantalla después de que el usuario comienza a desplazarse por la rueda o el panel táctil sin que los desarrolladores necesiten cambiar el código. Nuestras métricas muestran que el 75% de los objetos de escucha de eventos wheel y mousewheel que están registrados en objetivos raíz (ventana, documento o cuerpo) no especifican ningún valor para la opción pasiva y más del 98% de esos objetos de escucha no llaman a preventDefault(). En Chrome 73, cambiaremos los objetos de escucha wheel y mousewheel registrados en los destinos raíz (ventana, documento o cuerpo) para que sean pasivos de forma predeterminada. Significa un objeto de escucha de eventos como el siguiente:

window.addEventListener("wheel", func);

se vuelve equivalente a lo siguiente:

window.addEventListener("wheel", func, {passive: true});

Además, si se llama a preventDefault() dentro del objeto de escucha, se ignorará con la siguiente advertencia de Herramientas para desarrolladores:

[Intervention] Unable to preventDefault inside passive event listener due
to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312

Roturas y orientación

En la gran mayoría de los casos, no se observarán fallas. Solo en casos excepcionales (menos del 0.3% de las páginas según nuestras métricas), es posible que se realicen ajustes o desplazamientos no deseados debido a que se ignora la llamada a preventDefault() dentro de los objetos de escucha que se consideran pasivos de forma predeterminada. Tu aplicación puede determinar si podría tener este impacto en el entorno. Para ello, verifica si la llamada a preventDefault() tuvo algún efecto a través de la propiedad defaultPrevented. La solución para los casos afectados es relativamente fácil: pasa {passive: false} a addEventListener() para anular el comportamiento predeterminado y conservar el objeto de escucha de eventos como bloqueo.