Este artículo examina el estado actual del arte en la optimización de la velocidad de la página a través de la tecnología Service Worker. Contiene la esencia de más de 30 años-hombre de investigación que se dedicaron a Speed Kit,un complemento de rendimiento web fácil de usar para acelerar sitios web..

TL;DR

Los usuarios se van cuando la carga de la página tarda demasiado. Pero a pesar de que la velocidad de la página es fundamental para el éxito comercial, las cargas de página lentas siguen siendo comunes en los sitios web modernos. ¿Por qué es eso y qué puedes hacer al respecto?

En la primera parte de este artículo, motivamos nuestra búsqueda de tiempos rápidos de carga de página e identificamos los 3 cuellos de botella principales en el rendimiento web:: frontend, backend y red. Abordando todos estos desafíos, resumimos el actual Las 10 mejores prácticas de rendimiento web para el lado del cliente (frontend), el lado del servidor (backend) y la transferencia de datos (red). Entramos en más detalles sobre el almacenamiento en caché como la solución de referencia para acelerar los activos estáticos y discutimos por qué los datos dinámicos generalmente se consideran no almacenables en caché. Luego desplegamos el diseño del sistema respaldado por la investigación de Baqend que hace almacenamiento en caché de datos dinámicos ffácil a través de un novedoso mecanismo de coherencia de caché basado en filtros Bloom (ver VLDB paper): Baqend combina los beneficios de latencia del almacenamiento en caché HTTP con atomicidad Δ y consistencia de lectura linealizable. Luego entramos en detalles sobre cómo se puede usar el esquema de almacenamiento en caché único de Baqend para acelerar cualquier sitio web a través Speed Kit, un complemento de rendimiento web fácil de usar. Finalmente, le mostramos cómo generar su propio informe de rendimiento para descubrir el potencial para una mayor optimización.

(Para obtener una descripción general estructurada de las preguntas específicas respondidas en este artículo, consulte la tabla de contenidos en el fondo.)

Comencemos con una motivación para optimizar el rendimiento web.

¿Por qué es importante la velocidad de la página?

El 49% de los usuarios espera que los sitios web se carguen en 2 segundos o menos, según un encuesta de Akamai. Pero estas expectativas no se cumplen en la práctica: el sitio web de comercio electrónico promedio de los 500 principales, por ejemplo, tiene un tiempo de carga de página de 9,3 segundos (ver source).

Y aquí están mucho más estudios que relacionan el rendimiento web con el comportamiento del usuario. Por ejemplo, Amazon encontró que 100 ms de tiempo de carga adicional reducen los ingresos por ventas en un 1 %. Con los ingresos actuales de Amazon, el impacto supera los mil millones de dólares al año. De manera similar, Google midió una caída del 20% en el tráfico al comparar las reacciones de los usuarios a 30 resultados de búsqueda en lugar de 10: la disminución en la participación se debió a 500 ms de latencia adicional para la consulta de búsqueda. Al revés, GQ observó un aumento permanente del 80 % en el tráfico después de mejorar el tiempo de carga de la página de 7 a 2 segundos.

Dado que incluso las pequeñas mejoras en la velocidad de la página tienen un tremendo impacto en el éxito comercial, realmente sorprende la cantidad de sitios web que no son rápidos en absoluto. A lo largo del resto de este artículo, cubriremos cómo medir cuándo los sitios web se sienten lentos, discutiremos por qué muchos son lentos y explicaremos qué se puede hacer al respecto.

¿Cuándo se siente rápido un sitio web?

Las medidas típicas de rendimiento web se relacionan con la Tiempo hasta el primer byte (TTFB)DomContentLoaded, u otros aspectos técnicos de la carga de la página. Si bien esas métricas ayudan a los ingenieros a realizar diagnósticos u optimizaciones de bajo nivel, solo corresponden vagamente a la experiencia de los clientes: los usuarios perciben un sitio web como algo lento o rápido, dependiendo de cuándo se muestra el primer contenido relevante. Otro indicador es cuánto tiempo tardan en ingresar datos, hacer clic en la barra de navegación o interactuar con el sitio web de alguna otra manera. Si bien estos aspectos del rendimiento web son fáciles de comprender de forma intuitiva, la velocidad de la página percibida por el usuario no es tan fácil de medir objetivamente.

First Meaningful Paint (La primera pintura significativa) y el Speed Index (índice de velocidad) son medidas de rendimiento que representan la velocidad de página percibida por el usuario (user-perceived page speed).

En la ilustración anterior, puede ver cómo se carga un sitio web en un dispositivo cliente. La línea discontinua indica la integridad visual (eje y) desde una pantalla en blanco (0) hasta la página completamente renderizada (1). El ejemplo también ilustra dos de las medidas más populares para la velocidad de página percibida por el usuario:

  • First Meaningful Paint (FMP): La primera pintura significativa es el momento en el que el usuario ve información importante por primera vez, p. título y texto en un blog o barra de búsqueda y descripción general del producto en una tienda web. En consecuencia, el tiempo hasta el FMP es una medida razonable de si el usuario percibe o no el sitio web como rápido. Suele medirse en segundos o milisegundos. Para que sea objetivamente medible, el FMP generalmente se define como el momento en el que la ventana gráfica experimenta el mayor cambio visual. Para identificar el momento exacto en el que esto ocurre, las herramientas de medición recurren al análisis de vídeo.
  • Speed Index (SI): El índice de velocidad es el tiempo promedio hasta que aparece un elemento visible en la pantalla. Al igual que el tiempo para FMP, el índice de velocidad también se determina a través del análisis de video y también se suele medir en segundos o milisegundos. El índice de velocidad corresponde al área sobre la línea discontinua en la ilustración anterior: un SI pequeño corresponde a un sitio web rápido.

