Entrega del contenido web

30 de diciembre de 2021

Una maneras en las que podemos, y debemos, mejorar el rendimiento de nuestra web es mejorando la entrega de los contenidos.

Usar servidores que permitan el uso de protocolos modernos, elegir entregar los contenidos en formatos comprimidos y también saber qué ficheros se deben y cuáles no se deben comprimir.

Esto se traducirá en una agradable percepción de mayor velocidad para el usuario, pero también de un importante ahorro en cuanto a proceso y consumo de datos.

Protocolos de red

Necesito empezar viendo, muy a grandes rasgos y muy de andar por casa, cosas de protocolos de red.

Una transmisión de red se realiza en varias capas. Unas tienden más hacia la parte física, caracterizadas por el medio en el que se transmiten los datos; y otras, en una parte más lógica, definen formas en las se transmiten esos datos.

En un nivel más o menos intermedio podemos encontrar los protocolos TCP y UDP (Protocolos de la capa de transporte), muy extendidos hoy en día y, en general, en los que se basa Internet.

Debemos saber que las transmisiones en una red se realizan en trocitos, paquetes de red.

UDP (User Datagram Protocol)

Este protocolo es usado, normalmente, para transmisiones que requieren velocidad por encima de seguridad. Seguridad en en cuanto a la entrega de los datos, no en el secreto de los mismos.

Este protocolo, es el que se usa para la obtención de las IP relacionadas con un dominio por parte de los DNS, o en streams de audio o vídeo.

La velocidad de este protocolo radica en que transmite todos los paquetes sin establecer una conexión previa ni esperar una confirmación de recepción por parte del cliente. Éste los puede recibir o no, o recibirlos o no de manera ordenada. ¿A que te ha ocurrido de estar viendo un vídeo en streaming y, de pronto, se pixela, se entrecorta el sonido, pero sigue la reproducción? Pues es porque se perdieron paquetes o llegaron tarde.

Si hubiese un fallo suficientemente grande, sería el receptor quien volvería a pedir los paquetes erróneos, faltantes, o todos.

Haciendo un símil, es como el correo ordinario: envías una carta y el servicio de correos no te va a informar de si la ha entregado o no.

TCP (Transmission Control Protocol)

En el caso del TCP, el servidor mantiene un control sobre los paquetes. Para esto necesita establecer una conexión entre el servidor y el cliente.

Al establecer la conexión se establece qué datos se van a transmitir y en qué orden. Al terminar de enviar el último, se notifica que se cierra la conexión. Igualmente, al terminar de recibir, el cliente también notifica el cierre de la conexión.

Durante el tiempo en que la conexión está establecida, el cliente va confirmando cada uno de los paquetes de datos que va recibiendo correctamente para que el servidor envíe el siguiente.

Este proceso hace este protocolo más lento que, por ejemplo UDP, al tener que emplear partes importantes de la conexión en mantener el control sobre estos datos.

En este caso, el símil se acerca más al correo certificado, o con acuse de recibo.

Protocolos de transferencia de hipertexto

El Protocolo HTTP es el protocolo que, sobre los anteriores, UDP o TCP, permite la transferencia de ficheros de información en la Web.

A lo largo de su historia desde principios de los años 90 del s.XX, ha experimentado varios cambios y mejoras reflejados en sus diferentes versiones.

HTTP 1.1

Funciona sobre TCP.

Versiones anteriores hacía necesario establecer una conexión por cada transferencia. La versión 1.1 incorpora la posibilidad de realizar varias transmisiones dentro de una misma conexión al poder mantener ésta abierta durante un tiempo establecido (keep-alive). Esto ahorra el coste de tener que abrir y cerrar conexiones por cada transferencia.

Hasta este momento era necesario recibir la respuesta a una petición para poder realizar la siguiente. HTTP1.1 soporta pipeline, que permite realizar varias peticiones consecutivas (creo que son 5) sin esperar respuesta entre ellas. El servidor irá entregando cada uno de los recursos pedidos a continuación y en el mismo orden en el que fueron solicitados. Al terminar de recibir los recursos, el cliente puede volver a pedir otros cinco, incluso en la misma conexión si tiene habilitado keep-alive.

Con este protocolo, las respuestas deben ser procesadas y servidas en el mismo orden en el que se realizan las peticiones. Por lo que cada respuesta solo se transmitirá una vez la anterior haya sido transmitida.

HTTP/2

Funciona sobre TCP y requiere de una conexión segura SSL.

Si la versión 1.1 del protocolo permitía hasta cinco peticiones, HTTP/2 permite realizar hasta veinte peticiones de una vez.

En este caso, las peticiones se resuelven de manera asíncrona. Cada una tiene asignado un identificador (independiente del orden) lo que le permite al servidor ir entregando las respuestas en cualquier orden.

También, permite resolver las peticiones teniendo en cuenta prioridades calculadas en base a dependencias y pesos. Esto va a permitir, al cliente, establecer estas prioridades y, al servidor, asignar recursos y planificar para realizar las entregas de forma más eficaz.

Permite el uso de HTTP/2 Server Push. Esto, no siendo fácil de implementar, consigue que el servidor envíe ciertos resursos asociados antes de que el cliente tenga que pedirlos.

HTTP/3

Podría decirse que la versión 3 de http es HTTP/2 corriendo sobre UDP, haciendo uso de QUIC. Al funcionar sobre UDP, no es necesario establecer una conexión previa a la transmisión de los datos. Se ahorra el coste de establecer las conexiones y, además, el coste del control de los datos.

QUIC se encarga de gestionar la seguridad y las transferencias, de conseguir la multiplexación (el envío y recepción sin tener que volver a negociar la conexión) y de controlar la integridad de las transmisiones.

HTTP Push

Ya comenté anteriormente, de manera aproximada, cómo se carga una web. En resumen, el navegador web, obtiene el html y comienza a analizarlo de arriba a abajo. Según va encontrando recursos necesarios, los va pidiendo al servidor. Así, con HTTP1.1 se podrá pedir lotes de cinco recursos y con HTTP/2 podrá ir pidiendose hasta un límite de veinte.

Pero, si conocemos nuestra web, sabemos qué recursos van a ser necesarios sí o sí. Podríamos hacer que el servidor envíe junto con el html recursos que consideremos críticos para la web. Por ejemplo, en el caso de WordPress es casi seguro que va a necesitar jquery, las fuentes, algún css… el típico abobe the fold.

HTTP Push se puede usar tanto con HTTP/2 como con HTTP/3.

Ya, pero… y la caché del navegador

Como es el servidor el que fuerza la descarga de los recursos, junto con la primera petición del navegador, ¿qué ocurre si el recurso ya está cacheado? ¿Nos lo va a volver a enviar? Sí, o no, depende del servidor, la configuración de la web y el navegador. Sencillo, ¿no?

Se puede hacer uso de una cookie. Esta se enviará con la petición conteniendo información de los recursos ya cacheados y, que el servidor, los omita si no son necesarios.

En general, el servidor va a enviar los recursos, pero el navegador puede, al recibirlas cabeceras, comprobar la cache y cancelar la descarga. El «problema» es que a veces, las descargas terminan antes de que el navegador la haya cancelado.

Así que aquí, en general, nos va a tocar hacer pruebas y decidir si el incremento en el rendimiento compensa o solo ocupamos ancho de banda a lo tonto.

Podríamos tener en cuenta el peso de la descarga. Típicamente, me he encontrado, en que PageSpeedInsigths encuentra que jQuery es uno de esos recursos que bloquean la carga. JQuery, es una descarga bastante grande y quizás es conveniente meterla en un push. Pero, entonces, ya sabes que no debemos abusar de esto.

¿Por qué ahora sí pero antes no se usaba UDP?

Haciendo una suposición, o varias. Hace unos años, la parte de negociación de la conexión era menos costosa en relación al tiempo total de una transferencia. Compensaba usar tiempo en asegurar una conexión TCP y que hubiese un control sobre las transmisiones.

Con las velocidades de tranferencia actuales, posiblemente, y con recursos pequeños es así, la mayor parte del tiempo se pierde en establecer las conexiones y reportar estados. Por tanto, a día de hoy, es más eficiente no controlar las transferencias y, si fallasen, volverlas a pedir.

Por otro lado, QUIC dispone de un mecanismo para reconstruir información faltante o defectuosa en las transferencias, lo que, en gran medida, compensa la deficiencia en cuanto a la falta da control de UDP.

Algoritmos de compresión

Siempre supone una gran mejora que el servidor envíe los ficheros comprimidos. Pero no todos los ficheros deben ser comprimidos antes de enviar. Algunos tipos de archivo, como las imágenes jpeg o las fuentes woff, ya están comprimidas y volver a aplicarle un algoritmo de compresión puede resultar en ficheros más grandes.

¿Qué ficheros comprimir?

Comprime los ficheros que se envíen como texto o, si las tienes, imágenes que no estén en un formato comprimido, como bmp, tiff…

  • Ficheros de texto:
    • txt
    • css
    • js
    • json
    • html
    • xml
    • svg (sí, svg es un fichero de texto)
  • Ficheros de fuentes:
    • ttf
    • svg
    • otf
  • Otros:
    • pdf

WOFF2 ya es un formato comprimido con Brotly, evita volver a comprimirlo.

Gzip / DEFLATE

GZIP y DEFLATE, son el mismo algoritmo, en esencia. La principal diferencia, según he podido entender, radica en el algoritmo que usan para crear las sumas de seguridad (que evitan errores en el fichero) y la forma en la que comprimen la cabecera y pie del fichero.

Como siempre, hay quien recomienda uno u otro, en la práctica más basados en preferencias personales que en una diferencia sustancian en el rendimiento. Uno comprime un poco más, el otro descomprime más rápido. A la hora de que el contenido esté disponible, pues andan a la par.

<IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/html text/richtext text/plain text/xsd text/xsl text/xml image/bmp application/java application/msword application/vnd.ms-fontobject application/x-msdownload image/x-icon application/json application/vnd.ms-access video/webm application/vnd.ms-project application/x-font-otf application/vnd.ms-opentype application/vnd.oasis.opendocument.database application/vnd.oasis.opendocument.chart application/vnd.oasis.opendocument.formula application/vnd.oasis.opendocument.graphics application/vnd.oasis.opendocument.presentation application/vnd.oasis.opendocument.spreadsheet application/vnd.oasis.opendocument.text audio/ogg application/pdf application/vnd.ms-powerpoint image/svg+xml application/x-shockwave-flash image/tiff application/x-font-ttf application/vnd.ms-opentype audio/wav application/vnd.ms-write application/font-woff application/vnd.ms-excel
    <IfModule mod_mime.c>
        # DEFLATE by extension
        AddOutputFilter DEFLATE js css htm html xml
    </IfModule>
</IfModule>Lenguaje del código: HTML, XML (xml)

Brotli

Brotli es otro algoritmo de compresión que, afirman, consigue comprimir hasta un 30% más que DEFLATE sin añadir demasiada carga de trabajo en comparación.

<IfModule mod_brotli.c>
    AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript application/json application/x-font-ttf application/vnd.ms-fontobject image/x-icon
    <IfModule mod_mime.c>
        AddOutputFilter BROTLI_COMPRESS js css htm html xml
    </IfModule>
</IfModule>Lenguaje del código: HTML, XML (xml)

¿Y si el navegador no admite brotly?

No te preocupes. El navegador, o cliente, junto con la petición información sobre qué algoritmos de compresión soporta. Y el servidor lo tendrá en cuenta.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.