Polyfill: wat het is, werkingsprincipe en bibliotheken voor API-emulatie

Auteur: IT Sectr Gepubliceerd: 2026-05-19 Leestijd: 9 min

Polyfill (polyfill) — code die ontbrekende functionaliteit (API, methoden, objecten) emuleert in omgevingen waar deze niet native is geïmplementeerd. Polyfill maakt het mogelijk om moderne JavaScript-, CSS- of Web API-mogelijkheden te gebruiken in oude browsers en runtime-omgevingen. Volgens MDN Web Docs zijn polyfills een essentieel hulpmiddel voor progressieve verbetering en het waarborgen van cross-browsercompatibiliteit.

Belangrijkste punten

  • Polyfill — softwarematige emulatie van een ontbrekende API in een runtime-omgeving waar deze API niet is geïmplementeerd
  • core-js — de standaardbibliotheek voor polyfills voor modern JavaScript met ondersteuning voor alle stage-4 voorstellen
  • Polyfill.io — service die dynamisch polyfills levert alleen voor de browser van de gebruiker
  • Transpilatie vs polyfill: transpilatie converteert syntaxis (arrow function → function), polyfill voegt nieuwe methoden toe (Array.includes, Promise)
  • Feature detection — controle op aanwezigheid van native implementatie voordat de polyfill wordt geladen om conflicten te voorkomen

Wat is Polyfill?

Polyfill — een codefragment (meestal JavaScript) dat functionaliteit implementeert die de runtime-omgeving niet native ondersteunt. De term werd in 2009 bedacht door Remy Sharp als een woordspeling: Polyfill — een analogie van plamuur (Polyfilla) die scheuren in de muur vult. Polyfill vult de hiaten tussen de standaard en ondersteuning in een specifieke browser of runtime.

Polyfill verandert bestaande code niet — het breidt de runtime-omgeving uit. Als een browser Array.prototype.includes niet ondersteunt, voegt de polyfill deze methode toe aan het prototype van Array voordat de hoofdcode wordt uitgevoerd. Polyfills kunnen nieuwe globale objecten (Promise, Map, Set, Symbol), statische methoden (Array.from, Object.assign) en prototype-methoden emuleren.

Feature detection — een verplicht mechanisme vóór installatie van een polyfill. In plaats van de user-agent te controleren (welke browser), moet de aanwezigheid van de methode worden gecontroleerd: if (!Array.prototype.includes) { Array.prototype.includes = ... }. Dit garandeert dat de polyfill de native implementatie niet overschrijft als deze al bestaat. Google Analytics en andere diensten verzamelen gegevens over API-ondersteuning voor analyse.

Wanneer verschenen polyfills?

De eerste polyfills verschenen in het tijdperk van Internet Explorer 6–8 (2005–2009), toen ontwikkelaars de kloof ontdekten tussen W3C-standaarden en implementatie in browsers. De term werd geïntroduceerd door Remy Sharp in 2009 op de BarCamp London-conferentie. De eerste massale polyfill was html5shiv (2009) — een bibliotheek die ondersteuning voor HTML5-tags (<section>, <article>, <nav>) toevoegde aan Internet Explorer.

Met de komst van ES6 (2015) en de jaarlijkse updatecyclus van ECMAScript groeide het aantal benodigde polyfills. Elk jaar voegt de standaard nieuwe methoden toe (Array.includes, String.padStart, Object.fromEntries, Promise.allSettled) die niet worden ondersteund door oude browsers. core-js, begonnen als es6-shim in 2014, werd de universele oplossing. In 2026 bevat core-js meer dan 5000 polyfill-modules voor ES5–ES2025.

Wat kan en kan niet worden gepolyfill

CategorieKan worden gepolyfillKan niet worden gepolyfill
Prototype-methodenArray.includes, String.startsWith
Globale objectenPromise, Map, Set, Symbol
Statische methodenObject.assign, Array.from
TaalsyntaxisArrow functions, async/await, class
Web APIfetch, IntersectionObserverService Worker (vereist native ondersteuning)

Polyfill vs transpilatie: verschillen en interactie

Transpilatie converteert nieuwe syntaxis naar oude (const → var, () => {} → function() {}). Polyfill voegt ontbrekende methoden en objecten toe (Promise, Array.includes). Deze twee mechanismen vullen elkaar aan: transpilatie zorgt voor syntactische compatibiliteit, polyfills zorgen voor volledigheid van de API. Babel + core-js — de standaardcombinatie voor volledige ondersteuning.

Babel @babel/preset-env met de optie useBuiltIns bepaalt welke polyfills nodig zijn op basis van de doelbrowsers. useBuiltIns: “usage” analyseert welke API's in de code worden gebruikt en koppelt alleen de benodigde polyfills uit core-js. useBuiltIns: “entry” koppelt alle polyfills voor de doelbrowsers via een enkele import van core-js/stable.

Voorbeeld: polyfill voor Array.prototype.includes

js
// Controleren op aanwezigheid en toevoegen van polyfill
if (typeof Array.prototype.includes !== "function") {
  Object.defineProperty(Array.prototype, "includes", {
    value: function(searchElement, fromIndex) {
      if (this == null) {
        throw new TypeError("Array.prototype.includes called on null or undefined");
      }
      var arr = Object(this);
      var len = arr.length >>> 0;
      if (len === 0) { return false; }
      var start = fromIndex | 0;
      var k = Math.max(start >= 0 ? start : len + start, 0);

      while (k < len) {
        if (arr[k] === searchElement) { return true; }
        k++;
      }
      return false;
    },
    writable: true,
    configurable: true,
  });
}

// Gebruik — nu veilig in elke browser
const arr = [1, 2, 3, 4, 5];
console.log(arr.includes(3)); // true

De polyfill voor Array.prototype.includes controleert of de methode is gedefinieerd in het prototype van Array. Zo niet — dan wordt een eigenschap gecreëerd via Object.defineProperty met de flags writable: true, configurable: true. De implementatie volgt de ES2016-specificatie: null/undefined-controle, conversie naar object, werken met negatieve fromIndex. Na het toevoegen van de polyfill werkt de aanroep arr.includes(3) in alle browsers, inclusief Internet Explorer 11.

core-js: de standaardbibliotheek voor polyfills

core-js — de meest complete polyfill-bibliotheek voor JavaScript, die alle stage-4 voorstellen van TC39 (ECMAScript-standaard) ondersteunt. core-js bevat polyfills voor Promise, Symbol, Map, Set, WeakMap, WeakSet, Array-methoden, String-methoden, Object-methoden, Number-methoden, Math-methoden, Reflect, globalThis en alle stage-4 proposals. De huidige versie core-js 3.38+ dekt ES5–ES2025.

core-js integreert met Babel via @babel/preset-env en de optie useBuiltIns. Zonder deze integratie zou de ontwikkelaar elke polyfill handmatig moeten importeren: import “core-js/stable/array/includes”. @babel/preset-env voegt automatisch de benodigde imports toe op basis van de doelbrowsers uit .browserslistrc. Dit verkleint de bundelgrootte — alleen de benodigde polyfills worden gekoppeld.

Voorbeeld: polyfill voor fetch

Fetch API — een van de meest gepolyfillde Web API's. De native implementatie van fetch is beschikbaar in Chrome 42+ (2015), Safari 10.1+ (2017), Firefox 39+ (2015), maar ontbreekt in Internet Explorer en oude WebViews. De polyfill whatwg-fetch emuleert fetch via XMLHttpRequest. Alternatief — gebruik isomorphic-fetch (polyfill voor Node.js en browser) of de universele bibliotheek axios, die geen polyfills nodig heeft.

js
// Laden van fetch-polyfill alleen voor oude browsers
if (typeof self.fetch !== "function") {
  import("whatwg-fetch").then(module => {
    self.fetch = module.fetch;
    console.log("fetch polyfill loaded");
  });
}

