{"id":148,"date":"2022-06-22T20:18:44","date_gmt":"2022-06-22T18:18:44","guid":{"rendered":"https:\/\/edfmultisite.digital\/mainwp\/?p=148"},"modified":"2022-12-14T20:32:34","modified_gmt":"2022-12-14T19:32:34","slug":"repensar-el-rendimiento-web-con-trabajadores-de-servicios","status":"publish","type":"post","link":"https:\/\/edfmultisite.digital\/mainwp\/post\/repensar-el-rendimiento-web-con-trabajadores-de-servicios\/","title":{"rendered":"Repensar el rendimiento web"},"content":{"rendered":"\n<h2 class=\"has-text-align-center wp-block-heading\">Este art\u00edculo examina el estado actual del arte en la optimizaci\u00f3n de la velocidad de la p\u00e1gina a trav\u00e9s de la tecnolog\u00eda Service Worker. Contiene la esencia de m\u00e1s de 30 a\u00f1os-hombre de investigaci\u00f3n que se dedicaron a <a rel=\"noreferrer noopener\" href=\"https:\/\/www.baqend.com\/speedkit.html\" target=\"_blank\">Speed Kit<\/a>,un complemento de rendimiento web f\u00e1cil de usar para <a href=\"https:\/\/test.speed-kit.com\/\" target=\"_blank\" rel=\"noopener\">acelerar sitios web.<\/a>.<\/h2>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*LEl_DIh5mYsTIapr-qKcNw.png\" alt=\"\"\/><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"ec9d\">TL;DR<\/h1>\n\n\n\n<p id=\"a3f5\">Los usuarios se van cuando la carga de la p\u00e1gina tarda demasiado. Pero a pesar de que la velocidad de la p\u00e1gina es fundamental para el \u00e9xito comercial, las cargas de p\u00e1gina lentas siguen siendo comunes en los sitios web modernos. \u00bfPor qu\u00e9 es eso y qu\u00e9 puedes hacer al respecto?<\/p>\n\n\n\n<p id=\"45a7\">En la primera parte de este art\u00edculo, motivamos nuestra b\u00fasqueda de tiempos r\u00e1pidos de carga de p\u00e1gina e identificamos los&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#0052\" target=\"_blank\" rel=\"noopener\">3 cuellos de botella principales en el rendimiento web:<\/a>: frontend, backend y red. Abordando todos estos desaf\u00edos, resumimos el actual&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#07b5\" target=\"_blank\" rel=\"noopener\">Las 10 mejores pr\u00e1cticas de rendimiento web<\/a>&nbsp;para el lado del cliente (frontend), el lado del servidor (backend) y la transferencia de datos (red). Entramos en m\u00e1s detalles sobre el almacenamiento en cach\u00e9 como la soluci\u00f3n de referencia para acelerar los activos est\u00e1ticos y discutimos por qu\u00e9 los datos din\u00e1micos generalmente se consideran no almacenables en cach\u00e9. Luego desplegamos el dise\u00f1o del sistema respaldado por la investigaci\u00f3n de Baqend que hace&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#e80d\" target=\"_blank\" rel=\"noopener\">almacenamiento en cach\u00e9 de datos din\u00e1micos<\/a>&nbsp;ff\u00e1cil a trav\u00e9s de un novedoso mecanismo de coherencia de cach\u00e9 basado en filtros Bloom (ver&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/www.vldb.org\/pvldb\/vol10\/p1670-gessert.pdf\" target=\"_blank\">VLDB paper<\/a>): Baqend combina los beneficios de latencia del almacenamiento en cach\u00e9 HTTP con atomicidad \u0394 y consistencia de lectura linealizable. Luego entramos en detalles sobre c\u00f3mo se puede usar el esquema de almacenamiento en cach\u00e9 \u00fanico de Baqend para&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#d876\" target=\"_blank\" rel=\"noopener\">acelerar cualquier sitio web<\/a>&nbsp;a trav\u00e9s&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/test.speed-kit.com\/\" target=\"_blank\">Speed Kit<\/a>, un complemento de rendimiento web f\u00e1cil de usar. Finalmente, le mostramos c\u00f3mo generar&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#b59c\" target=\"_blank\" rel=\"noopener\">su propio informe de rendimiento<\/a>&nbsp;para descubrir el potencial para una mayor optimizaci\u00f3n.<\/p>\n\n\n\n<p id=\"5fe3\">(Para obtener una descripci\u00f3n general estructurada de las preguntas espec\u00edficas respondidas en este art\u00edculo, consulte la&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#2213\" target=\"_blank\" rel=\"noopener\">tabla de contenidos<\/a>&nbsp;en el fondo.)<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*EWd7zBr3jgZbvgBcy03Q2w.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"59db\">Comencemos con una motivaci\u00f3n para optimizar el rendimiento web.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"d803\">\u00bfPor qu\u00e9 es importante la velocidad de la p\u00e1gina?<\/h1>\n\n\n\n<p id=\"61ea\">El 49% de los usuarios espera que los sitios web se carguen en 2&nbsp;segundos o menos, seg\u00fan un&nbsp;<a href=\"https:\/\/www.akamai.com\/us\/en\/multimedia\/documents\/content\/%20akamai-performance-matters-key-consumer-insights-ebook.pdf,\" target=\"_blank\" rel=\"noopener\">encuesta de Akamai<\/a>. Pero estas expectativas no se cumplen en la pr\u00e1ctica: el sitio web de comercio electr\u00f3nico promedio de los 500 principales, por ejemplo, tiene un tiempo de carga de p\u00e1gina de 9,3 segundos (ver&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.radware.com\/applicationdelivery\/applicationaccelerationoptimization\/2014\/02\/report-sotu-for-ecommerce-page-speed-web-performance-winter-2013-14\/\" target=\"_blank\">source<\/a>).<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*CeZdKY4Oj6n9lwwqeXzxuw.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"8cc0\">Y aqu\u00ed est\u00e1n&nbsp;<a href=\"http:\/\/www.soasta.com\/wp-content\/uploads\/sites\/4\/2015\/09\/Time_Is_Money_Preview_Ed_SOASTA.pdf\" target=\"_blank\" rel=\"noopener\">mucho m\u00e1s<\/a>&nbsp;estudios que relacionan el rendimiento web con el comportamiento del usuario. Por ejemplo,&nbsp;Amazon&nbsp;encontr\u00f3 que 100&nbsp;ms de tiempo de carga adicional reducen los ingresos por ventas en un 1&nbsp;%. Con los ingresos actuales de Amazon, el impacto supera los mil millones de d\u00f3lares al a\u00f1o. De manera similar,&nbsp;Google&nbsp;midi\u00f3 una ca\u00edda del 20% en el tr\u00e1fico al comparar las reacciones de los usuarios a 30 resultados de b\u00fasqueda en lugar de 10: la disminuci\u00f3n en la participaci\u00f3n se debi\u00f3 a 500&nbsp;ms de latencia adicional para la consulta de b\u00fasqueda. Al rev\u00e9s,&nbsp;GQ&nbsp;observ\u00f3 un aumento permanente del 80&nbsp;% en el tr\u00e1fico despu\u00e9s de mejorar el tiempo de carga de la p\u00e1gina de 7 a 2&nbsp;segundos.<\/p>\n\n\n\n<p id=\"5e23\">Dado que incluso las peque\u00f1as mejoras en la velocidad de la p\u00e1gina tienen un tremendo impacto en el \u00e9xito comercial, realmente sorprende la cantidad de sitios web que no son r\u00e1pidos en absoluto. A lo largo del resto de este art\u00edculo, cubriremos c\u00f3mo medir cu\u00e1ndo los sitios web se sienten lentos, discutiremos por qu\u00e9 muchos son lentos y explicaremos qu\u00e9 se puede hacer al respecto.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"7990\">\u00bfCu\u00e1ndo se siente r\u00e1pido un sitio web?<\/h1>\n\n\n\n<p id=\"201d\">Las medidas t\u00edpicas de rendimiento web se relacionan con la&nbsp;<a href=\"https:\/\/medium.baqend.com\/web-performance-made-simple-fc61d81d0c0e#028e\" target=\"_blank\" rel=\"noopener\">Tiempo hasta el primer byte (TTFB)<\/a>,&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/Events\/DOMContentLoaded\" target=\"_blank\">DomContentLoaded<\/a>, u otros&nbsp;<strong>aspectos t\u00e9cnicos<\/strong>&nbsp;de la carga de la p\u00e1gina. Si bien esas m\u00e9tricas ayudan a los ingenieros a realizar diagn\u00f3sticos 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\u00e1pido, dependiendo de cu\u00e1ndo se muestra el primer contenido relevante. Otro indicador es cu\u00e1nto tiempo tardan en ingresar datos, hacer clic en la barra de navegaci\u00f3n o interactuar con el sitio web de alguna otra manera. Si bien estos aspectos del rendimiento web son f\u00e1ciles de comprender de forma intuitiva,&nbsp;la velocidad de la p\u00e1gina percibida por el usuario&nbsp;no es tan f\u00e1cil de medir objetivamente.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1390\/1*Uz7H2xKc-qCgNMXXWd8UqA.gif\" alt=\"\"\/><figcaption class=\"wp-element-caption\"><strong>First Meaningful Paint&nbsp;<\/strong>(La primera pintura significativa) y el<strong>&nbsp;Speed Index<\/strong>&nbsp;(\u00edndice de velocidad) son medidas de rendimiento que representan la velocidad de p\u00e1gina percibida por el usuario (user-perceived page speed).<\/figcaption><\/figure>\n\n\n\n<p id=\"351a\">En la ilustraci\u00f3n anterior, puede ver c\u00f3mo se carga un sitio web en un dispositivo cliente. La l\u00ednea discontinua indica la&nbsp;integridad visual&nbsp;(eje&nbsp;y) desde una pantalla en blanco (0) hasta la p\u00e1gina completamente renderizada (1). El ejemplo tambi\u00e9n ilustra dos de las medidas m\u00e1s populares para la velocidad de p\u00e1gina percibida por el usuario:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a rel=\"noreferrer noopener\" href=\"https:\/\/docs.google.com\/document\/d\/1BR94tJdZLsin5poeet0XoTW60M0SjvOJQttKT-JK8HI\/view#heading=h.k50nnyhtptq0\" target=\"_blank\"><strong>First Meaningful Paint (FMP)<\/strong><\/a>: La primera pintura significativa es el momento en el que el usuario ve informaci\u00f3n importante por primera vez, p. t\u00edtulo y texto en un blog o barra de b\u00fasqueda y descripci\u00f3n 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\u00e1pido. 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\u00e1fica experimenta el mayor cambio visual. Para identificar el momento exacto en el que esto ocurre, las herramientas de medici\u00f3n recurren al an\u00e1lisis de v\u00eddeo.<\/li>\n\n\n\n<li><a rel=\"noreferrer noopener\" href=\"https:\/\/sites.google.com\/a\/webpagetest.org\/docs\/using-webpagetest\/metrics\/speed-index\" target=\"_blank\"><strong>Speed Index (SI)<\/strong><\/a>: El \u00edndice de velocidad es el tiempo promedio hasta que aparece un elemento visible en la pantalla. Al igual que el tiempo para FMP, el \u00edndice de velocidad tambi\u00e9n se determina a trav\u00e9s del an\u00e1lisis de video y tambi\u00e9n se suele medir en segundos o milisegundos. El \u00edndice de velocidad corresponde al \u00e1rea sobre la l\u00ednea discontinua en la ilustraci\u00f3n anterior: un SI peque\u00f1o corresponde a un sitio web r\u00e1pido.<\/li>\n<\/ul>\n\n\n\n<p id=\"5700\">Tanto FMP como SI son ampliamente reconocidos como buenas representaciones num\u00e9ricas de la velocidad de p\u00e1gina percibida por el usuario; esto los distingue de otras medidas que capturan componentes ocultos del proceso de carga como el&nbsp;<a href=\"https:\/\/medium.baqend.com\/web-performance-made-simple-fc61d81d0c0e#028e\" target=\"_blank\" rel=\"noopener\">tiempo hasta el primer byte<\/a>. Si bien el SI es m\u00e1s detallado en lo que captura, el FMP tiene la ventaja de ser resistente a los valores at\u00edpicos, p. anuncios asincr\u00f3nicos que aparecen despu\u00e9s de un tiempo.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"4730\">\u00bfQu\u00e9 tan r\u00e1pido es lo suficientemente r\u00e1pido?<\/h1>\n\n\n\n<p id=\"9212\">Como se describi\u00f3 anteriormente, la mayor\u00eda de los usuarios esperan tiempos de carga inferiores a dos segundos. Sin embargo,,&nbsp;<a href=\"https:\/\/www.nngroup.com\/articles\/website-response-times\/\" target=\"_blank\" rel=\"noopener\">la ciencia cognitiva sugiere<\/a>&nbsp;que las personas empiezan a perder la concentraci\u00f3n cuando han estado esperando solo un segundo:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*pjxp9EX6svtBR16O0GKfJA.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Ilya&nbsp;<em>Grigorik<\/em>, \u201c<a href=\"https:\/\/hpbn.co\/\" target=\"_blank\" rel=\"noopener\">Redes de navegador de alto rendimiento<\/a>\u201c (2013)<\/figcaption><\/figure>\n\n\n\n<p>que con frecuencia mide los principales dominios de Alexa 1M, muchos sitios web incluso no alcanzan la marca de 10 segundos.<\/p>\n\n\n\n<p>Para cualquier negocio en l\u00ednea, la velocidad de la p\u00e1gina es, por lo tanto, una funci\u00f3n decisiva.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"0ad1\">Un alto ancho de banda no es suficiente, necesitamos reducir la latencia.<\/h2>\n\n\n\n<p id=\"a4d9\">Intuitivamente, una conexi\u00f3n r\u00e1pida a Internet ya deber\u00eda garantizar cargas de p\u00e1gina r\u00e1pidas. Sorprendentemente, sin embargo, este no es el caso. Si su sitio web se siente lento con una conexi\u00f3n de 5 Mbps, actualizar a 10 o incluso 100 Mbps no resolver\u00e1 el problema:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*4LN2bqPCNC9pgZDP6ji_UQ.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">El efecto del ancho de banda frente a la latencia en el tiempo de carga de la p\u00e1gina. (<a rel=\"noreferrer noopener\" href=\"https:\/\/hpbn.co\/primer-on-web-performance\/\" target=\"_blank\">source<\/a>)<\/figcaption><\/figure>\n\n\n\n<p id=\"79df\">Si observa el tiempo de carga de la p\u00e1gina con un ancho de banda creciente (barras azules), notar\u00e1 que no hay una mejora m\u00e1s all\u00e1 de 5 Mbps. Sin embargo, si puede disminuir la latencia de acceso (barras naranjas), ver\u00e1 una disminuci\u00f3n proporcional en el tiempo de carga de la p\u00e1gina. O dicho de otra manera:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>2\u00d7 Bandwidth \u2248 Same Load Time - 2 \u00d7 Ancho de banda \u2248 Mismo tiempo de carga<br><strong>\u00bd Latency \u2248 \u00bd Load Time<\/strong> - \u00bd Latencia \u2248 \u00bd Tiempo de carga<\/p>\n<\/blockquote>\n\n\n\n<p id=\"2c97\">A continuaci\u00f3n, discutiremos los diferentes cuellos de botella para el rendimiento web para explicar por qu\u00e9 la latencia es el factor clave de rendimiento.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"ba8a\"><strong>\u00bfQu\u00e9 hace que los sitios web sean lentos?<\/strong><\/h1>\n\n\n\n<p id=\"4b8c\">Al abrir un sitio web, el navegador env\u00eda una solicitud de datos al servidor web. Dependiendo de la&nbsp;distancia&nbsp;entre el cliente y el servidor, el tiempo de ejecuci\u00f3n del mensaje por s\u00ed solo ya puede causar un retraso significativo. Al recibir la solicitud del cliente, el servidor recopila los datos solicitados (lo que tambi\u00e9n puede llevar algo de tiempo) y luego los devuelve.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*s62LrX1Giuf5gOMO-3QsiQ.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"b87d\">Digamos, por ejemplo, que un usuario de EE. UU. est\u00e1 visitando un sitio web alojado en Europa. Para que el sitio web cargue r\u00e1pido, se deben resolver los siguientes cuellos de botella:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Representaci\u00f3n del lado del cliente&nbsp;(detalles<\/strong>&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#bbc1\" target=\"_blank\" rel=\"noopener\">abajo<\/a>): Incluso cuando los recursos individuales llegan r\u00e1pido, el navegador a\u00fan necesita tiempo para mostrar la p\u00e1gina. 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\u00f3n.<\/li>\n\n\n\n<li><strong>Procesamiento del lado del servidor&nbsp;(detalles<\/strong>&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#995b\" target=\"_blank\" rel=\"noopener\">abajo<\/a>): Para ensamblar los datos solicitados, el servidor debe realizar alg\u00fan 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\u00e1 un tiempo de espera adicional.<\/li>\n\n\n\n<li><strong>Latencia de red&nbsp;(detalles<\/strong>&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#1304\" target=\"_blank\" rel=\"noopener\">abajo<\/a>): Para un sitio web promedio, se deben transferir alrededor de 100 recursos a trav\u00e9s de una conexi\u00f3n de red de alta latencia. Por lo tanto, puede tomar un tiempo hasta que el navegador tenga suficientes datos para mostrar algo significativo.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*Y6-mHeOTlBfim-FenIFcxQ.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"c525\">En resumen de la de&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#ba8a\" target=\"_blank\" rel=\"noopener\">arriba<\/a>, 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\u00edculo, analizaremos m\u00e1s de cerca cada uno de estos tres cuellos de botella y analizaremos las posibles optimizaciones..&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#d876\" target=\"_blank\" rel=\"noopener\">M\u00e1s adelante en este art\u00edculo<\/a>, Describiremos c\u00f3mo implementamos un complemento de rendimiento,&nbsp;Speed \u200b\u200b\u200b\u200bKit&nbsp;, que optimiza estos cuellos de botella autom\u00e1ticamente.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"bbc1\">1.) \u00bfC\u00f3mo optimizar el rendimiento de la interfaz?<\/h1>\n\n\n\n<p id=\"8f3b\">El principio clave de la optimizaci\u00f3n de frontend es hacer que la vida del navegador sea lo m\u00e1s f\u00e1cil posible. Para ello, se deben eliminar los recursos prescindibles y compactar al m\u00e1ximo los restantes. Adem\u00e1s, los recursos cr\u00edticos deben obtenerse no solo lo m\u00e1s r\u00e1pido posible, sino tambi\u00e9n en el orden correcto para permitir un procesamiento fluido. Por \u00faltimo, el contenido debe optimizarse para los dispositivos de los clientes antes de enviar los datos a trav\u00e9s de la red.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"f28a\">Minimizar el peso de la p\u00e1gina<\/h2>\n\n\n\n<p id=\"c185\">Una de las formas m\u00e1s obvias de acelerar la carga de p\u00e1ginas es reducir la cantidad de bytes que deben transferirse a trav\u00e9s de la red. Un buen primer paso es&nbsp;eliminar artefactos no esenciales&nbsp;como HTML no utilizado, comentarios y scripts u hojas de estilo prescindibles. Para que los recursos restantes sean lo m\u00e1s peque\u00f1os posible, las herramientas de minificaci\u00f3n pueden eliminar a\u00fan m\u00e1s los caracteres innecesarios antes de subirlos a producci\u00f3n. Finalmente, la compresi\u00f3n GZip debe estar habilitada para todos los recursos de texto, reduciendo as\u00ed su tama\u00f1o efectivo antes de enviarlos por la red. Asimismo, la compresi\u00f3n de im\u00e1genes tambi\u00e9n puede mejorar la eficiencia del ancho de banda.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"8037\">Optimice la Ruta de Representaci\u00f3n Cr\u00edtica (CRP)<\/h2>\n\n\n\n<p id=\"d9a3\">The&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/medium.baqend.com\/web-performance-made-simple-fc61d81d0c0e#bad5\" target=\"_blank\">critical rendering path (CRP)<\/a>&nbsp;es la secuencia de acciones que el navegador debe realizar para comenzar a mostrar la p\u00e1gina. Para un rendimiento ideal, es obligatorio mantener esta secuencia&nbsp;<a href=\"https:\/\/medium.baqend.com\/building-a-shop-with-sub-second-page-loads-lessons-learned-4bb1be3ed07#fcba\" target=\"_blank\" rel=\"noopener\">tan corto como sea posible<\/a>. Con este fin, los recursos necesarios para mostrar la parte superior de la p\u00e1gina (es decir, el \u00e1rea inmediatamente visible) deben minimizarse, por ejemplo, inclinando el CSS cr\u00edtico. Adem\u00e1s, la carga de scripts de forma as\u00edncrona puede reducir en gran medida la cantidad de recursos cr\u00edticos.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"da00\">Servir im\u00e1genes receptivas<\/h2>\n\n\n\n<p id=\"8203\">Otra optimizaci\u00f3n para reducir la cantidad de datos cargados es&nbsp;cambiar el tama\u00f1o de las im\u00e1genes&nbsp;en el servidor o CDN antes de que se env\u00eden al cliente: en lugar de transferir una imagen de alta resoluci\u00f3n que luego se reduce en el navegador de todos modos, cada cliente recibe una imagen que es ya es perfecto en p\u00edxeles para las dimensiones de pantalla dadas. Cuando las im\u00e1genes est\u00e1n codificadas en&nbsp;WebP o JPEG progresivo, el navegador puede incluso comenzar a mostrarlas antes de que se carguen por completo, lo que reduce a\u00fan m\u00e1s el tiempo de espera percibido.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"9343\">Aproveche el almacenamiento en cach\u00e9 del navegador<\/h2>\n\n\n\n<p id=\"78eb\">The&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/medium.baqend.com\/web-performance-made-simple-fc61d81d0c0e#8a99\" target=\"_blank\">browser cache<\/a>&nbsp;se encuentra dentro del dispositivo del usuario y, por lo tanto, no solo proporciona un acceso r\u00e1pido, sino instant\u00e1neo, a los datos almacenados en cach\u00e9. Para limitar la obsolescencia, cada elemento de datos solo se almacena en cach\u00e9 durante un tiempo de vida (TTL) espec\u00edfico, despu\u00e9s del cual se elimina impl\u00edcitamente. Los activos est\u00e1ticos, como im\u00e1genes o secuencias de comandos, se pueden invalidar en el momento de la implementaci\u00f3n con los destructores de cach\u00e9. Sin embargo, solo se aplican a los activos vinculados: el archivo HTML en s\u00ed solo se suele almacenar en cach\u00e9 durante un tiempo muy corto para garantizar la actualizaci\u00f3n (micro-cach\u00e9, consulte&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#ff9a\" target=\"_blank\" rel=\"noopener\">abajo<\/a>) \u2014 lo que requiere frecuentes y lentas revalidaciones. De manera similar, los datos din\u00e1micos (por ejemplo, un carrito de compras o un teletipo de noticias) generalmente no se colocan en la cach\u00e9 del navegador, porque es dif\u00edcil mantener las copias en cach\u00e9 sincronizadas con los datos base (ver&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#b02e\" target=\"_blank\" rel=\"noopener\">abajo<\/a>). Mediante el uso&nbsp;<strong>Etag &amp; Last-Modified<\/strong>&nbsp;encabezados, es posible evitar recargar recursos vencidos a trav\u00e9s de la red cuando a\u00fan est\u00e1n actualizados: si la versi\u00f3n en cach\u00e9 y la versi\u00f3n original son id\u00e9nticas, el servidor solo env\u00eda un TTL nuevo (extendido) y omite el recurso en s\u00ed.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*87rRZ4cu5RmtGRaMcVZs0w.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Para obtener m\u00e1s informaci\u00f3n sobre el kit de velocidad, consulte a continuaci\u00f3n.,&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#d876\" target=\"_blank\" rel=\"noopener\">vea abajo<\/a>.<\/figcaption><\/figure>\n\n\n\n<p id=\"d647\">Para obtener m\u00e1s informaci\u00f3n sobre la optimizaci\u00f3n del lado del cliente, lea nuestro dedicado&nbsp;<a href=\"https:\/\/medium.baqend.com\/building-a-shop-with-sub-second-page-loads-lessons-learned-4bb1be3ed07#fcba\" target=\"_blank\" rel=\"noopener\">art\u00edculo sobre tecnolog\u00edas frontend<\/a>&nbsp;o ver&nbsp;<a href=\"https:\/\/www.youtube.com\/watch?v=7ipQ0MG-jSo\" target=\"_blank\" rel=\"noopener\">nuestra presentaci\u00f3n Code.Talks sobre rendimiento web (video)<\/a>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"995b\">2.) \u00bfC\u00f3mo ajustar el rendimiento del backend?<\/h1>\n\n\n\n<p id=\"74ea\">Para tiempos de carga de p\u00e1gina ideales, el backend debe producir una respuesta para cada solicitud entrante lo m\u00e1s r\u00e1pido posible. Sin embargo, la parte a\u00fan m\u00e1s dif\u00edcil es proporcionar estos tiempos de respuesta bajos en presencia de muchos usuarios simult\u00e1neos, cortes de red, fallas de m\u00e1quinas u otros escenarios de error.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"29bf\">Eficiencia de la pila del servidor<\/h2>\n\n\n\n<p id=\"56f8\">El&nbsp;Tiempo hasta el primer byte (TTFB)&nbsp;es el tiempo desde que se env\u00eda la primera solicitud hasta que se reciben los primeros datos, medido en el cliente. Representa un l\u00edmite inferior para (y generalmente se corresponde con) el tiempo de carga de su p\u00e1gina: cuanto m\u00e1s peque\u00f1o, mejor. En el lado del servidor, se puede facilitar un TTFB m\u00ednimo a trav\u00e9s de un c\u00f3digo eficiente y el procesamiento de solicitudes en paralelo en lugar de secuencialmente. En un backend distribuido, se recomienda adem\u00e1s optimizar las llamadas a la base de datos para una latencia baja y&nbsp;minimizar el estado compartido&nbsp;para evitar la coordinaci\u00f3n cuando sea posible.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"98d7\">Escalar horizontalmente<\/h2>\n\n\n\n<p id=\"053e\">Para hacer frente a una gran carga, un sistema debe dise\u00f1arse de tal manera que la carga sostenible crezca con la cantidad de m\u00e1quinas en el cl\u00faster. En la pr\u00e1ctica, un&nbsp;<a href=\"https:\/\/medium.baqend.com\/nosql-databases-a-survey-and-decision-guidance-ea7823a822d#059c\" target=\"_blank\" rel=\"noopener\">base de datos fragmentada<\/a>&nbsp;se usa a menudo en combinaci\u00f3n con (en su mayor\u00eda)&nbsp;servidores de aplicaciones sin estado. Para asegurarse de que las solicitudes de los clientes se distribuyan de manera uniforme en todas las m\u00e1quinas, se debe implementar un equilibrio de carga efectivo.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ff3a\">Garantice una alta disponibilidad<\/h2>\n\n\n\n<p id=\"99b4\">Para protegerse contra interrupciones de la m\u00e1quina o particiones de la red, los datos a menudo se distribuyen a varios lugares. Si bien esto aumenta la disponibilidad, tambi\u00e9n abre la puerta a posibles incoherencias entre las diferentes copias. Desde el <a rel=\"noreferrer noopener\" href=\"https:\/\/medium.baqend.com\/nosql-databases-a-survey-and-decision-guidance-ea7823a822d#dcc9\" target=\"_blank\">CAP Theorem<\/a>, sabemos que cada sistema de almacenamiento distribuido est\u00e1 sujeto a una compensaci\u00f3n de disponibilidad-consistencia: Bajo ciertas&nbsp;<a href=\"https:\/\/aphyr.com\/posts\/288-the-network-is-reliable\" target=\"_blank\" rel=\"noopener\">particiones de red<\/a>, tiene que sacrificar la coherencia (por ejemplo, responder con datos obsoletos) o sacrificar la disponibilidad (por ejemplo, devolver un error). Ante este trasfondo,&nbsp;<a href=\"https:\/\/medium.baqend.com\/nosql-databases-a-survey-and-decision-guidance-ea7823a822d#1555\" target=\"_blank\" rel=\"noopener\">elegir el sistema correcto<\/a>&nbsp;para una aplicaci\u00f3n dada es muy complejo. En el lado del servidor, las bases de datos se pueden configurar con&nbsp;conmutaci\u00f3n autom\u00e1tica por error&nbsp;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\u00e9s cuando el backend no est\u00e1 disponible (obsoleto por error).<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*4y4uoOvsoUR-A27glT7xXA.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Para detalles sobre Speed Kit,&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#d876\" target=\"_blank\" rel=\"noopener\">vea abajo<\/a>.<\/figcaption><\/figure>\n\n\n\n<p id=\"a060\">Para obtener m\u00e1s detalles sobre las tecnolog\u00edas utilizadas en el lado del servidor, consulte nuestros art\u00edculos relacionados sobre&nbsp;<a href=\"https:\/\/medium.baqend.com\/how-to-develop-a-backend-as-a-service-from-scratch-lessons-learned-a9fac618c2ce\" target=\"_blank\" rel=\"noopener\">Tecnolog\u00eda backend como servicio (DBaaS)<\/a>,&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/medium.baqend.com\/nosql-databases-a-survey-and-decision-guidance-ea7823a822d\" target=\"_blank\">NoSQL databases<\/a>,&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/medium.baqend.com\/real-time-databases-explained-why-meteor-rethinkdb-parse-and-firebase-dont-scale-822ff87d2f87\" target=\"_blank\">real-time databases<\/a>, and&nbsp;<a href=\"https:\/\/medium.baqend.com\/real-time-stream-processors-a-survey-and-decision-guidance-6d248f692056\" target=\"_blank\" rel=\"noopener\">procesamiento de flujo distribuido<\/a>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"1304\">3.) How to improve network performance?<\/h1>\n\n\n\n<p id=\"5a85\">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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"bc1e\">Reducir Latencia<\/h2>\n\n\n\n<p id=\"f6d6\">como se argumenta&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#0ad1\" target=\"_blank\" rel=\"noopener\">arriba<\/a>, La latencia es el factor clave para mejorar la velocidad de la p\u00e1gina. Para mantenerlo m\u00ednimo, los enfoques de vanguardia emplean&nbsp;<a href=\"https:\/\/medium.baqend.com\/nosql-databases-a-survey-and-decision-guidance-ea7823a822d#a99d\" target=\"_blank\" rel=\"noopener\">replicaci\u00f3n-geogr\u00e1fica<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/medium.baqend.com\/web-performance-made-simple-fc61d81d0c0e#7912\" target=\"_blank\" rel=\"noopener\">almacenamiento en cach\u00e9<\/a>, por ejemplo a trav\u00e9s&nbsp;<a href=\"https:\/\/medium.baqend.com\/web-performance-made-simple-fc61d81d0c0e#2fd5\" target=\"_blank\" rel=\"noopener\">Redes de entrega de contenido (CDN)<\/a>). Sin embargo, mantener la coherencia entre las copias almacenadas en cach\u00e9 (coherencia de cach\u00e9) es fundamental: si no realiza un seguimiento de las copias obsoletas, los usuarios ver\u00e1n contenido obsoleto. Para garantizar datos nuevos para los usuarios, el almacenamiento en cach\u00e9 generalmente se emplea solo para datos est\u00e1ticos. El esquema de almacenamiento en cach\u00e9 \u00fanico de Baqend (ver&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#e239\" target=\"_blank\" rel=\"noopener\">abajo<\/a>), por el contrario, permite almacenar en cach\u00e9 todo: no solo activos est\u00e1ticos, sino tambi\u00e9n resultados de consultas u otra informaci\u00f3n que cambia de forma impredecible.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"28a3\">Optimice la pila de protocolos<\/h2>\n\n\n\n<p id=\"72e4\">Internet est\u00e1 organizado en&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Internet_layer\" target=\"_blank\" rel=\"noopener\">capas<\/a>: Por ejemplo, cuando el tr\u00e1fico HTTP se env\u00eda 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\u00ed sucesivamente. Si bien cada una de estas capas pretende abstraerse de las complejidades de las capas inferiores, comprender c\u00f3mo funciona cada una de ellas y c\u00f3mo dependen unas de otras es fundamental para evitar cuellos de botella. Por ejemplo, debe alinear el tama\u00f1o del paquete TLS con el&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/TCP_congestion_control#Congestion_window\" target=\"_blank\" rel=\"noopener\">TCP ventana de congesti\u00f3n<\/a>&nbsp;evite problemas de latencia para el tr\u00e1fico HTTP encriptado y debe usar conexiones TCP persistentes siempre que sea posible para maximizar el ancho de banda (cf.&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/TCP_congestion_control#Slow_start\" target=\"_blank\" rel=\"noopener\">TCP comienzo-lento<\/a>). TLS tambi\u00e9n se puede optimizar, por ejemplo, mediante&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/OCSP_stapling\" target=\"_blank\" rel=\"noopener\">OCSP grapado<\/a>,&nbsp;<a href=\"https:\/\/hpbn.co\/transport-layer-security-tls\/#tls-session-resumption\" target=\"_blank\" rel=\"noopener\">reanudaci\u00f3n de sesi\u00f3n sin estado<\/a>, o terminar las conexiones TLS en un nodo CDN cercano en lugar del servidor de origen lejano.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"be08\">Aproveche HTTP\/2<\/h2>\n\n\n\n<p id=\"e8dd\">HTTP\/2 es el nuevo est\u00e1ndar para la comunicaci\u00f3n en la web. Introduce m\u00faltiples 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\u00f3n del protocolo, p.e.&nbsp;<a href=\"https:\/\/hpbn.co\/http2\/#request-and-response-multiplexing\" target=\"_blank\" rel=\"noopener\">multiplexaci\u00f3n<\/a>&nbsp;para aumentar la concurrencia o&nbsp;<a href=\"https:\/\/hpbn.co\/http2\/#header-compression\" target=\"_blank\" rel=\"noopener\">compresi\u00f3n de encabezado<\/a>&nbsp;para aprovechar al m\u00e1ximo el ancho de banda disponible. Otras funciones, como la inserci\u00f3n del servidor o la priorizaci\u00f3n de flujos, requieren cierto esfuerzo por parte del cliente o del servidor. Algunas mejores pr\u00e1cticas de HTTP\/1.1 son HTT&nbsp;<a href=\"https:\/\/hpbn.co\/http2\/#server-push\" target=\"_blank\" rel=\"noopener\">empuje del servidor<\/a>&nbsp;o <a href=\"https:\/\/hpbn.co\/http2\/#stream-prioritization\" target=\"_blank\" rel=\"noopener\">priorizaci\u00f3n de secuencias<\/a>&nbsp;requieren un poco de esfuerzo en el lado del cliente o del servidor.&nbsp;<a href=\"https:\/\/www.youtube.com\/watch?v=yURLTwZ3ehk\" target=\"_blank\" rel=\"noopener\">Algunas mejores pr\u00e1cticas de HTTP\/1.1 son HTTP\/2 anti-patterns (video)<\/a>&nbsp;y, por lo tanto, debe evitarse: la fragmentaci\u00f3n del dominio, por ejemplo, fue una forma efectiva de superar la concurrencia limitada de HTTP\/1.1 mediante la carga de recursos a trav\u00e9s de diferentes conexiones en paralelo. Con la versi\u00f3n HTTP\/2, usar una sola conexi\u00f3n es mucho m\u00e1s r\u00e1pido.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*_qhqnqbnZbFo3XlrMWNahQ.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"b5e0\">Para obtener m\u00e1s informaci\u00f3n sobre el ajuste de HTTP\/2 y el rendimiento de la red en general, consulte nuestro&nbsp;<a href=\"https:\/\/www.heise.de\/ix\/heft\/WWW-Beschleuniger-3948333.html\" target=\"_blank\" rel=\"noopener\">Art\u00edculo de Heise (alem\u00e1n)<\/a>&nbsp;o nuestro&nbsp;<a href=\"https:\/\/www.dropbox.com\/s\/048v5xaeavpxu84\/H2%20Presentation.pptx?dl=1\" target=\"_blank\" rel=\"noopener\">Tutorial sobre HTTP\/2 y redes (150 diapositivas)<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*oVwES9LefEG0_JjVyLdL2w.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"4fb8\">En la&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#0052\" target=\"_blank\" rel=\"noopener\">primera parte<\/a>&nbsp;de este art\u00edculo, descubrimos que la latencia es cr\u00edtica para cargas r\u00e1pidas de p\u00e1gina. En el&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#07b5\" target=\"_blank\" rel=\"noopener\">segunda parte<\/a>, luego resumimos las mejores pr\u00e1cticas actuales para evitar cuellos de botella en el frontend, el backend y la red. En esta parte, nos enfocamos en el almacenamiento en cach\u00e9 como el mecanismo fundamental para reducir la latencia y explicamos c\u00f3mo el esquema de almacenamiento en cach\u00e9 \u00fanico de Baqend permite almacenar en cach\u00e9 datos din\u00e1micos con s\u00f3lidas garant\u00edas de consistencia.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"6b6c\">\u00bfC\u00f3mo el almacenamiento en cach\u00e9 web hace que los sitios web sean r\u00e1pidos?<\/h1>\n\n\n\n<p id=\"ddfa\">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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"5632\">Caching brings data closer to the clients<\/h2>\n\n\n\n<p id=\"7240\">In traditional web caching, copies of requested data items are stored in different places all over the world, for example in the clients\u2019 devices (<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"https:\/\/medium.baqend.com\/web-performance-made-simple-fc61d81d0c0e#8a99\">browser cache<\/a>) or a globally distributed&nbsp;<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"https:\/\/medium.baqend.com\/web-performance-made-simple-fc61d81d0c0e#2fd5\">Content Delivery Network (CDN<\/a>). Thus, a client request does not have to travel all the way to the original web server, but instead only to the nearest cache.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*e4hAxCtUdiHkwwHURlAwvQ.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"b422\">Accessing data from nearby caches instead of the original web server has two immediate benefits:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Low Latency:<\/strong>&nbsp;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.<\/li>\n\n\n\n<li><strong>Less Processing<\/strong>: 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.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"b02e\">Challenge: dealing with staleness<\/h2>\n\n\n\n<p id=\"51f3\">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) \u2014 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&nbsp;<strong>Time To Live (TTL)&nbsp;<\/strong><a href=\"https:\/\/tools.ietf.org\/html\/rfc7234\" rel=\"noreferrer noopener\" target=\"_blank\">in the HTTP standard<\/a>. Since static resources change infrequently or not at all, they are typically cached with long TTLs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"605e\">Dynamic data: playing hard to cache<\/h2>\n\n\n\n<p id=\"23c5\">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&nbsp;<strong>small TTLs&nbsp;<\/strong>(micro-caching,&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#ff9a\" target=\"_blank\" rel=\"noopener\">see below<\/a>) for dynamic data or to not cache dynamic data at all.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"e239\">How to cache dynamic content without staleness?<\/h1>\n\n\n\n<p id=\"17a6\">Traditional web caching brings data closer to the clients, but only works for static resources. Baqend is unique through its ability to&nbsp;<em>cache anything<\/em><strong>&nbsp;<\/strong>\u2014 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&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/vsis-www.informatik.uni-hamburg.de\/vsis\/members\/look\/1264\" target=\"_blank\"><strong>published research<\/strong><\/a>. Here is the simple idea: First, we monitor all updates and invalidate stale caches where possible (e.g. in the CDN) \u2014 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\u2019 devices).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6711\">Detect stale data in the backend<\/h2>\n\n\n\n<p id=\"8c59\">To make this possible, Baqend&nbsp;<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"https:\/\/medium.baqend.com\/real-time-databases-explained-why-meteor-rethinkdb-parse-and-firebase-dont-scale-822ff87d2f87#b1b4\">keeps track of every issued response<\/a>&nbsp;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&nbsp;<strong>invalidation-based caches<\/strong>&nbsp;(e.g. CDNs like Akamai or Fastly), this is no problem as they provide an interface to remove specific data items from the cache.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6d07\">Bypass stale data in the client<\/h2>\n\n\n\n<p id=\"7723\">The situation is more involved for&nbsp;<strong>expiration-based caches<\/strong>&nbsp;(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.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*27xKv_RBo_fX2WU7Y6HFsA.png\" alt=\"\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4c4e\">Freshness guaranteed<\/h2>\n\n\n\n<p id=\"6613\">Since the full list of stale URLs can get prohibitively long, we use a compressed representation based on&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Bloom_filter\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>Bloom filters<\/strong><\/a>. 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 \u2014 since our CDN (<a href=\"https:\/\/www.fastly.com\/\" rel=\"noreferrer noopener\" target=\"_blank\">Fastly<\/a>) is invalidation-based (and&nbsp;<a href=\"https:\/\/www.fastly.com\/blog\/building-fast-and-reliable-purging-system\" rel=\"noreferrer noopener\" target=\"_blank\">specialized in fast invalidations through bimodal multicast<\/a>), 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&nbsp;<strong>guaranteed to be up-to-date<\/strong>&nbsp;and can be used safely.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3d3b\">Zero-latency loads<\/h2>\n\n\n\n<p id=\"a07a\">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&nbsp;<strong>browser cache<\/strong>: It is located within the user\u2019s device and therefore does not only provide fast, but&nbsp;<strong>instantaneous&nbsp;<\/strong>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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"7c32\">Example<\/h2>\n\n\n\n<p id=\"10a0\">Let\u2019s illustrate this scheme with a concrete example:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1382\/1*MA7-Zk_F0tHGHEeFXcz3nQ.gif\" alt=\"\"\/><figcaption class=\"wp-element-caption\">With Baqend, users only see fresh data: Using a&nbsp;<strong>Bloom filter<\/strong>&nbsp;of changed resources, clients avoid stale caches.<\/figcaption><\/figure>\n\n\n\n<p id=\"7360\">The above animation shows Baqend caching in action where two clients respectively read and write the same user comment:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Initial read<\/strong>: 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\u2019s browser cache.<\/li>\n\n\n\n<li><strong>Update<\/strong>: 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.<\/li>\n\n\n\n<li><strong>CDN invalidation<\/strong>: While the CDN is automatically invalidated by the server, the browser cache on the client\u2019s device still contains the outdated version of the user comment.<\/li>\n\n\n\n<li><strong>Refresh Bloom filter<\/strong>: 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.<\/li>\n\n\n\n<li><strong>Check Bloom filter<\/strong>: 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!<\/li>\n\n\n\n<li><strong>Bypass browser cache<\/strong>: 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).<\/li>\n<\/ol>\n\n\n\n<p id=\"2971\">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&nbsp;<strong>fast and consistent<\/strong>&nbsp;at the same time. To learn about the nitty-gritty details of this appraoch, check out our&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/www.baqend.com\/paper\/btw-cache.pdf\" target=\"_blank\">Cache Sketch research paper<\/a>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"60a4\">What consistency guarantees does Baqend provide?<\/h1>\n\n\n\n<p id=\"aa55\">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\u2019s caching scheme, in contrast, clients will&nbsp;<strong>never see data that is older than the Bloom filter<\/strong>&nbsp;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.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*sD45bbWgmBxSaq7AXnYq6g.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">To accelerate get requests, Baqend uses all benefits of the&nbsp;<strong>HTTP caching<\/strong>&nbsp;hierarchy, but adds rigorous&nbsp;<strong>consistency guarantees<\/strong>.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"c1ed\">\u0394-Atomicity<\/h2>\n\n\n\n<p id=\"1062\">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 \u2014 even if some TTLs are as long as 30 days. In the distributed systems community, this is called&nbsp;<a href=\"http:\/\/www.vukolic.com\/consistency-survey.pdf\" rel=\"noreferrer noopener\" target=\"_blank\">\u0394-atomicity<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"14c3\">Linearizability<\/h2>\n\n\n\n<p id=\"af94\">By frequently refreshing the Bloom filter, the client can minimize staleness. However, it can also perform every operation as a&nbsp;<strong>revalidation request<\/strong>&nbsp;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.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"6efb\">What optimizations does Baqend apply besides caching?<\/h1>\n\n\n\n<p id=\"baa4\">We have seen that caching optimizes&nbsp;<strong>latency of HTTP requests<\/strong>&nbsp;by putting copies of the data near the client. But as mentioned&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#07b5\" target=\"_blank\" rel=\"noopener\">earlier<\/a>, there are many more network-level optimizations beyond the mere proximity benefit of caching.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"47a9\">Protocol Stack Optimization<\/h2>\n\n\n\n<p id=\"4956\">Baqend implements several network-related optimizations that clients implicitly use.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*YxlTIWPbCrgd2mIGtv66Bw.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"4620\">As one of the most significant features, each of Baqend\u2019s CDN nodes maintains a pool of&nbsp;<strong>persistent TLS connections<\/strong>&nbsp;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&nbsp;<a href=\"https:\/\/istlsfastyet.com\/\" rel=\"noreferrer noopener\" target=\"_blank\">at most two round-trips<\/a>&nbsp;to the nearest CDN node.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"1c4f\">HTTP\/2<\/h2>\n\n\n\n<p id=\"c28b\">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:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/proxy\/1*HH2lLsrrrFdTxrESgWYLYw.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Loading a German website from Canada:&nbsp;<strong>Baqend caching<\/strong>&nbsp;(bottom) vs. standard hosting (top). (<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"https:\/\/medium.baqend.com\/hosting-lessons-learned-6010992eb257#451a\">details<\/a>)<\/figcaption><\/figure>\n\n\n\n<p id=\"f693\">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:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Multiplexing<\/strong>&nbsp;requests over TCP avoids head-of-line blocking.<\/li>\n\n\n\n<li><strong>Server Push&nbsp;<\/strong>allows you to send data before the user requests it.<\/li>\n\n\n\n<li><strong>Header Compression&nbsp;<\/strong>saves bandwidth, e.g. for repeatedly sent cookies.<\/li>\n<\/ul>\n\n\n\n<p id=\"dbf9\">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&nbsp;<a href=\"https:\/\/www.dropbox.com\/s\/048v5xaeavpxu84\/H2%20Presentation.pptx?dl=1\" rel=\"noreferrer noopener\" target=\"_blank\">HTTP\/2 &amp; Networking tutorial (150 slides)<\/a>&nbsp;which contains the gist of what we learned from building Baqend.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"80d8\">Image Optimization<\/h2>\n\n\n\n<p id=\"0cad\">Baqend is not only able to minimize latency and fine-tune network communication, but can also optimize the content itself for you:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*BgWIzvC3QkVP5XlVheJRLg.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"98c3\">Most notably, Baqend can transcode images to the most efficient formats (WebP and Progressive JPEG) and even rescale them to fit the requesting client\u2019s screen: To&nbsp;<strong>minimize page size<\/strong>, 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&nbsp;<strong>imperceptible<\/strong>&nbsp;for the user, these optimizations lead to significant load time improvements, especially when bandwidth is limited (e.g. on mobile connections).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"76df\">Summary<\/h2>\n\n\n\n<p id=\"690c\">In a nutshell, Baqend applies state-of-the-art optimizations transparently for all clients:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*YEm4oTsoUG1LTToERDE4ZA.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"094c\">Most importantly, Baqend reduces latency by caching not only static resources, but&nbsp;<strong>caching everything<\/strong>. Further, Baqend performs transparent network optimizations to enable latencies near the physical optimum.<\/p>\n\n\n\n<p id=\"0e17\">Next, we are going to discuss how modern browser standards can be leveraged to apply the above technology to any existing website.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*Covx712uJUUg-0a2jdm3YQ.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"d79c\">So far in this article, we have established the importance of faster page loads (see&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#0052\" target=\"_blank\" rel=\"noopener\">part I<\/a>), discussed state-of-the-art performance best practices (see&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#07b5\" target=\"_blank\" rel=\"noopener\">part II<\/a>), and described how Baqend provides many optimizations out-of-the-box and adds dynamic data caching on top (see&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#d876\" target=\"_blank\" rel=\"noopener\">part III<\/a>). Next, we describe how Baqend\u2019s unique benefits can be made available to any website using Baqend\u2019s 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&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#b59c\" target=\"_blank\" rel=\"noopener\">final part<\/a>&nbsp;of this article.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"5148\">How can Speed Kit accelerate your existing website?<\/h1>\n\n\n\n<p id=\"d95d\">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.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*J82RxzcSv1EzuuJfIkrJZw.gif\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"092b\">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&nbsp;<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Service_Worker_API\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>Service Worker<\/strong><\/a>, 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 \u2014 but will be cached from there on.<\/p>\n\n\n\n<p id=\"6baa\">To learn more about how Service Workers revolutionize browser performance, check out&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/www.dropbox.com\/s\/enwp8in2lkc2jh8\/ServiceWorkerMeetup_klein.pptx?dl=0\" target=\"_blank\">our talk on Service Workers and web performance<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"65e3\">Opt-in acceleration: You define what will be cached<\/h2>\n\n\n\n<p id=\"238e\">Many resources are easily cacheable through Speed Kit (e.g. images, stylesheets, etc.), while some are not (e.g. ads). Through,&nbsp;<a href=\"https:\/\/www.baqend.com\/guide\/topics\/speed-kit\/whiteblacklisting\/\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>speedup policies<\/strong><\/a><strong>&nbsp;<\/strong>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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"eedb\">End-to-end example: a page load with Speed Kit<\/h2>\n\n\n\n<p id=\"cf79\">Here is what happens in detail, when a user visits a Speed Kit page:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Compatibility check<\/strong>: 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.<\/li>\n\n\n\n<li><strong>Service Worker initialization<\/strong>: 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&nbsp;<strong>background<\/strong>. Speed Kit then becomes active during the load and starts serving requests from this point on. Initialization is required&nbsp;<strong>only on first load<\/strong>: For returning visitors where Speed Kit\u2019s Service Worker is already installed, Speed Kit will serve every request right away \u2014 starting with the HTML itself.<\/li>\n\n\n\n<li><strong>Request interception<\/strong>: Any request issued by the browser is automatically proxied through the Service Worker.<br><em>(a) Normal operation<\/em>: By checking your configuration, Speed Kit determines whether it should accelerate the request or simply forward it to the browser\u2019s network stack.<br><em>(b) Offline mode<\/em>: If there is no network connection, Speed Kit serves everything from the cache.<\/li>\n\n\n\n<li><strong>Bloom filter lookup<\/strong>: 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.)<\/li>\n\n\n\n<li><strong>Accelerated response<\/strong>: If the Bloom filter lookup reveals that a given requested resource is fresh, the response is served from the nearest cache:<br><em>(a) Local cache<\/em>: 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.<br><em>(b) CDN cache<\/em>: 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\u2019s CDN.<br><em>(c) Original server<\/em>: If there is a cache miss in the CDN, the response is fetched from Baqend\u2019s servers or \u2014 if it is not available there \u2014 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.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"df01\">Makes any website a Progressive Web App (PWA)<\/h2>\n\n\n\n<p id=\"dc9a\">With Speed Kit, your website becomes a full-fledged Progressive Web App. Users will not only experience faster page loads through Speed Kit\u2019s request acceleration, but also less downtime through the built-in offline mode:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*DyXsrodnY1tcloe0vaQFgQ.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"649f\">In&nbsp;<strong>offline mode<\/strong>, 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&nbsp;<strong>push notifications<\/strong>&nbsp;from the server to your users.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"d1df\">No vendor lock-in<\/h2>\n\n\n\n<p id=\"29ff\">Since Speed Kit is an opt-in solution, you can also&nbsp;<strong>opt-out any time<\/strong>. If you are not satisfied with Speed Kit\u2019s performance boost, just click the button \u2014 really,&nbsp;<a href=\"https:\/\/www.baqend.com\/guide\/topics\/speed-kit\/deactivation\/\" rel=\"noreferrer noopener\" target=\"_blank\">there\u2019s a button<\/a>&nbsp;\u2014 and your website will be back to the old default instantaneously.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"c510\">How does Speed Kit avoid stale content?<\/h1>\n\n\n\n<p id=\"919e\">To make sure that data is always up-to-date, Speed Kit\u2019s caches have to be refreshed whenever your content changes. Speed Kit does this periodically by default, but we also provide a convenient&nbsp;<a href=\"https:\/\/www.baqend.com\/guide\/topics\/speed-kit\/refreshing\/\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>refresh API<\/strong><\/a>&nbsp;that allows you to update all caches on-demand in realtime (including the browser cache within the user\u2019s device).<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*i5g-VB8cljnCDQVUtCWpdw.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Speed Kit automatically synchronizes all caches with your original website.<\/figcaption><\/figure>\n\n\n\n<p id=\"3ccf\">In more detail,&nbsp;<strong>cache synchronization<\/strong>&nbsp;(refresh) can be done both in two different ways:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Realtime<\/strong>: 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\u2019s cached copy.<\/li>\n\n\n\n<li><strong>Periodic<\/strong>: But even without any action on your part, Speed Kit automatically synchronizes itself in regular intervals (see illustration above for default values).<\/li>\n<\/ul>\n\n\n\n<p id=\"d46f\">Through its refresh mechanisms, Speed Kit stays&nbsp;<strong>always up-to-date<\/strong>&nbsp;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 \u201cscript\u201d). This radically simplifies staying in-sync, because your application logic does not need to identify the exact place where the change occurred \u2014 Speed Kit can figure it out. Also,&nbsp;<strong>invalidations never happen unccessariliy<\/strong>: Caches are only purged, if the content actually changed according to byte-by-byte comparison in Baqend.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"bf70\">How does Speed Kit accelerate personalized content?<\/h1>\n\n\n\n<p id=\"8e2c\">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&nbsp;<a href=\"https:\/\/www.baqend.com\/guide\/topics\/speed-kit\/personalized\/\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>Dynamic Blocks<\/strong><\/a>:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1320\/1*IHN4QPum3JKpwSwDlNI04w.gif\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Dynamic Blocks accelerate your website by loading a generic version first and filling in personalized infos later.<\/figcaption><\/figure>\n\n\n\n<p id=\"bc23\">The basic idea is to load and display personalized content in two steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Load generic page<\/strong>: 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.<\/li>\n\n\n\n<li><strong>Inject personalized data<\/strong>: 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.<\/li>\n<\/ol>\n\n\n\n<p id=\"9ddb\">With this approach, the browser can fetch linked assets much faster and can thus&nbsp;<strong>start rendering early<\/strong>, 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.<\/p>\n\n\n\n<p id=\"4692\">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&nbsp;<strong>single-page app<\/strong>&nbsp;(e.g. based on React or Angular): You simply blacklist the personalized Ajax\/REST API requests.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"3ed6\">How does Speed Kit accelerate third-party content?<\/h1>\n\n\n\n<p id=\"5369\">In practice, page load time is often governed by third-party dependencies. Typical examples are&nbsp;<em>social media integrations<\/em>&nbsp;(e.g. Facebook),&nbsp;<em>tracking providers<\/em>&nbsp;(e.g. Google Analytics),&nbsp;<em>JavaScript library CDNs<\/em>&nbsp;(e.g. CDN.js),<br><em>image hosters<\/em>&nbsp;(e.g. eBay product images),&nbsp;<em>service APIs<\/em>&nbsp;(e.g. Google Maps),<br>and&nbsp;<em>Ad Networks<\/em>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"5598\">For example: Google analytics<\/h2>\n\n\n\n<p id=\"f0d7\">The problem is that each external domain introduces its own handshakes at TCP and TLS level and therefore experiences an initially low-bandwidth connection (<a href=\"https:\/\/en.wikipedia.org\/wiki\/TCP_congestion_control#Slow_start\" rel=\"noreferrer noopener\" target=\"_blank\">TCP slow start<\/a>). All performance best practices fail, because third-party domains are out of control for the site owner. Even Google\u2019s own recommendation tool (<a href=\"https:\/\/developers.google.com\/speed\/pagespeed\/insights\/?hl=de\" rel=\"noreferrer noopener\" target=\"_blank\">PageSpeed Insights<\/a>) warns that its own tracking mechanism (Google Analytics)&nbsp;<a href=\"https:\/\/www.keycdn.com\/blog\/leverage-browser-caching\/\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>slows down websites<\/strong><\/a>: The provided TTL of 2 hours is simply ineffective. The only option left is to copy external resources \u2014 e.g. the Google Analytics script \u2014 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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"7879\">Caching the uncacheable<\/h2>\n\n\n\n<p id=\"b01d\">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.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*GXT8IDVEC9O9mCYIOd4I2Q.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Speed Kit is able to consistently&nbsp;<strong>cache third-party dependencies<\/strong>&nbsp;and deliver them over a warm and fast HTTP\/2 connection.<\/figcaption><\/figure>\n\n\n\n<p id=\"7812\">This does not only&nbsp;<strong>save networking overhead<\/strong>&nbsp;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\u2019s refresh mechanism, this optimization comes with&nbsp;<strong>no additional staleness<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"bd31\">Transparent content optimization<\/h2>\n\n\n\n<p id=\"a452\">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<strong>&nbsp;cache&nbsp;<\/strong>the images from Amazon\u2019s image API and transparently&nbsp;<strong>compress and resize<\/strong>&nbsp;them to fit your page layout the individual users\u2019 screen sizes. This feature also comes out-of-the-box and without any configuration or integration overhead for the site owner.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"46fe\">What distinguishes Speed Kit from CDNs, micro-caching, AMP etc.?<\/h1>\n\n\n\n<p id=\"f5bf\">Speed Kit has some similarities to other approaches for tackling web performance, but provides many benefits on top.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"d0ba\">Speed Kit vs. CDN<\/h2>\n\n\n\n<p id=\"43a6\">Unlike content delivery networks like Akamai, Fastly, or CloudFlare, Speed Kit&nbsp;<strong>caches dynamic data<\/strong>&nbsp;and therefore accelerates content that is simply untouchable for all other caching solutions.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*3BQKaZrkZYHL4glf5JjXhQ.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Speed Kit vs. CDN.<\/figcaption><\/figure>\n\n\n\n<p id=\"5289\">Similarly, Speed Kit is also&nbsp;<strong>accelerating third-party dependencies<\/strong>&nbsp;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\u2019t need to code countless invalidation hooks into your backend code, because Speed Kit\u2019s periodic refreshes&nbsp;<strong>handle cache invalidation automatically<\/strong>. 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&nbsp;<a href=\"https:\/\/www.baqend.com\/guide\/topics\/speed-kit\/privacy\/#speed-kit\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>GDPR compliance<\/strong><\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ff9a\">Speed Kit vs. Micro-Caching<\/h2>\n\n\n\n<p id=\"2dcf\">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,&nbsp;<strong>micro-caching uses short TTLs<\/strong>&nbsp;in order to avoid staleness. But by using short TTLs, micro-caching also provokes frequent&nbsp;<strong>cache misses<\/strong>&nbsp;and thus slow responses for users:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*cq68X4o2NiJ-E3vIDiRNjg.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">While&nbsp;<strong>short TTLs in micro-caching<\/strong>&nbsp;cause frequent cache misses,&nbsp;<strong>Speed Kit separates cache lifetime from staleness bounds<\/strong>&nbsp;through periodic cache refreshes.<\/figcaption><\/figure>\n\n\n\n<p id=\"d253\">In contrast,&nbsp;<strong>Speed Kit uses longer TTLs<\/strong>, 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&nbsp;<strong>periodic refresh<\/strong>. On the other hand, if no change is detected during refresh, the data item will remain in the cache until expiration \u2014 which might be 5 minutes, 5 hours, or 5 days. Internally, Speed Kit&nbsp;<strong>learns with your workload<\/strong>: Through time series prediction, the delivered TTLs will get closer to real inter-update times, the longer your application runs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"7632\">Speed Kit vs. AMP &amp; Instant Articles<\/h2>\n\n\n\n<p id=\"e259\">Google\u2019s Accelerated Mobile Pages (AMP) and Facebook\u2019s Instant Articles (IA) can be used to create fast websites. However, AMP and IA don\u2019t accelerate your&nbsp;<em>existing<\/em>&nbsp;website like Speed Kit does. Instead, Google and Facebook force you to&nbsp;<strong>rebuild your page<\/strong>&nbsp;on their platforms, using only those features that cannot hurt web performance.<br>For example, AMP enforces the following&nbsp;<strong>limitations&nbsp;<\/strong>on your website:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Restricted HTML<\/strong>: You can only use a stripped-down version of HTML.<\/li>\n\n\n\n<li><strong>Restricted JavaScript<\/strong>: No custom JavaScript allowed (except in iframes).<\/li>\n\n\n\n<li><strong>Restricted CSS<\/strong>: All stylings must be inlined and below 50 KB overall.<\/li>\n\n\n\n<li><strong>No repaints<\/strong>: You can\u2019t resize DOM elements (only static sizes allowed).<\/li>\n\n\n\n<li><strong>No desktop<\/strong>: Your website is only available to mobile users.<\/li>\n\n\n\n<li><strong>Google styling<\/strong>: Your website has to include a Google bar at the top.<\/li>\n\n\n\n<li><strong>Stale-while-revalidate<\/strong>: Users may see&nbsp;<a href=\"https:\/\/developers.google.com\/amp\/cache\/overview#google-amp-cache-updates\" rel=\"noreferrer noopener\" target=\"_blank\">outdated content<\/a>.<\/li>\n<\/ul>\n\n\n\n<p id=\"8efe\">As a second reason why AMP pages feel fast, Google uses a&nbsp;<strong>trick&nbsp;<\/strong>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&nbsp;<strong>loaded regardless of whether you click&nbsp;<\/strong>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,&nbsp;<a href=\"https:\/\/test.speed-kit.com\/test\/y0Am5Uampbyexample\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>AMP is relatively slow<\/strong><\/a>.<\/p>\n\n\n\n<p id=\"316b\">Instant Articles are technically similar to Google\u2019s AMP. One of the most significant distinctions, however, is that Facebook\u2019s approach is even more restrictive:&nbsp;<strong>Instant Articles are Facebook-only.<\/strong>&nbsp;Since they are only accessible for Facebook users, Instant Articles cannot be used to create public websites.<\/p>\n\n\n\n<p id=\"fa27\">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 \u2014 not your business: While you are still creating the content,&nbsp;<strong>users don\u2019t recognize your brand<\/strong>&nbsp;as they get their news \u201con Google\u201d or \u201cfrom Facebook\u201d. In consequence, your&nbsp;<a href=\"https:\/\/kinsta.com\/blog\/disable-google-amp\/\" rel=\"noreferrer noopener\" target=\"_blank\">leads may drop<\/a>, you&nbsp;<a href=\"https:\/\/www.alexkras.com\/google-may-be-stealing-your-mobile-traffic\/\" rel=\"noreferrer noopener\" target=\"_blank\">lose traffic<\/a>, you&nbsp;<a href=\"https:\/\/www.theregister.co.uk\/2017\/05\/19\/open_source_insider_google_amp_bad_bad_bad\/\" rel=\"noreferrer noopener\" target=\"_blank\">cannot create rich user experiences<\/a>, and you may even<a href=\"https:\/\/thirtybees.com\/blog\/amp-is-bad-for-e-commerce\/\" rel=\"noreferrer noopener\" target=\"_blank\">&nbsp;hurt your e-commerce sales performance<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*hQwprMcDk_EkwgfaJ8-djQ.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"c582\">In contrast to AMP and IA,&nbsp;<strong>Speed Kit&nbsp;<\/strong><a href=\"https:\/\/test.speed-kit.com\/\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>works for your existing website<\/strong><\/a>&nbsp;and has&nbsp;<em>no limitations<\/em>&nbsp;regarding what HTML, CSS, or JavaScript constructs are permitted. Speed Kit is&nbsp;<em>compatible&nbsp;<\/em>with any frontend framework and web server, working for both&nbsp;<strong>mobile and desktop<\/strong>&nbsp;users. Also, Speed Kit websites are&nbsp;<strong>never stale<\/strong>, since caches are refreshed in realtime \u2014 thus, you don\u2019t have to wait for Google\u2019s or Facebook\u2019s CDN to reflect changes in your website. As the most important advantage, though, Speed Kit is&nbsp;<a href=\"https:\/\/test.speed-kit.com\/test\/y0Am5Uampbyexample\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>simply faster than AMP<\/strong><\/a>.<\/p>\n\n\n\n<p id=\"917a\">At Baqend, we think that web performance should be brought forward through<strong>&nbsp;technological advance<\/strong>, 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\u2019s and Facebook\u2019s ecosystem, watch&nbsp;<a href=\"https:\/\/www.youtube.com\/watch?v=7ipQ0MG-jSo\" rel=\"noreferrer noopener\" target=\"_blank\">our Code.Talks presentation on web performance (video)<\/a>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"bc9d\">Summary<\/h1>\n\n\n\n<p id=\"e909\">In summary, we built Speed Kit to provide the following features:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*hsKgvyNtLRWi5XzmpXPQ6A.png\" alt=\"\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*VlLaDkPfdsnxlRRwRbN2jw.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"a24e\">In this final part of our article, we show how you can benchmark and optimize your own website with minimal time and effort.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"65b4\">How fast is your website?<\/h1>\n\n\n\n<p id=\"ca6c\">To produce detailed performance reports and sophisticated optimization hints, we have developed our own performance measurement tool based on the open-source tool&nbsp;<a href=\"https:\/\/www.webpagetest.org\/\" rel=\"noreferrer noopener\" target=\"_blank\">WebPagetest<\/a>: Baqend\u2019s&nbsp;<a href=\"https:\/\/test.speed-kit.com\/\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>Page Speed Analyzer<\/strong><\/a>&nbsp;measures your web performance and gives you suggestions where there is room for improvement.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*qNBSRn32f7IOSJk_suoQOg.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">The analyzer shows you how fast your website currently is (left) and how much faster it could become (right). (<a href=\"https:\/\/test.speed-kit.com\/test\/HA3g8umedium\/result\" rel=\"noreferrer noopener\" target=\"_blank\">example<\/a>)<\/figcaption><\/figure>\n\n\n\n<p id=\"cdc1\">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&nbsp;<strong>detailed performance report<\/strong>&nbsp;of your current website and a measurement of the performance edge provided during our test with Speed Kit.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*vX0q0d0jf6WKdHlEDe7tLQ.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">The analyzer provides you with&nbsp;<strong>waterfall diagrams<\/strong>&nbsp;and details on connections and requests made during page load. (<a href=\"https:\/\/www.webpagetest.org\/result\/180427_SC_e0daa70eb047ab8f7ef21f87436d7755\/1\/details\/#waterfall_view_step1\" rel=\"noreferrer noopener\" target=\"_blank\">original page<\/a>&nbsp;vs.&nbsp;<a href=\"https:\/\/www.webpagetest.org\/result\/180427_4A_847f047604a29aef4106d955244030ac\/2\/details\/#waterfall_view_step1\" rel=\"noreferrer noopener\" target=\"_blank\">Speed Kit<\/a>)<\/figcaption><\/figure>\n\n\n\n<p id=\"7803\">To produce objective results, the analyzer uses&nbsp;<a href=\"https:\/\/github.com\/GoogleChrome\/puppeteer\" rel=\"noreferrer noopener\" target=\"_blank\">Puppeteer<\/a>&nbsp;and several instances of&nbsp;<a href=\"https:\/\/www.webpagetest.org\/\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>WebPagetest<\/strong><\/a>, 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 (<strong>EU vs. US<\/strong>) and which version of your site should be loaded (<strong>mobile vs. desktop<\/strong>). To provide you with the maximum level of details regarding your website\u2019s performance, our analyzer also makes the&nbsp;<strong>waterfall diagrams<\/strong>&nbsp;available that are generated by WebPagetest.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"0eae\">Quantifiable Metrics<\/h2>\n\n\n\n<p id=\"72b6\">Among others, the Page Speed Analyzer collects the following metrics:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Speed Index &amp; First Meaningful Paint:<\/strong>&nbsp;Represent how quickly the page rendered the user-visible content (see&nbsp;<a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#7990\" target=\"_blank\" rel=\"noopener\">above<\/a>).<\/li>\n\n\n\n<li><strong>Domains:<\/strong>&nbsp;Number of unique hosts referenced.<\/li>\n\n\n\n<li><strong>Resources:<\/strong>&nbsp;Number of HTTP resources loaded.<\/li>\n\n\n\n<li><strong>Response Size:<\/strong>&nbsp;Number of compressed response bytes for resources.<\/li>\n\n\n\n<li><strong>Time To First Byte (TTFB):<\/strong>&nbsp;Represents the time between connecting to the server and receiving the first content.<\/li>\n\n\n\n<li><strong>DOMContentLoaded:<\/strong>&nbsp;Represents the time after which the initial HTML document has been completely loaded and parsed, without waiting for external resources.<\/li>\n\n\n\n<li><strong>FullyLoaded:&nbsp;<\/strong>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.)<\/li>\n\n\n\n<li><strong>Last Visual Change:<\/strong>&nbsp;Represents the time after which the final website is visible (no change thereafter).<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*zCQ6qtpWFCRPyaATDABXCg.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\"><a href=\"https:\/\/test.speed-kit.com\/\" rel=\"noreferrer noopener\" target=\"_blank\">Measure how fast your website is.<\/a><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4b6e\">Video<\/h2>\n\n\n\n<p id=\"f99d\">In addition to the metrics listed above, the Page Speed Analyzer takes a&nbsp;<strong>performance video<\/strong>&nbsp;of both website versions to visualize the rendering process. Through this side-by-side comparison, you can literally&nbsp;<strong>see the effect<\/strong>&nbsp;that Speed Kit has.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"5c2e\">Continuous Monitoring<\/h2>\n\n\n\n<p id=\"168d\">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&nbsp;<strong>validate<\/strong>&nbsp;Speed Kit\u2019s worth to your online business. But you can also try out new configurations to&nbsp;<strong>improve<\/strong>&nbsp;your existing Speed Kit configuration.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"7f37\">What systems are supported?<\/h1>\n\n\n\n<p id=\"fde4\">Speed Kit&nbsp;<strong>works for any site&nbsp;<\/strong>\u2014 and it is easy to integrate into your current tech stack! The generic approach for custom websites is described in the next section.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*ir0zCociXr3NgcWlc3TH_Q.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"0336\">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&nbsp;<a href=\"https:\/\/de.wordpress.org\/plugins\/baqend\/\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>WordPress plugin<\/strong><\/a>. For web hosters, we recommend our&nbsp;<a href=\"https:\/\/ext.plesk.com\/packages\/11e1bf5f-a0df-48c6-8761-e890ff4e906c-baqend\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>Plesk plugin<\/strong><\/a>&nbsp;which is available for Plesk 17.5.3 and higher versions.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"80d2\">How to activate Speed Kit for your website?<\/h1>\n\n\n\n<p id=\"dc0a\">For&nbsp;<a href=\"https:\/\/ext.plesk.com\/packages\/11e1bf5f-a0df-48c6-8761-e890ff4e906c-baqend\" rel=\"noreferrer noopener\" target=\"_blank\">Plesk<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/de.wordpress.org\/plugins\/baqend\/\" rel=\"noreferrer noopener\" target=\"_blank\">WordPress<\/a><strong>&nbsp;<\/strong>websites, we recommend the&nbsp;<em>native plugins<\/em>. However, Speed Kit is also easy-to-use for&nbsp;<em>custom websites<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/max\/1400\/1*dPm3SckDjm-GMOq9SJYjug.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"9bab\">To let you try out Speed Kit in production without any costs at all, Speed Kit provides an&nbsp;<strong>extensive free tier<\/strong>. To activate Speed Kit for your website, follow these steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Register a Speed Kit app<\/strong>:<strong>&nbsp;<\/strong>Create a&nbsp;<a href=\"https:\/\/dashboard.baqend.com\/register\" rel=\"noreferrer noopener\" target=\"_blank\">Baqend account<\/a>&nbsp;and choose app type&nbsp;<em>Speed Kit<\/em>.<\/li>\n\n\n\n<li><strong>Follow the instructions<\/strong>: You will be guided through the installation process by our setup Wizard. In essence, you will do the following:<br><em>(a) Specify the domain<\/em>&nbsp;to accelerate.<br><em>(b) Include a code snippet<\/em>&nbsp;into your website (we will generate it for you).<br><em>(c) Adjust refresh policies<\/em>&nbsp;to make sure our caching infrastructure is always synchronized with your original content.<br><em>(d) Optionally: C<\/em>onfine Speed Kit to parts of you website (e.g. \u201c\/blog\u201d) to try it in a limited scope first.<\/li>\n<\/ol>\n\n\n\n<p id=\"3959\"><strong>Questions?<\/strong>&nbsp;If you require help or have a question, simply drop us a line via&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/gitter.im\/Baqend\/Community\" target=\"_blank\">Gitter<\/a>&nbsp;or&nbsp;<a rel=\"noreferrer noopener\" href=\"mailto:support@baqend.com\" target=\"_blank\">email<\/a>!<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"97f9\">Table of Contents<\/h1>\n\n\n\n<p id=\"74ac\">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:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4b57\"><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#0052\" target=\"_blank\" rel=\"noopener\">Part I<\/a>: Web Performance Bottlenecks<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#d803\" data-type=\"URL\" data-id=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#d803\" target=\"_blank\" rel=\"noopener\">Why is page speed important?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#7990\" target=\"_blank\" rel=\"noopener\">When does a website feel fast?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#4730\" target=\"_blank\" rel=\"noopener\">How fast is fast enough?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#ba8a\" target=\"_blank\" rel=\"noopener\">What makes websites slow?<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"c69e\"><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#07b5\" target=\"_blank\" rel=\"noopener\">Part II<\/a>: Web Performance Best Practices<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#bbc1\" target=\"_blank\" rel=\"noopener\">How to optimize frontend performance?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#995b\" target=\"_blank\" rel=\"noopener\">How to tune backend performance?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#1304\" target=\"_blank\" rel=\"noopener\">How to improve network performance?<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4629\"><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#e80d\" target=\"_blank\" rel=\"noopener\">Part III<\/a>: Baqend \u2014 Caching Dynamic Data<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#6b6c\" target=\"_blank\" rel=\"noopener\">How does web caching make websites fast?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#e239\" target=\"_blank\" rel=\"noopener\">How to cache dynamic content without staleness?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#60a4\" target=\"_blank\" rel=\"noopener\">How to provide consistent reads from a web cache?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#6efb\" target=\"_blank\" rel=\"noopener\">What optimizations can be applied besides caching?<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"2180\"><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#d876\" target=\"_blank\" rel=\"noopener\">Part IV<\/a>: Speed Kit \u2014 Accelerating Any Website<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#5148\" target=\"_blank\" rel=\"noopener\">How to accelerate an existing website?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#c510\" target=\"_blank\" rel=\"noopener\">How to avoid stale content?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#bf70\" target=\"_blank\" rel=\"noopener\">How to accelerate personalized content?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.com\/p\/2638196fa60a#3ed6\" target=\"_blank\" rel=\"noopener\">How to accelerate third-party content?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#46fe\" target=\"_blank\" rel=\"noopener\">How is this different from CDNs, micro-caching, AMP etc.?<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"130d\"><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#b59c\" target=\"_blank\" rel=\"noopener\">Part V<\/a>: Measuring Performance<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#65b4\" target=\"_blank\" rel=\"noopener\">How fast is your website?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#7f37\" target=\"_blank\" rel=\"noopener\">What systems are supported?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a#80d2\" target=\"_blank\" rel=\"noopener\">How can you make your website faster&nbsp;<em>today<\/em>?<\/a><\/li>\n<\/ul>\n\n\n\n<p id=\"c68e\">\u00bfNo quieres perderte nuestra pr\u00f3xima publicaci\u00f3n sobre rendimiento web? Rec\u00edbelo convenientemente en tu bandeja de entrada uni\u00e9ndote a nuestro <a rel=\"noreferrer noopener\" href=\"http:\/\/www.baqend.com\/#newsletter\" target=\"_blank\">newsletter<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Este art\u00edculo examina el estado actual del arte en la optimizaci\u00f3n de la velocidad de la p\u00e1gina a trav\u00e9s de la tecnolog\u00eda Service Worker. Contiene la esencia de m\u00e1s de 30 a\u00f1os-hombre de investigaci\u00f3n que se dedicaron a Speed Kit,un complemento de rendimiento web f\u00e1cil de usar para acelerar sitios web.. TL;DR Los usuarios se [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":289,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,5,4,11],"tags":[7],"class_list":["post-148","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administradores","category-plugins","category-wordpress","category-wpo","tag-servidores"],"_links":{"self":[{"href":"https:\/\/edfmultisite.digital\/mainwp\/wp-json\/wp\/v2\/posts\/148","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/edfmultisite.digital\/mainwp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/edfmultisite.digital\/mainwp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/edfmultisite.digital\/mainwp\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/edfmultisite.digital\/mainwp\/wp-json\/wp\/v2\/comments?post=148"}],"version-history":[{"count":0,"href":"https:\/\/edfmultisite.digital\/mainwp\/wp-json\/wp\/v2\/posts\/148\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/edfmultisite.digital\/mainwp\/wp-json\/wp\/v2\/media\/289"}],"wp:attachment":[{"href":"https:\/\/edfmultisite.digital\/mainwp\/wp-json\/wp\/v2\/media?parent=148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/edfmultisite.digital\/mainwp\/wp-json\/wp\/v2\/categories?post=148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/edfmultisite.digital\/mainwp\/wp-json\/wp\/v2\/tags?post=148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}