
Nuestra posición como propietarios de un sitio web popular, y nuestro trabajo de apoyo a la popular plataforma React, nos brinda oportunidades únicas y la comprensión de trabajar con el navegador que queremos usar para resolver el problema de la "cola". Como miembro activo de la Comunidad de estándares web (W3C), participamos en una discusión sobre muchas innovaciones, incluidos los trabajadores de servicios y CSS-overscroll , pero hasta hace poco, nunca creamos nuestras propias iniciativas para mejorar el navegador web. Con el fin de lograr un aumento significativo en la productividad, se propuso una nueva API, que, como resultado de la estrecha cooperación con nuestros colegas de Google Chrome, se proporcionó para una versión de prueba . Chrome v74 incluirá la API isInputPending y se puede usar para mejorar tanto el tiempo de ejecución general de JavaScript como el tiempo de respuesta de eventos. Este es solo el primer paso para mejorar la planificación de JavaScript en la web. Esperamos obtener comentarios de los desarrolladores y usarlos para crear la versión final de la API.
Uno de los indicadores de rendimiento más importantes en la web moderna es el tiempo requerido para responder a un evento de usuario (haciendo clic en un botón o entrando en un campo), con su visualización completa. En Facebook, compartimos y medimos eventos en cuatro etapas:
- sistema operativo recibe datos
- inicio real de procesamiento
- comenzar a mostrar cambios en la pantalla en respuesta a un evento
- se completa el procesamiento y se visualiza el resultado
Cuando evaluamos nuestros productos más productivos, se notó que el tiempo de espera en la cola genera los mayores retrasos. Por cola se entiende el tiempo entre el momento en que el usuario interactúa con la página (por ejemplo, hacer clic o tocar) y cuando comienza el procesamiento real del evento. En algunos casos, este retraso puede ser bastante significativo. Imagine que hace clic en el icono de notificación y luego espera un minuto antes de que el botón responda. Probablemente nadie esperará una respuesta.
Arranque rápido o respuesta rápida: elija uno
Existe una difícil compensación entre la carga rápida de páginas y la interactividad. Si un sitio web requiere JavaScript, una opción es ejecutarlo todo en un bloque. Pero esto puede crear problemas. Los mecanismos de JavaScript dentro de los navegadores web generalmente son de un solo subproceso, es decir, solo pueden realizar una operación por página a la vez. En el caso de cargar la página, esto significa que si el usuario hace clic en algo, el navegador debe poner en cola el evento de clic hasta que se inicie todo el bloque de JavaScript.
Al igual que muchos otros sitios, resolvemos este problema dividiendo JavaScript en pequeños bloques. Mientras se carga la página, lanzamos JavaScript y luego devolvemos el control al navegador. Luego, el navegador puede verificar la cola de eventos de entrada y ver si hay algo que manejar. El navegador puede volver a ejecutar bloques JavaScript a medida que se agregan. Esto ayuda, pero puede causar otros problemas. Cada vez que devolvemos el control al navegador, lleva un tiempo comprobar el giro de los eventos de entrada, procesar los eventos y seleccionar el siguiente bloque de JavaScript. Por lo tanto, aunque el navegador responde a los eventos más rápido, aún necesitamos encontrar un equilibrio entre el tamaño de los bloques de código y la frecuencia con la que somos inferiores al navegador. Si cambiamos los controles con demasiada frecuencia, la página se carga demasiado lentamente, si por el contrario, con menos frecuencia, el navegador necesita más tiempo para responder a los eventos de los usuarios y la gente se decepciona.