Tanto FMP como SI son ampliamente reconocidos como buenas representaciones numéricas de la velocidad de página percibida por el usuario; esto los distingue de otras medidas que capturan componentes ocultos del proceso de carga como el tiempo hasta el primer byte. Si bien el SI es más detallado en lo que captura, el FMP tiene la ventaja de ser resistente a los valores atípicos, p. anuncios asincrónicos que aparecen después de un tiempo.

¿Qué tan rápido es lo suficientemente rápido?

Como se describió anteriormente, la mayoría de los usuarios esperan tiempos de carga inferiores a dos segundos. Sin embargo,, la ciencia cognitiva sugiere que las personas empiezan a perder la concentración cuando han estado esperando solo un segundo:

Ilya Grigorik, “Redes de navegador de alto rendimiento“ (2013)

que con frecuencia mide los principales dominios de Alexa 1M, muchos sitios web incluso no alcanzan la marca de 10 segundos.

Para cualquier negocio en línea, la velocidad de la página es, por lo tanto, una función decisiva.

Un alto ancho de banda no es suficiente, necesitamos reducir la latencia.

Intuitivamente, una conexión rápida a Internet ya debería garantizar cargas de página rápidas. Sorprendentemente, sin embargo, este no es el caso. Si su sitio web se siente lento con una conexión de 5 Mbps, actualizar a 10 o incluso 100 Mbps no resolverá el problema:

El efecto del ancho de banda frente a la latencia en el tiempo de carga de la página. (source)

Si observa el tiempo de carga de la página con un ancho de banda creciente (barras azules), notará que no hay una mejora más allá de 5 Mbps. Sin embargo, si puede disminuir la latencia de acceso (barras naranjas), verá una disminución proporcional en el tiempo de carga de la página. O dicho de otra manera:

2× Bandwidth ≈ Same Load Time – 2 × Ancho de banda ≈ Mismo tiempo de carga
½ Latency ≈ ½ Load Time – ½ Latencia ≈ ½ Tiempo de carga

A continuación, discutiremos los diferentes cuellos de botella para el rendimiento web para explicar por qué la latencia es el factor clave de rendimiento.

¿Qué hace que los sitios web sean lentos?

Al abrir un sitio web, el navegador envía una solicitud de datos al servidor web. Dependiendo de la distancia entre el cliente y el servidor, el tiempo de ejecución del mensaje por sí solo ya puede causar un retraso significativo. Al recibir la solicitud del cliente, el servidor recopila los datos solicitados (lo que también puede llevar algo de tiempo) y luego los devuelve.

Digamos, por ejemplo, que un usuario de EE. UU. está visitando un sitio web alojado en Europa. Para que el sitio web cargue rápido, se deben resolver los siguientes cuellos de botella:

  1. Representación del lado del cliente (detalles abajo): Incluso cuando los recursos individuales llegan rápido, el navegador aún necesita tiempo para mostrar la página. El tiempo que transcurre hasta que finalmente se muestra el contenido suele estar dominado por las dependencias entre los recursos individuales, ya que pueden bloquear el proceso de representación.
  2. Procesamiento del lado del servidor (detalles abajo): Para ensamblar los datos solicitados, el servidor debe realizar algún trabajo, como representar plantillas HTML o ejecutar consultas de bases de datos; esto requiere tiempo para completarse. Cuando hay muchos usuarios activos al mismo tiempo, el servidor puede estar bajo una gran carga o incluso sobrecargado, lo que provocará un tiempo de espera adicional.
  3. Latencia de red (detalles abajo): Para un sitio web promedio, se deben transferir alrededor de 100 recursos a través de una conexión de red de alta latencia. Por lo tanto, puede tomar un tiempo hasta que el navegador tenga suficientes datos para mostrar algo significativo.

En resumen de la de arriba, Los tres cuellos de botella principales del rendimiento web son (1) el frontend, (2) el backend y (3) la red. En esta parte del artículo, analizaremos más de cerca cada uno de estos tres cuellos de botella y analizaremos las posibles optimizaciones.. Más adelante en este artículo, Describiremos cómo implementamos un complemento de rendimiento, Speed ​​​​Kit , que optimiza estos cuellos de botella automáticamente.

1.) ¿Cómo optimizar el rendimiento de la interfaz?

El principio clave de la optimización de frontend es hacer que la vida del navegador sea lo más fácil posible. Para ello, se deben eliminar los recursos prescindibles y compactar al máximo los restantes. Además, los recursos críticos deben obtenerse no solo lo más rápido posible, sino también en el orden correcto para permitir un procesamiento fluido. Por último, el contenido debe optimizarse para los dispositivos de los clientes antes de enviar los datos a través de la red.

Minimizar el peso de la página

Una de las formas más obvias de acelerar la carga de páginas es reducir la cantidad de bytes que deben transferirse a través de la red. Un buen primer paso es eliminar artefactos no esenciales como HTML no utilizado, comentarios y scripts u hojas de estilo prescindibles. Para que los recursos restantes sean lo más pequeños posible, las herramientas de minificación pueden eliminar aún más los caracteres innecesarios antes de subirlos a producción. Finalmente, la compresión GZip debe estar habilitada para todos los recursos de texto, reduciendo así su tamaño efectivo antes de enviarlos por la red. Asimismo, la compresión de imágenes también puede mejorar la eficiencia del ancho de banda.

Optimice la Ruta de Representación Crítica (CRP)

The critical rendering path (CRP) es la secuencia de acciones que el navegador debe realizar para comenzar a mostrar la página. Para un rendimiento ideal, es obligatorio mantener esta secuencia tan corto como sea posible. Con este fin, los recursos necesarios para mostrar la parte superior de la página (es decir, el área inmediatamente visible) deben minimizarse, por ejemplo, inclinando el CSS crítico. Además, la carga de scripts de forma asíncrona puede reducir en gran medida la cantidad de recursos críticos.

Servir imágenes receptivas