// Fetch gebruiken (werkt zowel met polyfill als met native API)
async function loadData() {
  try {
    const response = await fetch("https://api.example.com/data");
    const json = await response.json();
    return json;
  } catch (error) {
    console.error("Failed to load:", error);
  }
}

Dynamische import van de fetch-polyfill via import() garandeert dat moderne browsers geen overbodige code laden. De polyfill wordt asynchroon geladen en blokkeert de hoofdthread niet. Na het laden vervangt self.fetch de native implementatie of voegt de ontbrekende toe. Dit is een techniek van progressive enhancement: moderne browsers krijgen alleen native code, oude browsers — extra polyfill.

Integratie van core-js met Babel

js
// babel.config.js — core-js + preset-env
module.exports = {
  presets: [
    ["@babel/preset-env", {
      useBuiltIns: "usage",
      corejs: {
        version: "3.38",
        proposals: true,
      },
      targets: {
        browsers: ["> 0.5%", "not dead", "not op_mini all"],
      },
    }],
  ],
};
none
# .browserslistrc — doelbrowsers
> 0.5%
last 2 versions
not dead
not op_mini all
ie >= 11
not ios_saf < 12

useBuiltIns: “usage” analyseert de code en voegt alleen die polyfills toe die daadwerkelijk worden gebruikt. corejs.version geeft de versie van core-js in het project aan. targets.browsers bepaalt het minimale browserniveau — hoe ouder de browsers, hoe meer polyfills worden gekoppeld. .browserslistrc wordt niet alleen door Babel gebruikt, maar ook door Autoprefixer, PostCSS en Stylelint voor consistente targeting.

Polyfill.io en dynamisch laden van polyfills

Polyfill.io — een service (en gelijknamige bibliotheek) die dynamisch bepaalt welke polyfills de browser van de gebruiker nodig heeft en alleen deze retourneert. Polyfill.io gebruikt de User-Agent-header om de browserversie te bepalen en levert de minimale set polyfills. Dit vermindert de hoeveelheid verzonden gegevens in vergelijking met een universele polyfill-bundel.

Het aansluiten van Polyfill.io gebeurt via een <script>-tag vóór de hoofdcode van de applicatie. De service analyseert de User-Agent en retourneert een JavaScript-bestand met polyfills alleen voor deze browser. Chrome krijgt geen enkele polyfill, IE 11 krijgt de volledige set. Dit is de optimale benadering voor prestaties: moderne browsers laden geen overbodige code.

Polyfill.io aansluiten

html
<!-- Polyfill.io: dynamisch laden -->
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=Promise%2CArray.prototype.includes%2CObject.assign%2Cfetch"></script>

<!-- Lokale versie van Polyfill.io -->
<script src="/js/polyfill.js"></script>
<script>
  // feature detection voor fetch
  if (!self.fetch) {
    loadScript("/js/fetch-polyfill.js");
  }
</script>

Parameter features in de URL van Polyfill.io geeft aan welke polyfills moeten worden geladen. Mogelijke waarden: methodenamen (Array.prototype.includes), globale objecten (Promise) of flags (es6, es2016). De flag “default” koppelt de basisset voor modern JavaScript. Voor productieprojecten wordt aanbevolen Polyfill.io op een eigen CDN te hosten of een lokale versie van de bibliotheek te gebruiken voor controle over de beschikbaarheid.

Polyfills in mobiele apps en WebView

WebView in mobiele applicaties (Android WebView, WKWebView op iOS) — een speciale omgeving voor polyfills. De WebView-versie hangt af van de OS-versie en de geïnstalleerde update van Chrome System WebView (Android) of WKWebView van iOS Safari. In oude Android-versies (4.4, 5.0) is WebView gebaseerd op Chromium 30–37 — zonder ondersteuning voor fetch, Promise, IntersectionObserver.

React Native gebruikt JavaScriptCore (iOS) of Hermes (Android) — deze engines implementeren ES6+ op verschillende manieren. JavaScriptCore op iOS ondersteunt de meeste ES6-functionaliteiten, maar kan sommige stage-3 voorstellen missen. Hermes (standaard gebruikt in React Native 0.70+) ondersteunt een beperkte set van de ES-standaard — daarvoor zijn polyfills verplicht.

