Ele.me mejora el rendimiento de los tiempos de carga con una aplicación web progresiva de varias páginas

Ele.me es la empresa más grande de pedidos y entregas de comida en China continental. Atiende a 260 millones de usuarios registrados de más de 200 ciudades de toda China y cuenta con más de 1.3 millones de fichas de restaurantes. Dado que el 99% de sus usuarios piden comida a través de dispositivos móviles, Ele.me se propuso mejorar su experiencia en la Web móvil para que fuera más rápida y confiable con conexiones inestables, todo ello con el uso del modelo técnico central de una app de varias páginas para satisfacer sus necesidades operativas.

  • El tiempo de carga disminuyó un 11.6% en todas las páginas prealmacenadas en caché
  • En promedio, el tiempo de carga disminuyó un 6.35% en todas las páginas.
  • El tiempo de interacción de forma constante se redujo a 4.93 segundos en una red 3G en la primera carga

Después del lanzamiento de la AWP ele.me, los tiempos de carga disminuyeron significativamente, lo que transformó nuestra experiencia web móvil en uno de los sitios de reserva de comida más rápidos de China.

Spencer Yang, gerente de producto de Ele.me AWP

Elegir entre aplicaciones de varias páginas y aplicaciones de una sola página

En una app de varias páginas (MPA), cada ruta a la que navega un usuario activa una solicitud completa de la página, junto con las secuencias de comandos asociadas y los estilos necesarios, al servidor. Esto contrasta con un modelo de app de una sola página (SPA), en el que cada navegación de ruta activa una recuperación solo para el contenido y los datos relevantes para esa ruta, y la IU se construye con un código JavaScript que se ejecuta en la app cliente.

El crecimiento explosivo de Ele.me en los últimos años llevó al crecimiento de distintas unidades de negocios dentro de la empresa, cada una a cargo de ejecutar sus microservicios en el dominio principal https://ele.me. El equipo de Ele.me concluyó que la separación de estos servicios individuales se entrega mejor con un modelo de app de varias páginas (MPA), en el que cada equipo ejecuta y mantiene su propio servicio.

Cómo aplicar PRPL a una MPA

El patrón PRPL (recursos críticos precargar, render ruta inicial, rutas restantes almacenar en caché previamente, rutas restantes de carga diferida) proporciona a los desarrolladores web un conjunto de rieles para guiar la estructura de una AWP, con un énfasis particular en reducir el tiempo de interactividad y maximizar el almacenamiento en caché para reducir las idas y vueltas en la red. Si bien la PRPL se probó bien en las SPA, quedaba menos claro cómo se aplicaría realmente en una MPA. Ele.me decidió adoptar la mentalidad de PRPL cuando pensó en reconstruir su MPA como una AWP. Para ello, se aseguran de que cuando un usuario navegue a una página, esté precargando recursos críticos para esa página incluyendo <link rel="preload"> según sea necesario o mostrando esas secuencias de comandos en un nivel lo suficientemente superficial para que el precargador del navegador pueda hacer su trabajo sin necesidad de sugerencias adicionales. También mejoran progresivamente su AWP mediante la instalación de un service worker cada vez que el navegador lo admite, que luego usan para recuperar y almacenar previamente en caché otras rutas de navegación de nivel superior, de modo que el usuario obtenga una experiencia de carga y renderización más rápida cuando haga clic en la AWP. Cada página de una MPA tiene su propia ruta, por lo que acelerar la renderización de la ruta inicial equivale a implementar prácticas recomendadas para optimizar la ruta de renderización crítica para cada ruta. Con estos cambios, el tiempo de carga general disminuyó en promedio un 6.35% en todas las páginas.

Cómo entregar las pantallas del esqueleto de transición lo antes posible

Ele.me quería aplicar la idea de las pantallas de esqueleto a la UX, que es una forma de garantizar que, cada vez que el usuario presione cualquier botón o vínculo, la página reaccione lo antes posible mediante la transición del usuario a esa página nueva y, luego, cargando el contenido de esa página a medida que el contenido esté disponible. Esta también es la clave para mejorar el rendimiento percibido de la AWP. Sin embargo, como cada página de una MPA tiene su propia ruta inicial, cada navegación requiere rehacer todo el trabajo necesario de carga, análisis y evaluación cada vez.

Para solucionar este problema, Ele.me compiló la pantalla de esqueleto como un componente real de la IU y, luego, usó la pila de renderización del servidor de Vue.js para compilar y, luego, renderizar previamente los componentes de Vue en cadenas antes de insertarlos en las plantillas HTML. Esto les permite renderizar la pantalla de esqueleto directamente y lograr una transición más fluida cuando navegan entre páginas.


Pantalla de esquema durante la transición de página
Pantalla de esqueleto durante la transición de página
Página completamente renderizada después de la transición de página
La página se renderiza por completo después de la transición de la página

Almacena recursos compartidos en caché con un service worker

Las diferentes rutas se cargan a medida que un usuario navega por la AWP, y sería un desperdicio cargar estas rutas desde la red una y otra vez. Para solucionar este problema, Ele.me analizó las rutas críticas que más les interesan a los usuarios, creó un complemento de webhook para recopilar las dependencias de esas rutas críticas y, luego, las guardó previamente en caché cuando se instalaba un service worker en el navegador cliente del usuario. Estas rutas críticas incluyen JavaScript, CSS y las imágenes que forman la shell de IU típica de la AWP.

El service worker almacena en caché de forma incremental las rutas que se consideran importantes, pero no críticas, durante el tiempo de ejecución, a medida que el usuario continúa navegando por la AWP. Esto permite que Ele.me entregue la AWP a los usuarios directamente desde la caché en todas las condiciones de red. Como resultado, el tiempo de carga disminuyó un 11.6% en todas las páginas que se almacenaron en caché previamente.

Lecturas adicionales