Otra optimización para reducir la cantidad de datos cargados es cambiar el tamaño de las imágenes en el servidor o CDN antes de que se envíen al cliente: en lugar de transferir una imagen de alta resolución que luego se reduce en el navegador de todos modos, cada cliente recibe una imagen que es ya es perfecto en píxeles para las dimensiones de pantalla dadas. Cuando las imágenes están codificadas en WebP o JPEG progresivo, el navegador puede incluso comenzar a mostrarlas antes de que se carguen por completo, lo que reduce aún más el tiempo de espera percibido.

Aproveche el almacenamiento en caché del navegador

The browser cache se encuentra dentro del dispositivo del usuario y, por lo tanto, no solo proporciona un acceso rápido, sino instantáneo, a los datos almacenados en caché. Para limitar la obsolescencia, cada elemento de datos solo se almacena en caché durante un tiempo de vida (TTL) específico, después del cual se elimina implícitamente. Los activos estáticos, como imágenes o secuencias de comandos, se pueden invalidar en el momento de la implementación con los destructores de caché. Sin embargo, solo se aplican a los activos vinculados: el archivo HTML en sí solo se suele almacenar en caché durante un tiempo muy corto para garantizar la actualización (micro-caché, consulte abajo) — lo que requiere frecuentes y lentas revalidaciones. De manera similar, los datos dinámicos (por ejemplo, un carrito de compras o un teletipo de noticias) generalmente no se colocan en la caché del navegador, porque es difícil mantener las copias en caché sincronizadas con los datos base (ver abajo). Mediante el uso Etag & Last-Modified encabezados, es posible evitar recargar recursos vencidos a través de la red cuando aún están actualizados: si la versión en caché y la versión original son idénticas, el servidor solo envía un TTL nuevo (extendido) y omite el recurso en sí.

Para obtener más información sobre el kit de velocidad, consulte a continuación., vea abajo.

Para obtener más información sobre la optimización del lado del cliente, lea nuestro dedicado artículo sobre tecnologías frontend o ver nuestra presentación Code.Talks sobre rendimiento web (video).

2.) ¿Cómo ajustar el rendimiento del backend?

Para tiempos de carga de página ideales, el backend debe producir una respuesta para cada solicitud entrante lo más rápido posible. Sin embargo, la parte aún más difícil es proporcionar estos tiempos de respuesta bajos en presencia de muchos usuarios simultáneos, cortes de red, fallas de máquinas u otros escenarios de error.

Eficiencia de la pila del servidor

El Tiempo hasta el primer byte (TTFB) es el tiempo desde que se envía la primera solicitud hasta que se reciben los primeros datos, medido en el cliente. Representa un límite inferior para (y generalmente se corresponde con) el tiempo de carga de su página: cuanto más pequeño, mejor. En el lado del servidor, se puede facilitar un TTFB mínimo a través de un código eficiente y el procesamiento de solicitudes en paralelo en lugar de secuencialmente. En un backend distribuido, se recomienda además optimizar las llamadas a la base de datos para una latencia baja y minimizar el estado compartido para evitar la coordinación cuando sea posible.

Escalar horizontalmente

Para hacer frente a una gran carga, un sistema debe diseñarse de tal manera que la carga sostenible crezca con la cantidad de máquinas en el clúster. En la práctica, un base de datos fragmentada se usa a menudo en combinación con (en su mayoría) servidores de aplicaciones sin estado. Para asegurarse de que las solicitudes de los clientes se distribuyan de manera uniforme en todas las máquinas, se debe implementar un equilibrio de carga efectivo.

Garantice una alta disponibilidad

Para protegerse contra interrupciones de la máquina o particiones de la red, los datos a menudo se distribuyen a varios lugares. Si bien esto aumenta la disponibilidad, también abre la puerta a posibles incoherencias entre las diferentes copias. Desde el CAP Theorem, sabemos que cada sistema de almacenamiento distribuido está sujeto a una compensación de disponibilidad-consistencia: Bajo ciertas particiones de red, tiene que sacrificar la coherencia (por ejemplo, responder con datos obsoletos) o sacrificar la disponibilidad (por ejemplo, devolver un error). Ante este trasfondo, elegir el sistema correcto para una aplicación dada es muy complejo. En el lado del servidor, las bases de datos se pueden configurar con conmutación automática por error para recuperarse de los errores por su cuenta. En el lado del cliente (o en la CDN), las fallas se pueden compensar u ocultar por otros medios, por ejemplo, sirviendo (posiblemente) contenido obsoleto de cachés cuando el backend no está disponible (obsoleto por error).

Para detalles sobre Speed Kit, vea abajo.

Para obtener más detalles sobre las tecnologías utilizadas en el lado del servidor, consulte nuestros artículos relacionados sobre Tecnología backend como servicio (DBaaS)NoSQL databasesreal-time databases, and procesamiento de flujo distribuido.

3.) How to improve network performance?

With about 100 requests for an average website, networking often becomes a limiting factor for page load times. To reduce networking overhead, it is not only necessary to accelerate every individual access operation, but also to optimize all the protocols that are involved, especially HTTP.

Reducir Latencia

como se argumenta arriba, La latencia es el factor clave para mejorar la velocidad de la página. Para mantenerlo mínimo, los enfoques de vanguardia emplean replicación-geográfica or almacenamiento en caché, por ejemplo a través Redes de entrega de contenido (CDN)). Sin embargo, mantener la coherencia entre las copias almacenadas en caché (coherencia de caché) es fundamental: si no realiza un seguimiento de las copias obsoletas, los usuarios verán contenido obsoleto. Para garantizar datos nuevos para los usuarios, el almacenamiento en caché generalmente se emplea solo para datos estáticos. El esquema de almacenamiento en caché único de Baqend (ver abajo), por el contrario, permite almacenar en caché todo: no solo activos estáticos, sino también resultados de consultas u otra información que cambia de forma impredecible.

Optimice la pila de protocolos

Internet está organizado en capas: Por ejemplo, cuando el tráfico HTTP se envía por cable, las solicitudes individuales se dividen en paquetes TLS cifrados que se dividen en segmentos TCP, cada uno de los cuales corresponde a varios paquetes IP y así sucesivamente. Si bien cada una de estas capas pretende abstraerse de las complejidades de las capas inferiores, comprender cómo funciona cada una de ellas y cómo dependen unas de otras es fundamental para evitar cuellos de botella. Por ejemplo, debe alinear el tamaño del paquete TLS con el TCP ventana de congestión evite problemas de latencia para el tráfico HTTP encriptado y debe usar conexiones TCP persistentes siempre que sea posible para maximizar el ancho de banda (cf. TCP comienzo-lento). TLS también se puede optimizar, por ejemplo, mediante OCSP grapadoreanudación de sesión sin estado, o terminar las conexiones TLS en un nodo CDN cercano en lugar del servidor de origen lejano.

Aproveche HTTP/2

HTTP/2 es el nuevo estándar para la comunicación en la web. Introduce múltiples mejoras de rendimiento significativas sobre su predecesor HTTP/1.1 para aumentar los tiempos de carga. Algunas optimizaciones vienen listas para usar con la nueva versión del protocolo, p.e. multiplexación para aumentar la concurrencia o compresión de encabezado para aprovechar al máximo el ancho de banda disponible. Otras funciones, como la inserción del servidor o la priorización de flujos, requieren cierto esfuerzo por parte del cliente o del servidor. Algunas mejores prácticas de HTTP/1.1 son HTT empuje del servidor o priorización de secuencias requieren un poco de esfuerzo en el lado del cliente o del servidor. Algunas mejores prácticas de HTTP/1.1 son HTTP/2 anti-patterns (video) y, por lo tanto, debe evitarse: la fragmentación del dominio, por ejemplo, fue una forma efectiva de superar la concurrencia limitada de HTTP/1.1 mediante la carga de recursos a través de diferentes conexiones en paralelo. Con la versión HTTP/2, usar una sola conexión es mucho más rápido.

Para obtener más información sobre el ajuste de HTTP/2 y el rendimiento de la red en general, consulte nuestro Artículo de Heise (alemán) o nuestro Tutorial sobre HTTP/2 y redes (150 diapositivas).

En la primera parte de este artículo, descubrimos que la latencia es crítica para cargas rápidas de página. En el segunda parte, luego resumimos las mejores prácticas actuales para evitar cuellos de botella en el frontend, el backend y la red. En esta parte, nos enfocamos en el almacenamiento en caché como el mecanismo fundamental para reducir la latencia y explicamos cómo el esquema de almacenamiento en caché único de Baqend permite almacenar en caché datos dinámicos con sólidas garantías de consistencia.

¿Cómo el almacenamiento en caché web hace que los sitios web sean rápidos?

Even if you bring down processing time to almost 0 in both backend and frontend, network latency can still be prohibitive for fast page loads. Caching is the only way to effectively reduce the distance between clients and the data they need to access.

Caching brings data closer to the clients

In traditional web caching, copies of requested data items are stored in different places all over the world, for example in the clients’ devices (browser cache) or a globally distributed Content Delivery Network (CDN). Thus, a client request does not have to travel all the way to the original web server, but instead only to the nearest cache.

Accessing data from nearby caches instead of the original web server has two immediate benefits:

  • Low Latency: Since every request can be answered by a nearby web cache (e.g. your browser cache or a CDN edge node), the client does not have to wait as long for responses.
  • Less Processing: Since requests are only forwarded to the web server on cache misses (i.e. when the data is not available in the CDN node), load on the original web server is effectively reduced.

Challenge: dealing with staleness

The problem with caching is that you have to keep your copy in-sync with the original data: Whenever the base data changes, the corresponding caches have to be invalidated (i.e. cleared or marked as outdated) — or else users will see stale data. To bound the possible staleness, all cached resources expire after a certain amount of time and are then implicitly invalidated. This timeframe is called the Time To Live (TTL) in the HTTP standard. Since static resources change infrequently or not at all, they are typically cached with long TTLs.

Dynamic data: playing hard to cache

For dynamic data such as user comments, product recommendations, social feeds, or database queries, however, long TTLs correspond to a high probability of data staleness. Therefore, it is considered state of the art to either assign small TTLs (micro-caching, see below) for dynamic data or to not cache dynamic data at all.

How to cache dynamic content without staleness?

Traditional web caching brings data closer to the clients, but only works for static resources. Baqend is unique through its ability to cache anything — even dynamic data such as user profiles, counters, or database query results. The concrete algorithms behind this are not our secret sauce, but they are all published research. Here is the simple idea: First, we monitor all updates and invalidate stale caches where possible (e.g. in the CDN) — both in realtime. Second, we tell our clients which caches have become stale, so that they can avoid stale caches that our servers cannot invalidate (e.g. the browser caches in the clients’ devices).

Detect stale data in the backend

To make this possible, Baqend keeps track of every issued response and invalidates the corresponding caches upon change. In more detail, we continuously monitor all cached resources and remove them from the caches whenever they are updated. For invalidation-based caches (e.g. CDNs like Akamai or Fastly), this is no problem as they provide an interface to remove specific data items from the cache.

Bypass stale data in the client

The situation is more involved for expiration-based caches (e.g. the browser cache), because they keep data until the respective TTL expires: Data items cannot be removed. To invalidate changed information regardless, we therefore use a trick: We let the client know which currently cached resources have become stale and only let it use the fresh ones. This information is transmitted initially on connection, in fixed periods, and on-demand when staleness needs to be avoided for the next read operation.

Freshness guaranteed

Since the full list of stale URLs can get prohibitively long, we use a compressed representation based on Bloom filters. An entry in the Bloom filter indicates that the content was changed in the near past and that the content might be stale. In such cases, the client bypasses all expiration-based caches and fetches the content from the nearest CDN edge server — since our CDN (Fastly) is invalidation-based (and specialized in fast invalidations through bimodal multicast), the client knows it only contains fresh data. When the Bloom filter does not contain a specific resource, on the other hand, the browser cache is guaranteed to be up-to-date and can be used safely.

