Mirando bajo el capó de Gmail rediseñado

Hace medio año, Google anunció una versión actualizada de la interfaz de Gmail. A pesar de las múltiples quejas de las personas, esta es la interfaz predeterminada ahora.

Entre los otros problemas, las personas notaron problemas de rendimiento con la nueva interfaz, especialmente en máquinas de gama baja. Veamos cómo podría suceder esto y qué puede ser tan pesado en la interfaz web del cliente de correo electrónico. Utilizaremos DevTools de Google Chrome, por lo que este artículo también será un buen recordatorio sobre las funciones que tienen.

Configuración inicial

En primer lugar, veamos el rendimiento de Gmail. Chrome Devtools tiene una herramienta integrada, Lighthouse, que muestra un informe agradable y claro sobre diferentes aspectos de su sitio web, incluido el rendimiento. La puntuación de rendimiento de Gmail es 2 de cada 100:

Para ser sincero, este no es el resultado que podría esperar de un producto de Google. Sin embargo, echemos un vistazo más profundo a esta situación. Después de deshabilitar el caché y volver a cargar la página, en la pestaña Red de herramientas de desarrollo se mostrarán todas las solicitudes que se hayan realizado para cargar esta página. Para mí, fue de 6.9 Mb en total. Esto es mucho, especialmente teniendo en cuenta que Webpack, por ejemplo, le advierte de forma predeterminada cuando el tamaño de sus activos es superior a 244 Kb. Aquí tenemos 27 veces más.

Vale la pena mencionar aquí que los servicios web modernos (incluido Gmail) están utilizando Service Workers para el almacenamiento en caché de activos avanzados. Por lo tanto, para obtener números adecuados para la carga útil de arranque en frío, no solo debe deshabilitar la memoria caché sino también restablecer los Service Workers, que también retiene algunos recursos en caché. Después de eso, sus números mostrarán el tamaño completo de los activos.

Ahora veamos la carga de la página en cámara lenta. Hay una explicación en la documentación de Google Chrome sobre cómo hacerlo. Obtendremos una serie de capturas de pantalla, que muestran la página en diferentes etapas de carga:

Muestra que la página se vuelve más o menos utilizable después de 9 segundos.

Volver a cargar la página con el caché y los Service Workers habilitados muestra una imagen mejor. Solo hay 250 Kb de solicitudes, pero en realidad no hace que la página sea más rápida, todavía tenemos que ver una pantalla de carga durante 9 segundos. Hay algo más que hace que la página se cargue más lentamente, no las compensaciones de la red.

Bloqueando algunos recursos

Si miramos la lista de recursos, habrá muchos de ellos:

¿Quizás algunos de ellos no son realmente necesarios para el trabajo de la página? Intentemos bloquear recursos y veamos cómo afectará esto a la página. Es fácil de hacer con la función integrada de herramientas de desarrollo.