Si ejecutamos grandes bloques de JavaScript, el navegador puede enviar eventos de usuario con un largo retraso (arriba); Si ejecutamos bloques más pequeños, la página tarda más en cargar (abajo).
Cuando descubrimos retrasos en la cola, recurrimos a nuestros colegas en Chrome. Queríamos ver cómo se vería todo si se nos ocurriera un nuevo enfoque de descarga que eliminaría este dilema de compromiso. Después de hablar con ellos, sugerimos isInputPending. La API isInputPending es la primera en utilizar el concepto de interrupciones para eventos de usuario en la web.
Debajo del capó, isInputPending escucha en la cola de entrada de Chrome en el lado del compilador para detectar eventos antes de que se agreguen a la transmisión principal. Dado que esta escucha se realiza fuera del hilo principal, las llamadas isInputPending no consumen muchos recursos informáticos y deberían ser muy rápidas. Esto permite a los desarrolladores llamar con frecuencia a la API y maximizar la capacidad de respuesta.
Tan pronto como preparamos esta propuesta, recurrimos al Grupo de trabajo de rendimiento web del W3C y recibimos el acuerdo de varios proveedores de navegadores de que vale la pena explorar nuestra idea. En el futuro, colaboramos con nuestros colegas en Chrome, implementamos independientemente una nueva API y enviamos las correcciones de código correspondientes en Chrome. Gracias a los ingenieros de Chrome, obtuvimos parches de prueba que nos permiten probar los cambios y obtener comentarios de los desarrolladores antes de un lanzamiento completo. Esta versión nos permitirá comprender la importancia de esta API para los desarrolladores y determinará nuestras conversaciones futuras sobre esta API con los proveedores de navegadores web. Esta es la primera vez que pasamos por todas las etapas de desarrollo de una API web, desde discutir una propuesta en un foro hasta transferir código a un navegador web.
Como su nombre lo indica, isInputPending le dice si hay eventos en espera de entrada. Los desarrolladores pueden usar esta información mientras ejecutan JavaScript para decidir si quieren recuperar el control del navegador. Usado correctamente, isInputPending puede eliminar por completo el dilema de la carga rápida y la interactividad.
Para trabajar con la API, navigator.scheduling.isInputPending()
. Esencialmente, si el navegador espera que se envíe el evento, este método devuelve true
. Cuando se llama sin ningún argumento, se verifican todos los tipos de eventos compatibles. Además, es posible especificar manualmente una lista de tipos de eventos: mouse, rueda, táctil, que deben verificarse para la entrada pendiente.
Ejemplo: verificar cualquier tipo de evento
while (workQueue.length > 0) { if (navigator.scheduling.isInputPending()) { // break; } let job = workQueue.shift(); job.execute(); }
Ejemplo: comprobación de eventos de entrada específicos
while (workQueue.length > 0) { if (navigator.scheduling.isInputPending(['mousedown', 'mouseup', 'keydown', 'keyup'])) { // 'mousedown' 'mouseup' 'keydown' 'keyup' break; } let job = workQueue.shift(); job.execute(); }
Que sigue
Si los comentarios de la comunidad son positivos, isInputPending puede estar completamente disponible en Chrome. Entonces podemos deshacernos de estos retrasos notables en la cola y hacer que el trabajo en Internet sea más rápido y más flexible para las personas en nuestros sitios. Para los desarrolladores que también quieren deshacerse de los retrasos en la cola y mejorar la interacción y el rendimiento de descarga, pronto estará disponible una versión de prueba. Regístrese aquí y comparta su opinión sobre la versión de prueba tan pronto como esté disponible.
El proceso de portabilidad isInputPending de Chrome es una nueva forma de desarrollar estándares web en Facebook. Esperamos continuar desarrollando nuevas API y aumentar nuestra contribución a los navegadores web de código abierto. En el futuro, podríamos incorporar esta API directamente en React para que los desarrolladores puedan aprovechar la API de forma inmediata. Además, isInputPending ahora es parte del gran trabajo de crear primitivas para la planificación en la web. Esperamos continuar nuestra asociación con Chrome. Al final, esperamos ver las herramientas del navegador que permitirán a los desarrolladores integrarse más profundamente en la cola de tareas del navegador e incluso les permitirán comprender las prioridades del navegador para diversas solicitudes y tareas de la red.
Nota del autor
Para probar la nueva API que necesita: