Polyfill (polyfill) — kód emulující chybějící funkcionalitu (API, metody, objekty) v prostředích, kde není nativně implementována. Polyfill umožňuje používat moderní možnosti JavaScriptu, CSS nebo Web API ve starých prohlížečích a runtime. Podle MDN Web Docs jsou polyfilly klíčovým nástrojem progresivního vylepšování a zajištění cross-browser kompatibility.
Hlavní body
Polyfill — fragment kódu (obvykle JavaScript) implementující funkcionalitu, kterou prostředí běhu nativně nepodporuje. Termín navrhl Remy Sharp v roce 2009 jako slovní hříčku: Polyfill — analogie tmelu (Polyfilla), který vyplňuje praskliny ve zdi. Polyfill vyplňuje mezery mezi standardem a podporou v konkrétním prohlížeči nebo runtime.
Polyfill nemění existující kód — rozšiřuje prostředí běhu. Pokud prohlížeč nepodporuje Array.prototype.includes, polyfill přidá tuto metodu do prototypu Array před spuštěním hlavního kódu. Polyfilly mohou emulovat nové globální objekty (Promise, Map, Set, Symbol), statické metody (Array.from, Object.assign) a metody prototypů.
Feature detection — povinný mechanismus před instalací polyfillu. Místo kontroly user-agent (jaký prohlížeč) je třeba zkontrolovat existenci metody: if (!Array.prototype.includes) { Array.prototype.includes = ... }. To zaručuje, že polyfill nepřepíše nativní implementaci, pokud již existuje. Google Analytics a další služby sbírají data o podpoře API pro analýzu.
První polyfilly se objevily v éře Internet Exploreru 6–8 (2005–2009), když vývojáři objevili propast mezi standardy W3C a implementací v prohlížečích. Termín zavedl Remy Sharp v roce 2009 na konferenci BarCamp London. Prvním masovým polyfillem byl html5shiv (2009) — knihovna přidávající podporu pro HTML5 tagy (<section>, <article>, <nav>) v Internet Exploreru.
S příchodem ES6 (2015) a ročním cyklem aktualizací ECMAScriptu vzrostl počet potřebných polyfillů. Každý rok standard přidává nové metody (Array.includes, String.padStart, Object.fromEntries, Promise.allSettled), které staré prohlížeče nepodporují. core-js, započatý jako es6-shim v roce 2014, se stal univerzálním řešením. K roku 2026 obsahuje core-js více než 5000 modulů polyfillů pro ES5–ES2025.
| Kategorie | Lze polyfillovat | Nelze polyfillovat |
|---|---|---|
| Metody prototypů | Array.includes, String.startsWith | — |
| Globální objekty | Promise, Map, Set, Symbol | — |
| Statické metody | Object.assign, Array.from | — |
| Syntaxe jazyka | — | Arrow functions, async/await, class |
| Web API | fetch, IntersectionObserver | Service Worker (vyžaduje nativní podporu) |
Transpilace převádí novou syntaxi na starou (const → var, () => {} → function() {}). Polyfill přidává chybějící metody a objekty (Promise, Array.includes). Tyto dva mechanismy se doplňují: transpilace zajišťuje syntaktickou kompatibilitu, polyfilly zajišťují úplnost API. Babel + core-js — standardní kombinace pro plnou podporu.
Babel @babel/preset-env s volbou useBuiltIns určuje, které polyfilly jsou potřeba na základě cílových prohlížečů. useBuiltIns: „usage” analyzuje, která API jsou v kódu použita, a připojuje pouze potřebné polyfilly z core-js. useBuiltIns: „entry” připojuje všechny polyfilly pro cílové prohlížeče prostřednictvím jediného importu core-js/stable.
// Kontrola existence a přidání polyfillu
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,
});
}
// Použití — nyní bezpečné v jakémkoli prohlížeči
const arr = [1, 2, 3, 4, 5];
console.log(arr.includes(3)); // truePolyfill pro Array.prototype.includes kontroluje, zda je metoda definována v prototypu Array. Pokud ne — vytváří vlastnost pomocí Object.defineProperty s příznaky writable: true, configurable: true. Implementace následuje specifikaci ES2016: kontrola null/undefined, převod na objekt, práce se záporným fromIndex. Po přidání polyfillu volání arr.includes(3) funguje ve všech prohlížečích včetně Internet Exploreru 11.
core-js — nejúplnější knihovna polyfillů JavaScriptu, podporující všechny stage-4 návrhy TC39 (standard ECMAScript). core-js obsahuje polyfilly pro Promise, Symbol, Map, Set, WeakMap, WeakSet, Array metody, String metody, Object metody, Number metody, Math metody, Reflect, globalThis a všechny stage-4 proposals. Aktuální verze core-js 3.38+ pokrývá ES5–ES2025.
core-js se integruje s Babelem přes @babel/preset-env a volbu useBuiltIns. Bez této integrace by vývojář musel ručně importovat každý polyfill: import „core-js/stable/array/includes”. @babel/preset-env automaticky přidává potřebné importy na základě cílových prohlížečů z .browserslistrc. To zmenšuje velikost bundle — připojují se pouze potřebné polyfilly.
Fetch API — jedno z nejčastěji polyfillovaných Web API. Nativní implementace fetch je dostupná v Chrome 42+ (2015), Safari 10.1+ (2017), Firefox 39+ (2015), ale chybí v Internet Exploreru a starých WebView. Polyfill whatwg-fetch emuluje fetch přes XMLHttpRequest. Alternativa — použijeme isomorphic-fetch (polyfill pro Node.js a prohlížeč) nebo univerzální knihovnu axios, která nevyžaduje polyfilly.
// Načtení polyfillu fetch pouze pro staré prohlížeče
if (typeof self.fetch !== "function") {
import("whatwg-fetch").then(module => {
self.fetch = module.fetch;
console.log("fetch polyfill loaded");
});
}
// Použití fetch (funguje s polyfillem i s nativním 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);
}
}Dynamický import polyfillu fetch přes import() zaručuje, že moderní prohlížeče nenačtou zbytečný kód. Polyfill se načítá asynchronně a neblokuje hlavní vlákno. Po načtení self.fetch nahrazuje nativní implementaci nebo přidává chybějící. To je technika progresivního vylepšování: moderní prohlížeče dostávají pouze nativní kód, staré — další 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 — cílové prohlížeče
> 0.5%
last 2 versions
not dead
not op_mini all
ie >= 11
not ios_saf < 12useBuiltIns: „usage” analyzuje kód a přidává pouze ty polyfilly, které jsou skutečně použity. corejs.version udává verzi core-js v projektu. targets.browsers určuje minimální úroveň prohlížečů — čím starší prohlížeče, tím více polyfillů bude připojeno. .browserslistrc používají nejen Babel, ale také Autoprefixer, PostCSS a Stylelint pro konzistentní cílení.
Polyfill.io — služba (a stejnojmenná knihovna), která dynamicky určuje, které polyfilly prohlížeč uživatele potřebuje, a vrací pouze je. Polyfill.io používá hlavičku User-Agent k určení verze prohlížeče a dodává minimální sadu polyfillů. To snižuje množství přenášených dat ve srovnání s univerzálním balíčkem polyfillů.
Připojení Polyfill.io se provádí pomocí tagu <script> před hlavním kódem aplikace. Služba analyzuje User-Agent a vrací JavaScriptový soubor s polyfilly pouze pro tento prohlížeč. Chrome nezíská žádný polyfill, IE 11 získá plnou sadu. To je optimální přístup pro výkon: moderní prohlížeče nenačítají zbytečný kód.
<!-- Polyfill.io: dynamické načítání -->
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=Promise%2CArray.prototype.includes%2CObject.assign%2Cfetch"></script>
<!-- Lokální verze Polyfill.io -->
<script src="/js/polyfill.js"></script>
<script>
// detekce funkcí pro fetch
if (!self.fetch) {
loadScript("/js/fetch-polyfill.js");
}
</script>Parametr features v URL Polyfill.io určuje, které polyfilly se mají načíst. Možné hodnoty: názvy metod (Array.prototype.includes), globálních objektů (Promise) nebo příznaky (es6, es2016). Příznak „default” připojuje základní sadu pro moderní JavaScript. Pro produkční projekty se doporučuje hostovat Polyfill.io na vlastním CDN nebo použít lokální verzi knihovny pro kontrolu nad dostupností.
WebView v mobilních aplikacích (Android WebView, WKWebView na iOS) — zvláštní prostředí pro polyfilly. Verze WebView závisí na verzi operačního systému a nainstalované aktualizaci Chrome System WebView (Android) nebo WKWebView z iOS Safari. Ve starých verzích Androidu (4.4, 5.0) WebView stojí na Chromiu 30–37 — bez podpory fetch, Promise, IntersectionObserver.
React Native používá JavaScriptCore (iOS) nebo Hermes (Android) — tyto enginy implementují ES6+ odlišně. JavaScriptCore na iOS podporuje většinu funkcí ES6, ale může postrádat některé stage-3 návrhy. Hermes (používaný standardně v React Native 0.70+) podporuje omezenou sadu standardu ES — pro něj jsou polyfilly povinné.
// Detekce funkcí pro WebView
const polyfills = [];
// Promise
if (typeof Promise === "undefined") {
polyfills.push("Promise");
}
// Fetch API
if (typeof self.fetch === "undefined") {
polyfills.push("fetch");
}
// IntersectionObserver (potřebný pro líné načítání)
if (typeof IntersectionObserver === "undefined") {
polyfills.push("IntersectionObserver");
}
// Dynamické načítání polyfillů
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 pro WebView kontroluje existenci kritických API (Promise, fetch, IntersectionObserver) a dynamicky načítá polyfilly pouze pro chybějící. To zaručuje, že moderní WebView (Chrome 100+ na Android 12) nenačítají zbytečný kód a stará WebView (Android 5.0) získávají potřebnou podporu.
Často kladené otázky
React Native na Hermes vyžaduje polyfilly pro některé ES metody: Array.flat, Array.flatMap, globalThis, TextEncoder. Doporučuje se připojit core-js nebo react-native-polyfill-globals pro produkční sestavení. JavaScriptCore na iOS podporuje více funkcí, ale také může vyžadovat polyfilly pro stage-3 návrhy.
Polyfilly snižují výkon o 1–5%, protože implementace v JavaScriptu je pomalejší než nativní C++ implementace v enginu. Například polyfill Promise v čistém JS je pomalejší než nativní Promise ve V8. Pro většinu aplikací je však rozdíl nepostřehnutelný. Pro kritický kód se doporučuje kontrolovat existenci nativní implementace pomocí feature detection.
Transpilace převádí syntaxi: const → var, arrow funkce → function. Polyfill přidává nové objekty/metody: Promise, Array.includes, fetch. Transpilace funguje ve fázi sestavení, polyfill se načítá v runtime. Oba mechanismy jsou nezbytné pro plnou podporu moderního kódu ve starých prostředích.
Lze, pokud cílová skupina používá pouze moderní prohlížeče (Chrome 90+, Safari 15+, Firefox 90+). Pro projekty podporující stará zařízení nebo firemní uživatele (Internet Explorer 11 se stále používá ve státním sektoru) jsou polyfilly povinné. Analyzujte statistiky prohlížečů svého publika prostřednictvím Google Analytics.
core-js v plném sestavení váží ~85 KB (gzip). Při použití useBuiltIns: „usage” v Babel se připojují pouze potřebné polyfilly, což zmenšuje velikost na 5–30 KB v závislosti na cílových prohlížečích. Pro moderní prohlížeče (Chrome 100+) nemusí být vyžadován žádný polyfill.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také