Zero-latency loads

By using the Bloom filter to control freshness, data can be taken from any expiration-based cache, without sacrificing consistency. The most significant performance boost comes from using the browser cache: It is located within the user’s device and therefore does not only provide fast, but instantaneous access to cached data. Using the browser cache further saves traffic and bandwidth, since data is immediately available and does not have to go over the network.

Example

Let’s illustrate this scheme with a concrete example:

With Baqend, users only see fresh data: Using a Bloom filter of changed resources, clients avoid stale caches.

The above animation shows Baqend caching in action where two clients respectively read and write the same user comment:

  1. Initial read: The reading client (left) loads a website that contains a user comment. When the read is completed, the user comment is cached in the accessed CDN edge node as well as the reading client’s browser cache.
  2. Update: The user comment is updated by the author. On receiving the write operation, the Baqend server implicitly updates the Bloom filter to reflect that the user comment has been changed.
  3. CDN invalidation: While the CDN is automatically invalidated by the server, the browser cache on the client’s device still contains the outdated version of the user comment.
  4. Refresh Bloom filter: The client loads a new Bloom filter from the server; the new Bloom filter reflects the updated comment. This happens upon page load as well as in configurable intervals.
  5. Check Bloom filter: The user refreshes the website. Before loading the user comment from the browser cache, though, the browser checks whether the version in the browser cache is still up-to-date: It is not!
  6. Bypass browser cache: Since the Bloom filter contains the user comment, the browser knows that the locally available version is outdated. Instead of using the browser cache, it therefore accesses the nearest CDN node and receives the current version (HTTP revalidation request).

Using the Bloom filter for staleness checks effectively solves the cache coherence problem for web caching: Since the client can check whether a given cache is up-to-date, there is no risk of seeing stale data. As a result, reads are blazingly fast and consistent at the same time. To learn about the nitty-gritty details of this appraoch, check out our Cache Sketch research paper.

What consistency guarantees does Baqend provide?

With traditional web caching, maximum staleness depends on the specified TTL, because the the browser cache and other purely expiration-based caches will serve any data item until it expires. With Baqend’s caching scheme, in contrast, clients will never see data that is older than the Bloom filter they use for the staleness check. As illustrated below, expiration-based caches (left side) are invalidated through the Bloom filter, while the invalidation-based caches (right side) are actively kept up-to-date by the backend.

To accelerate get requests, Baqend uses all benefits of the HTTP caching hierarchy, but adds rigorous consistency guarantees.

Δ-Atomicity

With Baqend, staleness is not only limited by the TTL, but by the interval in which the Bloom filter is refreshed. All the client has to do is make sure that the Bloom filter is never older than the tolerable staleness. For example, in order to avoid staleness over 30 seconds, it is enough to refresh the Bloom filter roughly twice a minute — even if some TTLs are as long as 30 days. In the distributed systems community, this is called Δ-atomicity.

Linearizability

By frequently refreshing the Bloom filter, the client can minimize staleness. However, it can also perform every operation as a revalidation request against the original backend to enforce strong consistency: By bypassing all caches, the client thus eliminates all sources of data staleness apart from message runtime itself.

What optimizations does Baqend apply besides caching?

We have seen that caching optimizes latency of HTTP requests by putting copies of the data near the client. But as mentioned earlier, there are many more network-level optimizations beyond the mere proximity benefit of caching.

Protocol Stack Optimization

Baqend implements several network-related optimizations that clients implicitly use.

As one of the most significant features, each of Baqend’s CDN nodes maintains a pool of persistent TLS connections to our backend, so that a client only has to establish a TLS connection with the nearest CDN edge node. Since the initial TLS handshake takes at least two roundtrips, establishing a secure connection with a CDN node in close proximity can thus provide a substantial latency benefit over going all the way to the original web server. By employing OCSP stapling, stateless session resumption, dynamic record sizing, and several TCP tweaks, Baqend ensures that the handshake takes at most two round-trips to the nearest CDN node.

HTTP/2

Another important optimization that Baqend uses by default is HTTP/2. For a typical website and in particular combined with caching, H2 can improve performance drastically as shown below:

Loading a German website from Canada: Baqend caching (bottom) vs. standard hosting (top). (details)

Baqend (bottom) is not only faster than an uncached hosting solution (top). Perhaps more surprisingly, the TLS-secured Baqend website (bottom right) is faster than the non-TLS version (left). But even beyond TLS optimization, HTTP/2 introduces three significant improvements over HTTP/1.1:

  • Multiplexing requests over TCP avoids head-of-line blocking.
  • Server Push allows you to send data before the user requests it.
  • Header Compression saves bandwidth, e.g. for repeatedly sent cookies.

And there is a lot more that Baqend optimizes with respect to the basic web protocols involved in loading a page (DNS, IP, TCP, TLS, HTTP). For details, check out our HTTP/2 & Networking tutorial (150 slides) which contains the gist of what we learned from building Baqend.

Image Optimization

Baqend is not only able to minimize latency and fine-tune network communication, but can also optimize the content itself for you:

Most notably, Baqend can transcode images to the most efficient formats (WebP and Progressive JPEG) and even rescale them to fit the requesting client’s screen: To minimize page size, a user with a high-resolution display will receive high-resolution images, while a users with an old mobile phone will receive a smaller version that is natively scaled to the smaller screen dimensions. For text-based content, Speed Kit similarly ensures that GZip compression is correctly applied to resources. While imperceptible for the user, these optimizations lead to significant load time improvements, especially when bandwidth is limited (e.g. on mobile connections).

Summary

In a nutshell, Baqend applies state-of-the-art optimizations transparently for all clients:

Most importantly, Baqend reduces latency by caching not only static resources, but caching everything. Further, Baqend performs transparent network optimizations to enable latencies near the physical optimum.

