Polyfill JavaScript Nur bei Bedarf

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Der folgende Beitrag stammt von Pascal Klau, einem Auszubildenden aus Süddeutschland, der unnötige HTTP-Anfragen und Brokkoli nicht mag. Pascal wird einen Weg erklären, wie man einen Polyfilling-Service so nutzt, dass man ihn möglicherweise gar nicht mehr verwenden muss.

Die Situation

Wir möchten JavaScript in ES6-Syntax schreiben. Da wir aber ältere Browser unterstützen müssen, die ES6 nicht verstehen, müssen wir uns damit auseinandersetzen.

Hier ist das Standardverfahren: ES6 schreiben → alles nach ES5 kompilieren (z.B. Babel) → das an den Browser senden.

Das ist vielleicht nicht mehr der effizienteste Weg. Das Problem ist, dass wir moderne Browser zwingen, den alten Code auszuführen, wenn sie es nicht müssten. Sie unterstützen ES6, also können wir ihnen nicht auch ES6 geben.

Ein besserer Weg

Es gibt ein Polyfill-Projekt namens Polyfill.io API, das ES6-Code clientseitig polyfillen kann.

Es implementiert auch Polyfills für einige HTML-Features wie das <picture>-Element.

Beschreibung von ihrer Website

Polyfill.io liest den User-Agent (UA) Header jeder Anfrage und liefert Polyfills, die für den anfragenden Browser geeignet sind. Passen Sie die Antwort basierend auf den Features an, die Sie in Ihrer App verwenden [...].

Es wird von Financial Times entwickelt, daher hat es eine gewisse Unterstützung und wir können ziemlich sicher sein, dass es nicht verschwinden wird.

Eins ist klar: Polyfill.io bietet keine Unterstützung für syntaktischen Zucker. Zum Beispiel Klassen, erweiterte Objektliterale und Dinge wie Pfeilfunktionen. Dafür bräuchte man immer noch einen Compiler.

Polyfill.io einrichten

Polyfill.io zu Ihrem Projekt hinzuzufügen, kann so einfach sein. Fügen Sie das CDN-gehostete Skript zu Ihrer Seite hinzu.

<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>

Beim Ausführen des Skripts werden der UA und die gewünschten Features ausgegeben.

UA detected: chrome/56.0.0
Features requested: default

Request-Parameter ändern

Es gibt eine Reihe von Optionen zur Anpassung der Anfrage, die Sie in die Skriptquelle einfügen.

Funktionen

Liste der zu polyfillenden Browser-Features. Akzeptiert eine durch Kommas getrennte Liste von Feature-Namen. Verfügbare Feature-Namen finden Sie auf der Seite Browser und Features.

<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=fetch"></script>

In Safari 10 sagt das Skript jetzt so etwas

Features requested: fetch

- setImmediate, License: CC0 (required by "Promise", "fetch")
- fetch

Wenn ein Feature wie fetch von einem anderen Feature wie Promise abhängt, fügt Polyfill.io es automatisch hinzu.

Flags

  • always – Polyfill soll unabhängig davon einbezogen werden, ob es vom anfragenden User-Agent benötigt wird.
  • gated – Wenn der Polyfill in das Bundle aufgenommen wird, wird er von einer Feature-Erkennung begleitet, die den Polyfill nur dann ausführt, wenn die native API nicht vorhanden ist.
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=fetch&flags=gated"></script>

Callback

Name einer Funktion, die nach dem Laden der Polyfills aufgerufen wird. Dies ist einfach eine Möglichkeit, Ihren eigenen Code auszulösen, sobald die Polyfills geladen sind. Er soll es ermöglichen, dass der Polyfill-Service einfacher asynchron mit `async` und `defer` Attributen geladen werden kann.

Das Problem

So gut all das auch klingt, es ist immer noch nicht perfekt.

Moderne Browser müssen jetzt kein ES5 mehr laden, sondern müssen stattdessen einen Server-Roundtrip (eine HTTP-Anfrage) machen, um zu prüfen, ob Polyfills benötigt werden.

Das hat mich so sehr gestört, dass ich an einem kleinen Projekt gearbeitet habe, um zu helfen.

Ein noch besserer Weg

Dynamischen Polyfill einrichten

Das von mir erstellte npm-Paket heißt dynamic-polyfill. Es prüft, ob das Feature nativ unterstützt wird oder nicht, bevor eine Serveranfrage gestellt wird.

Die Einrichtung sieht so aus

import polyfill from 'dynamic-polyfill'

polyfill({
    fills: 'fetch, Promise',
    options: 'gated', // default: null
    minify: false,  // default: true
    afterFill() {
        main()
    }
})

function main() {
    // app code here
}

Das wird im Wesentlichen so ausgeführt, in Klartext

Gibt es [window.fetch, window.Promise]?

Wenn ja, rufe den afterFill() Callback auf.

Wenn nein, erstelle ein <script> Tag mit dem `async`-Attribut, füge den Polyfill.io-Link mit allen bereitgestellten Optionen ein und rufe den afterFill() Callback auf, nachdem er geladen wurde.

Hinweis: Nicht alle Optionen werden bisher unterstützt, nur die wichtigsten.

Geringer Fußabdruck

Da dieses Modul weniger als 1 KB minifiziert ist und keine Abhängigkeiten hat, hat es einen super kleinen Fußabdruck in Ihrem Projekt.

Fazit

Schreiben Sie zukunftssicheres und effizientes JavaScript für moderne Browser. Lassen Sie Polyfill.io ältere Browser handhaben. Machen Sie keine zusätzliche HTTP-Anfrage, wenn es nicht sein muss.

Stellen Sie nur sicher, dass Sie etwas zur Hand haben, um diese Freudentränen zu trocknen.