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 — 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.
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.
| Categorie | Kan worden gepolyfill | Kan niet worden gepolyfill |
|---|---|---|
| Prototype-methoden | Array.includes, String.startsWith | — |
| Globale objecten | Promise, Map, Set, Symbol | — |
| Statische methoden | Object.assign, Array.from | — |
| Taalsyntaxis | — | Arrow functions, async/await, class |
| Web API | fetch, IntersectionObserver | Service Worker (vereist native ondersteuning) |
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.
// 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)); // trueDe 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 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.
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.
// 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.
// 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"],
},
}],
],
};# .browserslistrc — doelbrowsers
> 0.5%
last 2 versions
not dead
not op_mini all
ie >= 11
not ios_saf < 12useBuiltIns: “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 — 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: 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.
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.
// 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
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.
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.
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.
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.
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
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.
Lees ook