Next, we are going to discuss how modern browser standards can be leveraged to apply the above technology to any existing website.

So far in this article, we have established the importance of faster page loads (see part I), discussed state-of-the-art performance best practices (see part II), and described how Baqend provides many optimizations out-of-the-box and adds dynamic data caching on top (see part III). Next, we describe how Baqend’s unique benefits can be made available to any website using Baqend’s performance plugin: Speed Kit. To find out how fast your website currently is and by how much Speed Kit would improve it, skip ahead to the final part of this article.

How can Speed Kit accelerate your existing website?

To boost content delivery, Speed Kit intercepts requests made by the browser and reroutes them: Instead of loading content from the original domain, Speed Kit delivers data from Baqend.

To activate Speed Kit, you simply include a code snippet into your website which we generate for you. Whenever a user is visiting your website, the snippet then installs (i.e. launches) the Speed Kit Service Worker, a process running concurrently to the main thread in the browser. As soon as the Service Worker is active, all HTTP requests matching your speedup policies (see next paragraph) are rerouted to Baqend. If we have a cached copy of the requested resource (Media, text, etc.), it is served superfast; if the resource is requested for the very first time from our caches, it is served as fast as the origin allows — but will be cached from there on.

To learn more about how Service Workers revolutionize browser performance, check out our talk on Service Workers and web performance.

Opt-in acceleration: You define what will be cached

Many resources are easily cacheable through Speed Kit (e.g. images, stylesheets, etc.), while some are not (e.g. ads). Through, speedup policies you can define regex expressions as well as domain whitelists and blacklists to tell Speed Kit exactly which request should be accelerated and which ones should be left untouched: Speed Kit will not interfere with a request, unless explicitly configured to.

End-to-end example: a page load with Speed Kit

Here is what happens in detail, when a user visits a Speed Kit page:

  1. Compatibility check: The Speed Kit JavaScript snippet is executed and checks whether Service Workers are available in the browser. If not, the page is simply loaded without Speed Kit.
  2. Service Worker initialization: If the user visits the website for the first time, the browser starts loading the page like normal and initializes the Service Worker in the background. Speed Kit then becomes active during the load and starts serving requests from this point on. Initialization is required only on first load: For returning visitors where Speed Kit’s Service Worker is already installed, Speed Kit will serve every request right away — starting with the HTML itself.
  3. Request interception: Any request issued by the browser is automatically proxied through the Service Worker.
    (a) Normal operation: By checking your configuration, Speed Kit determines whether it should accelerate the request or simply forward it to the browser’s network stack.
    (b) Offline mode: If there is no network connection, Speed Kit serves everything from the cache.
  4. Bloom filter lookup: For handled requests, Speed Kit consults the Bloom filter to confirm freshness of the local Service Worker cache. (Exception: In offline mode, the local cache is used regardless, because no other option is available.)
  5. Accelerated response: If the Bloom filter lookup reveals that a given requested resource is fresh, the response is served from the nearest cache:
    (a) Local cache: If the requested response is fresh according to the Bloom filter and also available in the local cache, Speed Kit returns the cached copy instantaneously.
    (b) CDN cache: Upon a local cache miss (or when the Bloom filter returned the resource as stale), Speed Kit issues the request over the HTTP/2 connection to Baqend’s CDN.
    (c) Original server: If there is a cache miss in the CDN, the response is fetched from Baqend’s servers or — if it is not available there — ultimately from the original server. In the process, the metadata (URL, content type, etc.) are stored in Baqend to allow sophisticated query-based refreshing of cached data in the future.

Makes any website a Progressive Web App (PWA)

With Speed Kit, your website becomes a full-fledged Progressive Web App. Users will not only experience faster page loads through Speed Kit’s request acceleration, but also less downtime through the built-in offline mode:

In offline mode, Speed Kit displays cached content instead of showing an error message. For a Speed Kit user, the website thus appears to be blazingly fast, when a traditional website would not even be usable. In addition, mobile users can add any Speed Kit website to their homescreens, just like native mobile apps. Through web push (coming soon), Speed Kit further allows sending push notifications from the server to your users.

No vendor lock-in

Since Speed Kit is an opt-in solution, you can also opt-out any time. If you are not satisfied with Speed Kit’s performance boost, just click the button — really, there’s a button — and your website will be back to the old default instantaneously.

How does Speed Kit avoid stale content?

To make sure that data is always up-to-date, Speed Kit’s caches have to be refreshed whenever your content changes. Speed Kit does this periodically by default, but we also provide a convenient refresh API that allows you to update all caches on-demand in realtime (including the browser cache within the user’s device).

Speed Kit automatically synchronizes all caches with your original website.

In more detail, cache synchronization (refresh) can be done both in two different ways:

  • Realtime: By programmatically calling an API hook or by manually clicking a button in the Speed Kit dashboard, you can trigger immediate synchronization. Thus, you can make sure that changes in your original content are immediately reflected Speed Kit’s cached copy.
  • Periodic: But even without any action on your part, Speed Kit automatically synchronizes itself in regular intervals (see illustration above for default values).

Through its refresh mechanisms, Speed Kit stays always up-to-date and in-synch with your website. Both refresh mechanisms work on simple URLs as well as complex query conditions (e.g. all URLs matching a specific regex expression and having content type “script”). This radically simplifies staying in-sync, because your application logic does not need to identify the exact place where the change occurred — Speed Kit can figure it out. Also, invalidations never happen unccessariliy: Caches are only purged, if the content actually changed according to byte-by-byte comparison in Baqend.

How does Speed Kit accelerate personalized content?

Some pages generate personalized or segmented content into their HTML pages, for example shopping carts, custom ads, or personal user greetings. Normally, there is no point in caching those HTML pages, since they are essentially unique for every user. With Speed Kit, however, there is a way to do exactly that through the concept of Dynamic Blocks:

