Zurück zum Blog

Folgen und abonnieren

HTML mit dem Fastly JavaScript SDK neu schreiben

Sy Brand

Staff Software Engineer, WebAssembly

Eine Abbildung einer Tastatur mit einem Hebel in der Mitte und einer Hand, die den Hebel nach vorne schiebt

Die Anpassung von Webseiten für den Zuschauer kann das Umschreiben von HTML erfordern, das aus einer anderen Quelle abgerufen wurde. Vielleicht stellen wir eine Anforderung an einen Service, der einem anderen Team gehört, und müssen Teile der Antwort selektiv ändern. Vielleicht möchten wir die statischen Teile der Seite auf der Edge cachen, näher am Nutzer, und die individuelle Anpassung an einem physischen Standort vornehmen, der die Anfragelatenz minimiert. Das Fastly Compute JavaScript SDK ist jetzt mit einem Streaming-HTML-Rewriter ausgestattet, der diese Ziele mit einer ergonomischen API erreichen kann, die sich in bestehende Webstandards einfügt und herkömmliche serverseitige DOM-Manipulationslösungen übertrifft.

Der HTML-Rewriter ist in Version 3.35.0 des JS SDK verfügbar und die Dokumentation finden Sie in den Dokumenten zu @fastly/js-compute.

So funktioniert die HtmlRewritingStream-API

Das JS SDK bietet einen HTMLRewritingStream-Typ, mit dem Sie das Umschreiben von Callbacks auf CSS-Selektoren registrieren können. Wenn der Rewriter auf ein Element trifft, das mit dem Selektor übereinstimmt, ruft er den registrierten Callback auf. Dieser Callback kann die Attribute des Elements manipulieren und Inhalte aus dem unmittelbaren Kontext hinzufügen oder entfernen. Nachdem Sie eine Instanz dieses Typs erstellt haben, können Sie einen HTML-Stream durch ihn leiten. Wenn wir beispielsweise den Text „Header: “ vor alle h1-Tags setzen und div-Tags ein Attribut hinzufügen möchten, könnten wir Folgendes schreiben:

/// <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)));

Sie konstruieren den HTMLRewritingStream mit zwei Callbacks: einen für H1-Tags und einen für divs. Sie stellen eine HTTP-Anfrage, um eine HTML-Seite abzurufen, und leiten die Antwort durch den Rewriting-Transformer. Schließlich geben Sie eine Antwort zurück, die den umgeschriebenen Text enthält.

HTMLRewritingStream ist eine Art von TransformStream – ein Teil des Streams-API-Webstandards. Dies hat zwei wesentliche Vorteile. Erstens wird HTML in einem Streaming-Verfahren verarbeitet, bei dem das Dokument in Fragmenten empfangen, verarbeitet und an den Client gesendet wird, anstatt auf die Übertragung und Transformation des gesamten Dokuments warten zu müssen. Zweitens passt der Rewriter in bestehende Pipelines, die auf TransformStream basieren. Wenn Sie also individuelle Streaming-Transformationen haben, die Sie vor oder nach dem HTML-Rewrite durchführen möchten, verketten Sie einfach einen weiteren PipeThrough-Aufruf, etwa so:

body.pipeThrough(aCustomTransformer)
    .pipeThrough(htmlRewriter)
    .pipeThrough(anotherCustomTransformer);

Die API orientiert sich an der html-rewriter-Schnittstelle von Akamai, mit Ausnahme der Option insert_implicit_close, die nicht unterstützt wird, und der Hinzufügung der Option escapeHTML, die das Einfügen von HTML als Text in umgeschriebene Elemente ermöglicht. Die Implementierung nutzt das lol-html Rust-Crate von Cloudflare, um Parsing und Umschreiben in Echtzeit durchzuführen.

Performance-Benchmarks: Fastly HTMLRewritingStream vs. LinkeDOM

Dank der zugrundeliegenden streamingbasierten Infrastruktur für latenzarmes Parsen und Umschreiben übertrifft HTMLRewritingStream reine JS-Bibliotheken wie LinkeDOM deutlich. Die folgende Grafik zeigt die Verarbeitungszeit in Millisekunden für das Überschreiben einer Anzahl von Bild-Tags zusammen mit ihren Beschriftungen und Beschreibungen:

Beachten Sie die logarithmischen Achsen. Dies zeigt, dass die Verarbeitungszeit für HTMLRewritingStream etwa 20-mal schneller ist als die von LinkedDOM. Die Messungen wurden mit einer lokalen Ausführung auf einem M3 MacBook Pro durchgeführt und über 20 Durchläufe gemittelt.

Sie können den Unterschied in Aktion in dieser kleinen Demo sehen, in der Bilder mit einem Bild von Nicholas Cage umgeschrieben werden (beachten Sie, dass die Auswahl höherer Bildzahlen für die LinkeDOM-Implementierung zu CPU-Timeouts führen kann).

Fazit: High-Performance-HTML-Rewriting auf der Edge mit Fastly Compute

Die HTML-Rewriter-Funktion des Fastly JavaScript SDK ist jetzt in Version 3.35.0 verfügbar. Sie bietet Ihnen eine ergonomische, leistungsstarke Methode zum Umschreiben von HTML, die in bestehende Webstandards passt. Bitte probieren Sie sie aus und lassen Sie uns wissen, wie sie Ihre Compute-Workloads unterstützt.