Reescritura de HTML con el SDK de JavaScript de Fastly

Staff Software Engineer, WebAssembly

La personalización de páginas web para el espectador puede requerir reescribir el HTML recuperado de otra fuente. Quizás hagamos una petición a un servicio propiedad de otro equipo y necesitemos modificar partes de la respuesta de forma selectiva. Quizá queramos almacenar en caché las partes estáticas de la página en el borde, más cerca de los usuarios, y realizar la personalización en una ubicación física que minimice la latencia de las peticiones. El SDK de JavaScript de Fastly Compute ahora incluye un reescritor HTML en streaming que puede lograr estos objetivos con una API ergonómica que se ajusta a los estándares web existentes y supera a las soluciones de manipulación de DOM de propósito general en el servidor.
El reescritor de HTML está disponible en la versión 3.35.0 del SDK JS, y la documentación está disponible en la documentación de @fastly/js-compute.
Cómo funciona la API HTMLRewritingStream
El SDK de JS proporciona un tipo HTMLRewritingStream que te permite registrar devoluciones de llamada de reescritura en los selectores de CSS. Cuando el reescribidor encuentra un elemento que coincide con el selector, llama a la callback registrada. Esta callback puede manipular los atributos del elemento y añadir o eliminar contenido del contexto inmediato. Después de crear una instancia de este tipo, puedes canalizar un flujo HTML a través de él. Por ejemplo, si queremos anteponer el texto «Encabezado: » a cualquier etiqueta h1 y agregar un atributo a las etiquetas div, podríamos escribir lo siguiente:
/// <reference types="@fastly/js-compute" />
import { HTMLRewritingStream } from 'fastly/html-rewriter';
async function handleRequest(event) {
let transformer = new HTMLRewritingStream()
.onElement("h1", e => e.prepend("Header: "))
.onElement("div", e => e.setAttribute("special-attribute", "top-secret"));
let body = (await fetch("https://example.com/")).body.pipeThrough(transformer);
return new Response(body, {
status: 200,
headers: new Headers({
"content-type": "text/html"
})
})
}
addEventListener("fetch", (event) => event.respondWith(handleRequest(event))); Construyes el HTMLRewritingStream con dos callbacks: una para etiquetas H1 y otra para divs. Haces una petición HTTP para recuperar una página HTML y pasas la respuesta por el transformador de reescritura. Finalmente, devuelves una respuesta que contiene el cuerpo reescrito.
HTMLRewritingStream es un tipo de TransformStream — que forma parte del estándar web de la Streams API. Esto tiene dos ventajas principales. En primer lugar, el HTML se procesa en streaming, de forma que el documento se recibe, procesa y envía al cliente en fragmentos, en lugar de tener que esperar a que se transmita y transforme el documento completo. En segundo lugar, el reescritor se ajusta a las canalizaciones existentes basadas en TransformStream, así que si tienes transformaciones de streaming personalizadas que quieres realizar antes o después de la reescritura de HTML, simplemente encadena otra llamada de pipeThrough, como esta:
body.pipeThrough(aCustomTransformer)
.pipeThrough(htmlRewriter)
.pipeThrough(anotherCustomTransformer); La API sigue la interfaz html-rewriterde Akamai con la excepción de la opción insert_implicit_close, que no es compatible, y la adición de una opción escapeHTML, que permite incluir HTML como texto en los elementos reescritos. La implementación utiliza la caja de Rust lol-html de Cloudflare para realizar análisis y reescritura sobre la marcha.
Pruebas de rendimiento: Fastly HTMLRewritingStream frente a LinkeDOM
Debido a la infraestructura subyacente de análisis y reescritura de baja latencia basada en streaming, el HTMLRewritingStream supera ampliamente a las bibliotecas JS puras como LinkeDOM. El gráfico a continuación muestra el tiempo de procesamiento en milisegundos para reescribir un número de etiquetas de imagen junto con sus etiquetas y descripciones:

Ten en cuenta los ejes logarítmicos. Esto muestra que el tiempo de procesamiento de HTMLRewritingStream es ~20 veces más rápido que el de LinkedDOM. Las medidas se tomaron con una ejecución local en un MacBook Pro M3, promediadas en 20 ejecuciones.
Puedes ver la diferencia en acción en esta pequeña demo, que reescribe imágenes con una foto de Nicholas Cage (ten en cuenta que seleccionar un mayor número de imágenes para la implementación de LinkeDOM puede producir tiempos de espera de la CPU).
Conclusión: reescritura de HTML de alto rendimiento en el edge con Fastly Compute
La función de reescritura HTML del SDK de JavaScript de Fastly ya está disponible en la versión 3.35.0. Te ofrece una forma ergonómica y eficaz de reescribir HTML que se ajusta a los estándar web existentes. Pruébalo y cuéntanos cómo te está ayudando con tus cargas de trabajo de ordenador.