Resultó que las solicitudes a `https: //mail.google.com / _ / scs / *` son cruciales para la interfaz de Gmail, pero algunas otras pueden bloquearse:

  • www.gstatic.com/og/* - Biblioteca de clientes API de Google, para realizar solicitudes a API de diferentes servicios de Google
  • ssl.gstatic.com/inputtools/* - Herramientas de entrada de Google - widget de teclado de pantalla
  • hangouts.google.com: widget de Hangouts incrustado

Después de bloquear estos scripts, la página se carga en 4 segundos, pero las funciones esenciales como leer y escribir correos electrónicos siguen funcionando. Si también experimenta problemas de rendimiento en la interfaz de Gmail, bloquear estas URL podría ser una solución para usted.

Perfilado

En este punto, hemos cortado algunos recursos, pero la página aún se carga lentamente. Deberíamos mirar lo que está sucediendo durante estos 4 segundos. Chrome tiene un generador de perfiles Javascript incorporado, que nos mostrará la siguiente imagen:

Aparentemente, el navegador estaba ocupado ejecutando Javascript durante todo este tiempo. Es interesante observar qué tipo de código es este. Generalmente, Javascript se envía a los clientes en una forma minimizada sin formato y con funciones y nombres variables variables.

Desminificar el código fuente

Tratemos de entender el código minificado. Descargaremos recursos y los pasaremos a través de Prettier, una herramienta de formato de código. Alternativamente, puede usar una función incorporada de Chrome DevTools.

El código se vuelve más legible, pero aún es muy difícil de entender sin nombres originales, qué hacen estas funciones. Afortunadamente, las cadenas se conservan y podemos usar estas pistas para restaurar el código fuente. Hay algunas cadenas como closet_uid_ o type_error: TrustedResourceUrl. Podemos buscarlos en Internet con la esperanza de encontrar un marco de código abierto del que provengan.

La búsqueda nos llevaría a la Biblioteca de cierre de Google. Parece que hemos visto algunas piezas minificadas de este marco. Una comparación adicional revela algunas coincidencias entre el código minimizado y las fuentes de la Biblioteca de cierre:

Dos declaraciones if, una corta y otra larga, luego asignación y finalmente una llamada a función. Este debe ser el mismo código.

Yendo más allá, también encontramos cadenas como GwtExecutor, ListenableFuture, DaggerComponentFactory, que parecen partes de Java-stack, posiblemente compiladas en Javascript. Un proyecto relacionado de la Bandeja de entrada de Google aparece en la página "proyectos usando GWT" y es posible que haya compartido algún código con la interfaz principal de Gmail.

Esta pila de tecnología es muy inesperada. A la luz del hecho de que Google promueve activamente los componentes web y su marco además de eso (Polymer), es muy sorprendente ver en 2018 un rediseño de un proyecto de Google que no los usa.

En cambio, tenemos una pila de tecnología muy antigua con muchos artefactos de los últimos días donde todos los navegadores no seguían los estándares y tenía que escribir un tratamiento especial para cada navegador. Las sobras aún están allí, en la edición 2018 del código de Gmail:

  • AJAX a través de ActiveXObject, un hack para IE6, porque no tenía soporte XMLHttpRequest
  • Los oyentes de eventos a través de attachEvent, eran necesarios para IE8 y posteriores, no tenían el método estándar `addEventListener`.

Este código se incluye en el paquete sin ningún motivo práctico, ya que Gmail solo admite oficialmente IE10 +, no hay consumidores para estos hacks.

Además de la sobrecarga heredada, esta pila tiene un paradigma de componentes obsoletos. Se basa en la jerarquía de clases: un enfoque con una gran cantidad de abstracciones pesadas, que se crean para cada componente que ralentiza significativamente el procesamiento cuando tiene cientos de componentes en una página. Los marcos de interfaz de usuario modernos no hacen largas cadenas de herencia, sus clases son ligeras y el trabajo de renderizado lo realiza el núcleo del marco. Esto reduce una sobrecarga de componentes, por lo que puede tener más componentes sin penalización de rendimiento.

Definitivamente está contribuyendo a la lenta inicialización de la página: hay miles de clases que se instancian durante la carga de la página que ralentiza el procesamiento de la página.

Por lo tanto, a pesar de la apariencia visual actualizada, el código de Gmail lleva el legado de las tecnologías antiguas, el peso no puede ser ocultado por el nuevo caparazón visual.

Verificación de la cobertura del código

Otra característica útil de DevTools es la cobertura del Código. Ayuda a comprender qué partes del código no fueron ejecutadas por el navegador y posiblemente pueden cargarse a pedido.

Aproximadamente la mitad del código no fue utilizado. Puede haber piezas legítimas, como oyentes de eventos y otras operaciones asíncronas. Pero vale la pena revisar las partes no utilizadas de todos modos, podemos encontrar algún código que podría desecharse.

Además de los hacks ya mencionados para versiones anteriores de Internet Explorer, hemos encontrado un par de piezas más interesantes:

Restos de Google Picasa

El servicio se ha cerrado, pero la memoria aún vive en el código GMail.

Teclado de pantalla

Hay un montón de clases responsables de la función, que probablemente no use todos los días, pero se cargan con cada visita a la página de Gmail.

Integración con Google Calendar

Igual que el anterior: es posible que no use Google Calendar, pero se cargará la representación de la reunión agradable.

Conclusión

Esta revisión puede aclarar algunas razones por las que la interfaz de Gmail es lenta. Desafortunadamente, está fuera de nuestras manos hacer que Google mejore el rendimiento de su interfaz. Pero podemos aprender algunas lecciones para nuestras propias aplicaciones web:

  • Google Closure Compiler es muy poderoso. Ese fue un verdadero rompecabezas para restaurar el código fuente, actualmente ofrece la mejor tasa de compresión en comparación con cualquier otro minificador JS.
  • Verifique su proyecto en busca de código no utilizado, por ejemplo, hacks para navegadores antiguos. Revisa tu código y deshazte de las cosas que ya no son reales. Si usa Babel, considere proporcionar la configuración de la lista del navegador para incluir solo las transformaciones que tengan sentido para su público objetivo.
  • Las abstracciones no son gratis. Si desea resolver una tarea utilizando un patrón de programación elegante, primero piense en el costo de la misma. Puede haber una solución más simple disponible.
  • No incluya elementos de página secundarios en la carga útil inicial, utilice la división de código. En el caso de Gmail, el widget Hangouts se está cargando de inmediato, lo que ralentiza los recursos principales. Puede cargarse más tarde, después de la funcionalidad crucial de la página: la lista de correos electrónicos.
  • No descuides las tecnologías modernas. Pueden contener soluciones fundamentalmente diferentes para sus problemas, más eficaces y convenientes.
  • Por último, no olvides prestar atención al rendimiento de tu aplicación. Audítelo de vez en cuando o configure una integración de CI para ello.
Gracias a Oli Steadman por corregir el artículo.