Ondersteuning controleren in WebView

js
// Feature detection voor WebView
const polyfills = [];

// Promise
if (typeof Promise === "undefined") {
  polyfills.push("Promise");
}

// Fetch API
if (typeof self.fetch === "undefined") {
  polyfills.push("fetch");
}

// IntersectionObserver (nodig voor lazy loading)
if (typeof IntersectionObserver === "undefined") {
  polyfills.push("IntersectionObserver");
}

// Dynamisch laden van polyfills
if (polyfills.length > 0) {
  const script = document.createElement("script");
  script.src = "https://cdn.polyfill.io/v3/polyfill.min.js"
    + "?features=" + polyfills.join(",");
  document.head.appendChild(script);
}

Feature detection voor WebView controleert de aanwezigheid van kritieke API's (Promise, fetch, IntersectionObserver) en laadt dynamisch polyfills alleen voor de ontbrekende. Dit garandeert dat moderne WebViews (Chrome 100+ op Android 12) geen overbodige code laden en oude WebViews (Android 5.0) de nodige ondersteuning krijgen.

Veelgestelde vragen

Zijn polyfills nodig voor React Native?

React Native op Hermes vereist polyfills voor sommige ES-methoden: Array.flat, Array.flatMap, globalThis, TextEncoder. Het wordt aanbevolen om core-js of react-native-polyfill-globals te koppelen voor productiebuilds. JavaScriptCore op iOS ondersteunt meer functies, maar kan ook polyfills nodig hebben voor stage-3 voorstellen.

Beïnvloeden polyfills de prestaties?

Polyfills verminderen de prestaties met 1–5%, omdat de JavaScript-implementatie langzamer is dan de native C++-implementatie in de engine. Bijvoorbeeld, een polyfill voor Promise in puur JS is langzamer dan native Promise in V8. Voor de meeste applicaties is het verschil echter onmerkbaar. Voor kritieke code wordt aanbevolen de aanwezigheid van een native implementatie te controleren via feature detection.

Wat is het verschil tussen polyfill en transpilatie?

Transpilatie converteert syntaxis: const → var, pijlfuncties → function. Polyfill voegt nieuwe objecten/methoden toe: Promise, Array.includes, fetch. Transpilatie werkt in de buildfase, polyfill wordt geladen in runtime. Beide mechanismen zijn nodig voor volledige ondersteuning van moderne code in oude omgevingen.

Kan men polyfills vermijden in 2026?

Ja, als de doelgroep alleen moderne browsers gebruikt (Chrome 90+, Safari 15+, Firefox 90+). Voor projecten die oude apparaten of zakelijke gebruikers ondersteunen (Internet Explorer 11 wordt nog steeds gebruikt in de overheidssector) zijn polyfills verplicht. Analyseer de browserstatistieken van uw publiek via Google Analytics.

Hoe groot zijn de core-js polyfills?

core-js weegt in de volledige build ~85 KB (gzip). Bij gebruik van useBuiltIns: “usage” in Babel worden alleen de benodigde polyfills gekoppeld, wat de grootte reduceert tot 5–30 KB afhankelijk van de doelbrowsers. Voor moderne browsers (Chrome 100+) is mogelijk geen enkele polyfill nodig.

Samenvatting

  • Polyfill — emulatie van een ontbrekende API in de runtime-omgeving, die compatibiliteit van moderne code met oude omgevingen waarborgt
  • core-js — de standaardbibliotheek voor polyfills voor ES5–ES2025, te integreren met Babel via @babel/preset-env
  • Polyfill.io — service voor dynamisch laden van polyfills op basis van de User-Agent van de browser
  • Transpilatie + polyfills — complete oplossing: Babel converteert syntaxis, core-js voegt ontbrekende API's toe
  • Feature detection — controle op aanwezigheid van native implementatie voordat de polyfill wordt geladen voor prestaties
  • WebView en Hermes vereisen verplichte polyfills voor fetch, Promise en IntersectionObserver in oude versies

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook