HTTP / 2 Server Push permite que un servidor compatible con HTTP / 2 envíe recursos a un cliente compatible con HTTP / 2 antes de que el cliente los solicite. Es, en su mayor parte, una técnica de desempeño que puede ser útil para cargar recursos de manera preventiva.
HTTP / 2 Server Push [1] [2] no es un mecanismo de notificación del servidor al cliente. En cambio, el cliente usa los recursos empujados cuando, de otro modo, puede haber producido una solicitud para obtener el recurso de todos modos; Sin embargo, esto puede resultar en un desperdicio de ancho de banda si dichos recursos empujados no son utilizados por el cliente.
Concepto basico
Considere un sitio web con tres recursos: index.html, styles.css y script.js. Cuando un usuario, a través de su navegador, se conecta a la página de inicio de este sitio web, recupera automáticamente index.html. A medida que el navegador analiza el texto HTML en index.html, encuentra instrucciones que requerirán styles.css y script.js. En ese momento, el navegador emitirá solicitudes para obtener estos otros dos archivos. Para ensamblar la página web completa, el navegador apilará dichas solicitudes a medida que vaya descubriendo gradualmente la composición del sitio.
Con HTTP / 2 Push, el servidor puede tomar la iniciativa al tener reglas que activan el envío de contenido incluso antes de que se solicite. En este escenario de ejemplo, el servidor sabe que cualquiera que solicite index.html necesitará styles.css y script.js, por lo que puede enviarlos al cliente de inmediato sin esperar a que el cliente los solicite. Si se hace correctamente, para cuando el navegador termine de analizar index.html, la transferencia de styles.css y script.js ya habría comenzado, o incluso completado, eliminando la latencia de tener que solicitarlos y esperar a que lleguen.
Cómo funciona HTTP / 2 PUSH a nivel de protocolo
Push funciona a través de HTTP / 2, que en esencia es un protocolo de marcos, lo que significa que la información se intercambia en grupos de bytes llamados marcos. Además, las tramas son parte de los flujos y los flujos se identifican con un número. El número de flujo está presente en cada cuadro como un campo binario. Las secuencias permiten hacer coincidir las solicitudes con las respuestas, por ejemplo, la respuesta a la solicitud GET /index.html en la secuencia 3 también debe estar en la secuencia 3.
Hay diferentes tipos de marcos y cada uno tiene una función diferente. HTTP / 2 tiene solo algunos de estos tipos, y no los necesitamos todos para explicar los conceptos básicos. Aquí están los interesantes para esta descripción:
- Marco HEADERS. Como su nombre lo indica, este tipo de trama lleva encabezados HTTP. Cuando el navegador lo envía al servidor, indica que se está realizando una solicitud. Cuando el servidor lo envía al navegador, indica que se está enviando una respuesta a una solicitud anterior o promesa de inserción.
- Marco PUSH_PROMISE. El servidor envía este marco al navegador para comenzar a enviar un recurso. También contiene encabezados HTTP. Sin embargo, el tipo de encabezados presentes en un marco PUSH_PROMISE son encabezados que normalmente estarían presentes en una solicitud. Esto es diferente de los encabezados de respuesta que normalmente enviaría un servidor. La URL de la solicitud, por ejemplo, está presente en el marco PUSH_PROMISE como el pseudoencabezado de ruta: específico de HTTP / 2, al igual que el pseudoencabezado de: autoridad para indicar un host. Otros encabezados que pueden estar presentes en un PUSH_PROMISE y que utilizan algunos navegadores son los encabezados de caché, por ejemplo, if-none-match.
- Tramas de DATOS. Estos marcos se envían en cualquier dirección para llevar el contenido real de un recurso o el contenido que el navegador envía o PUT al servidor.
- Tramas RST_STREAM. Estos marcos sirven para muchos propósitos. Uno de ellos es hacer que el navegador le indique al servidor que no se necesita un flujo empujado.
Cuando el servidor quiere enviar un recurso, prepara un marco PUSH_PROMISE, diseñándolo de la mejor manera posible para seducir al navegador para que utilice los contenidos enviados. Luego, el servidor anexa el marco PUSH_PROMISE a la parte de respuesta de una secuencia normal iniciada por el navegador. Sin embargo, los datos reales del recurso insertado se envían en un flujo nuevo iniciado por el servidor y, por lo tanto, con un número par.
El navegador mantiene los datos enviados en una zona de "cuarentena" temporal hasta que decide utilizarlos. Más tarde, cada vez que el navegador va a realizar una solicitud real, examina el contenido de las promesas push recibidas para ver si es lo suficientemente similar a la solicitud que desea realizar. Sin embargo, el servidor no necesita esperar hasta ese momento para comenzar a enviar datos para el recurso prometido. Una vez que se ha enviado la trama PUSH_PROMISE en la secuencia iniciada por el navegador, el servidor puede enviar lo que serían encabezados de respuesta usando una trama HEADERS en la nueva secuencia iniciada por el servidor, y luego puede enviar los datos del recurso usando tramas DATA. Y en cualquier momento, el navegador puede interrumpir cualquier transferencia utilizando RST_STREAM.
Así es como funcionaría esto en el ejemplo anterior. Si el servidor está listo para HTTP / 2 PUSH, cuando recibe una solicitud a index.html, puede pronosticar que las solicitudes a styles.css y script.js siguen de cerca. Entonces emite promesas de empuje para adelantarse un poco a los eventos. Así es como podrían verse las cosas, en orden de aparición y formando los números de transmisión:
- El servidor recibe el marco HEADERS solicitando index.html en el flujo 3, y puede pronosticar la necesidad de styles.css y script.js.
- El servidor envía un PUSH_PROMISE para styles.css y un PUSH_PROMISE para script.js, nuevamente en la secuencia 3. Estos marcos son aproximadamente equivalentes a la solicitud de un navegador.
- El servidor envía un marco HEADERS en el flujo 3 para responder a la solicitud de index.html.
- El servidor envía el (los) marco (s) de DATOS con el contenido de index.html, todavía en el flujo 3.
- El servidor envía el marco HEADERS para la respuesta a styles.css en el flujo 4 (observe el número de flujo par) y luego para la respuesta a script.js en el flujo 6.
- El servidor envía marcos de DATOS para el contenido de styles.css y script.js, utilizando sus respectivos números de flujo.
Las promesas push se envían lo antes posible para que el navegador las tenga mucho antes de cualquier descubrimiento. Tenga en cuenta que los encabezados HTTP (específicamente Enlace con la palabra clave 'precarga' [3] ) pueden revelar URL que el navegador necesita buscar, y un navegador ansioso comenzaría a pedir los recursos al ver esos encabezados. Por lo tanto, las promesas de inserción se envían mejor incluso antes de los encabezados de respuesta de la transmisión a la que se adjuntan. [4]
Implementaciones
La inserción del servidor HTTP / 2 se está implementando progresivamente, por ejemplo, el servidor web Nginx lo implementó en la versión 1.13.9 en febrero de 2018. [5]
Según el equipo de Google Chrome , Server Push en HTTP / 2 y gQUIC rara vez se usa, y los recursos enviados no se usan con más frecuencia que se usan. Han propuesto eliminar la función de Chrome y Chromium. [6]
Referencias
- ^ "Configuraciones del servidor HTTP / 2" . Consultado el 30 de marzo de 2019 .
- ^ "Servidor Push" . Protocolo de transferencia de hipertexto versión 2 (HTTP / 2) . IETF . Mayo de 2015. p. 60 seg. 8.2. doi : 10.17487 / RFC7540 . RFC 7540 . Consultado el 6 de mayo de 2015 .
- ^ "Precarga" . w3c.github.io . Consultado el 30 de noviembre de 2016 .
- ^ "Una mirada más cercana a HTTP / 2 Push" . ShimmerCat.
- ^ https://nginx.org/en/CHANGES-1.14
- ^ https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYLvmQUBY/m/vOWBKZGoAQAJ?pli=1