Dynamic Blocks accelerate your website by loading a generic version first and filling in personalized infos later.

The basic idea is to load and display personalized content in two steps:

  1. Load generic page: The initial request for an anonymous version of the page (e.g. with an empty shopping cart) can be accelerated with Speed Kit, because it is the same for all users.
  2. Inject personalized data: The user-specific data is loaded concurrently to the generic version from the original backend. As soon as it arrives, the personalized content replaces the generic placeholder.

With this approach, the browser can fetch linked assets much faster and can thus start rendering early, even before the personalized content is available. Thus, Dynamic Blocks mitigate the problems caused by a backend with high TTFB. All this requires from you as a developer is to identify dynamic blocks through a query selector.

With Dynamic Blocks, your website essentially behaves as though the personalized information (e.g. a shopping cart) was loaded through Ajax requests. Accordingly, you typically do not need Dynamic Blocks, when you are building a single-page app (e.g. based on React or Angular): You simply blacklist the personalized Ajax/REST API requests.

How does Speed Kit accelerate third-party content?

In practice, page load time is often governed by third-party dependencies. Typical examples are social media integrations (e.g. Facebook), tracking providers (e.g. Google Analytics), JavaScript library CDNs (e.g. CDN.js),
image hosters (e.g. eBay product images), service APIs (e.g. Google Maps),
and Ad Networks.

For example: Google analytics

The problem is that each external domain introduces its own handshakes at TCP and TLS level and therefore experiences an initially low-bandwidth connection (TCP slow start). All performance best practices fail, because third-party domains are out of control for the site owner. Even Google’s own recommendation tool (PageSpeed Insights) warns that its own tracking mechanism (Google Analytics) slows down websites: The provided TTL of 2 hours is simply ineffective. The only option left is to copy external resources — e.g. the Google Analytics script — to your own server. But while this may indeed be faster, it also makes things inconsistent and frequently breaks the scripts. In consequence, web developers have come to accept potentially slow dependencies as an inevitable fact.

Caching the uncacheable

Using the new Service Worker standard, Speed Kit does what was impossible until lately: Speed Kit is able to rewrite requests to slow third-party domains within the client, so that they are fetched through the established and fast HTTP/2 connection to Baqend.

Speed Kit is able to consistently cache third-party dependencies and deliver them over a warm and fast HTTP/2 connection.

This does not only save networking overhead by eliminating third-party connections, but allows applying the same caching mechanisms to all external resources. As the cached resources are also kept up-to-date by Speed Kit’s refresh mechanism, this optimization comes with no additional staleness.

Transparent content optimization

As a bonus, the accelerated third-party content itself is also optimized. If you run a price comparison search engine, for example, Speed Kit can cache the images from Amazon’s image API and transparently compress and resize them to fit your page layout the individual users’ screen sizes. This feature also comes out-of-the-box and without any configuration or integration overhead for the site owner.

What distinguishes Speed Kit from CDNs, micro-caching, AMP etc.?

Speed Kit has some similarities to other approaches for tackling web performance, but provides many benefits on top.

Speed Kit vs. CDN

Unlike content delivery networks like Akamai, Fastly, or CloudFlare, Speed Kit caches dynamic data and therefore accelerates content that is simply untouchable for all other caching solutions.

Speed Kit vs. CDN.

Similarly, Speed Kit is also accelerating third-party dependencies which are out of reach for state-of-the-art CDN caching. At the same time, integration is much simpler with Speed Kit, since it relies on a script instead of taking over your DNS. You also don’t need to code countless invalidation hooks into your backend code, because Speed Kit’s periodic refreshes handle cache invalidation automatically. With GDPR around the corner, Speed Kit has another great advanatage over CDNs: It does not see any personally identifiable information like cookies from your users. Therefore, you can add Speed Kit without violating GDPR compliance.

Speed Kit vs. Micro-Caching

Many web architectures employ micro-caching to increase scalability, for example by putting a cache server like Varnish in front of the actual web server. By design, though, micro-caching uses short TTLs in order to avoid staleness. But by using short TTLs, micro-caching also provokes frequent cache misses and thus slow responses for users:

While short TTLs in micro-caching cause frequent cache misses, Speed Kit separates cache lifetime from staleness bounds through periodic cache refreshes.

In contrast, Speed Kit uses longer TTLs, because the TTL does not determine worst-case staleness: When a 5-minute refresh interval is scheduled, for instance, Speed Kit makes sure that no cached item is older than 5 minutes. If the resource changes, Speed Kit will discover and invalidate the change through the periodic refresh. On the other hand, if no change is detected during refresh, the data item will remain in the cache until expiration — which might be 5 minutes, 5 hours, or 5 days. Internally, Speed Kit learns with your workload: Through time series prediction, the delivered TTLs will get closer to real inter-update times, the longer your application runs.

Speed Kit vs. AMP & Instant Articles

Google’s Accelerated Mobile Pages (AMP) and Facebook’s Instant Articles (IA) can be used to create fast websites. However, AMP and IA don’t accelerate your existing website like Speed Kit does. Instead, Google and Facebook force you to rebuild your page on their platforms, using only those features that cannot hurt web performance.
For example, AMP enforces the following limitations on your website:

  • Restricted HTML: You can only use a stripped-down version of HTML.
  • Restricted JavaScript: No custom JavaScript allowed (except in iframes).
  • Restricted CSS: All stylings must be inlined and below 50 KB overall.
  • No repaints: You can’t resize DOM elements (only static sizes allowed).
  • No desktop: Your website is only available to mobile users.
  • Google styling: Your website has to include a Google bar at the top.
  • Stale-while-revalidate: Users may see outdated content.

As a second reason why AMP pages feel fast, Google uses a trick that has nothing to do with the technology itself: Whenever you look at a Google result on your mobile device, the browser is already fetching the AMP pages featured at the top. Since they are loaded regardless of whether you click the link, AMP pages can be rendered instantly. However, this only works when the user is visiting through a Google search result. For a normal page load, AMP is relatively slow.

Instant Articles are technically similar to Google’s AMP. One of the most significant distinctions, however, is that Facebook’s approach is even more restrictive: Instant Articles are Facebook-only. Since they are only accessible for Facebook users, Instant Articles cannot be used to create public websites.

Through their featured positions, both AMP and IA appear to be attractive for publishing. It should be noted, however, that both are designed to boost their respective ecosystems — not your business: While you are still creating the content, users don’t recognize your brand as they get their news “on Google” or “from Facebook”. In consequence, your leads may drop, you lose traffic, you cannot create rich user experiences, and you may even hurt your e-commerce sales performance.

In contrast to AMP and IA, Speed Kit works for your existing website and has no limitations regarding what HTML, CSS, or JavaScript constructs are permitted. Speed Kit is compatible with any frontend framework and web server, working for both mobile and desktop users. Also, Speed Kit websites are never stale, since caches are refreshed in realtime — thus, you don’t have to wait for Google’s or Facebook’s CDN to reflect changes in your website. As the most important advantage, though, Speed Kit is simply faster than AMP.

At Baqend, we think that web performance should be brought forward through technological advance, be it with Speed Kit or simply through solid web engineering. To learn how you can achieve the benefits of AMP and IA without locking yourself into Google’s and Facebook’s ecosystem, watch our Code.Talks presentation on web performance (video).

Summary

In summary, we built Speed Kit to provide the following features:

In this final part of our article, we show how you can benchmark and optimize your own website with minimal time and effort.

How fast is your website?

To produce detailed performance reports and sophisticated optimization hints, we have developed our own performance measurement tool based on the open-source tool WebPagetest: Baqend’s Page Speed Analyzer measures your web performance and gives you suggestions where there is room for improvement.

The analyzer shows you how fast your website currently is (left) and how much faster it could become (right). (example)

The Page Speed analyzer compares your current website (left) against the same website accelerated by Speed Kit (right). To this end, the analyzer runs a series of tests against your page and the accelerated version; finally, it gives you a detailed performance report of your current website and a measurement of the performance edge provided during our test with Speed Kit.

The analyzer provides you with waterfall diagrams and details on connections and requests made during page load. (original page vs. Speed Kit)

To produce objective results, the analyzer uses Puppeteer and several instances of WebPagetest, an open-source tool for measuring web performance. By using an actual browser (Chrome) to load the page under test, WebPagetest generates realistic test results. In our analyzer, you can specify from where the test should be executed (EU vs. US) and which version of your site should be loaded (mobile vs. desktop). To provide you with the maximum level of details regarding your website’s performance, our analyzer also makes the waterfall diagrams available that are generated by WebPagetest.

Quantifiable Metrics

Among others, the Page Speed Analyzer collects the following metrics:

  • Speed Index & First Meaningful Paint: Represent how quickly the page rendered the user-visible content (see above).
  • Domains: Number of unique hosts referenced.
  • Resources: Number of HTTP resources loaded.
  • Response Size: Number of compressed response bytes for resources.
  • Time To First Byte (TTFB): Represents the time between connecting to the server and receiving the first content.
  • DOMContentLoaded: Represents the time after which the initial HTML document has been completely loaded and parsed, without waiting for external resources.
  • FullyLoaded: Represents the time until all resources are loaded, including activity triggered by JavaScript. (Measures the time until which there was 2 seconds of no network activity after Document Complete.)
  • Last Visual Change: Represents the time after which the final website is visible (no change thereafter).
Measure how fast your website is.

Video

In addition to the metrics listed above, the Page Speed Analyzer takes a performance video of both website versions to visualize the rendering process. Through this side-by-side comparison, you can literally see the effect that Speed Kit has.

Continuous Monitoring

If you are using Speed Kit already, the analyzer shows you what Speed Kit is currently doing for your performance: On the left, you see how your website would perform after removing Speed Kit; on the right, you see a test of your current website. The analyzer will also give you hints, if your Speed Kit configuration can be tuned or when you missed a setting. Thus, you can use the analyzer to validate Speed Kit’s worth to your online business. But you can also try out new configurations to improve your existing Speed Kit configuration.

What systems are supported?

Speed Kit works for any site — and it is easy to integrate into your current tech stack! The generic approach for custom websites is described in the next section.

For additional comfort, there are also native plugins for different content management and web hosting platforms. You can activate Speed Kit for your WordPress website within minutes by using our WordPress plugin. For web hosters, we recommend our Plesk plugin which is available for Plesk 17.5.3 and higher versions.

How to activate Speed Kit for your website?

For Plesk and WordPress websites, we recommend the native plugins. However, Speed Kit is also easy-to-use for custom websites.

To let you try out Speed Kit in production without any costs at all, Speed Kit provides an extensive free tier. To activate Speed Kit for your website, follow these steps:

  1. Register a Speed Kit app: Create a Baqend account and choose app type Speed Kit.
  2. Follow the instructions: You will be guided through the installation process by our setup Wizard. In essence, you will do the following:
    (a) Specify the domain to accelerate.
    (b) Include a code snippet into your website (we will generate it for you).
    (c) Adjust refresh policies to make sure our caching infrastructure is always synchronized with your original content.
    (d) Optionally: Confine Speed Kit to parts of you website (e.g. “/blog”) to try it in a limited scope first.

Questions? If you require help or have a question, simply drop us a line via Gitter or email!

Table of Contents

This article provides an overview over the current state of the art in research and practice of web performance. In particular, it answers the following questions:

Part I: Web Performance Bottlenecks

Part II: Web Performance Best Practices

Part III: Baqend — Caching Dynamic Data

Part IV: Speed Kit — Accelerating Any Website

Part V: Measuring Performance

¿No quieres perderte nuestra próxima publicación sobre rendimiento web? Recíbelo convenientemente en tu bandeja de entrada uniéndote a nuestro newsletter.