Polyfill: vad det är, funktionsprincip och bibliotek för API-emulering

Författare: IT Sectr Publicerad: 2026-05-19 Lästid: 9 min

Polyfill (polyfill) — kod som emulerar saknad funktionalitet (API, metoder, objekt) i miljöer där den inte är implementerad inbyggt. Polyfill gör det möjligt att använda moderna JavaScript-, CSS- eller Web API-funktioner i gamla webbläsare och körningsmiljöer. Enligt MDN Web Docs är polyfills ett nyckelverktyg för progressiv förbättring och säkerställande av cross-browser-kompatibilitet.

Huvudpunkter

  • Polyfill — programvaruemulering av ett saknat API i körningsmiljön där detta API inte är implementerat
  • core-js — standardbiblioteket för polyfills för modern JavaScript med stöd för alla stage-4-förslag
  • Polyfill.io — tjänst som dynamiskt levererar polyfills endast för användarens webbläsare
  • Transpilering vs polyfill: transpilering konverterar syntax (arrow function → function), polyfill lägger till nya metoder (Array.includes, Promise)
  • Feature detection — kontroll av förekomsten av inbyggd implementering innan polyfillen laddas för att undvika konflikter

Vad är Polyfill?

Polyfill — en kodbit (vanligtvis JavaScript) som implementerar funktionalitet som körningsmiljön inte stöder inbyggt. Termen föreslogs av Remy Sharp 2009 som en ordlek: Polyfill — en analogi till spackel (Polyfilla) som fyller sprickor i väggen. Polyfill fyller luckorna mellan standarden och stödet i en specifik webbläsare eller körningsmiljö.

Polyfill ändrar inte befintlig kod — den utökar körningsmiljön. Om webbläsaren inte stöder Array.prototype.includes lägger polyfillen till denna metod i prototypen Array innan huvudkoden körs. Polyfills kan emulera nya globala objekt (Promise, Map, Set, Symbol), statiska metoder (Array.from, Object.assign) och prototypmetoder.

Feature detection — obligatorisk mekanism innan installation av polyfill. Istället för att kontrollera user-agent (vilken webbläsare) bör man kontrollera metodens förekomst: if (!Array.prototype.includes) { Array.prototype.includes = ... }. Detta garanterar att polyfillen inte skriver över den inbyggda implementeringen om den redan finns. Google Analytics och andra tjänster samlar in data om API-stöd för analys.

När uppstod polyfills?

De första polyfillsen uppstod under Internet Explorer 6–8-eran (2005–2009), när utvecklare upptäckte klyftan mellan W3C-standarder och implementering i webbläsare. Termen introducerades av Remy Sharp 2009 på konferensen BarCamp London. Den första massiva polyfillen var html5shiv (2009) — ett bibliotek som lade till stöd för HTML5-taggar (<section>, <article>, <nav>) i Internet Explorer.

Med tillkomsten av ES6 (2015) och ECMAScripts årliga uppdateringscykel ökade antalet nödvändiga polyfills. Varje år lägger standarden till nya metoder (Array.includes, String.padStart, Object.fromEntries, Promise.allSettled) som inte stöds av gamla webbläsare. core-js, som startade som es6-shim 2014, blev den universella lösningen. År 2026 innehåller core-js över 5000 polyfillmoduler för ES5–ES2025.

Vad kan och kan inte polyfillas

KategoriKan polyfillasKan inte polyfillas
PrototypmetoderArray.includes, String.startsWith
Globala objektPromise, Map, Set, Symbol
Statiska metoderObject.assign, Array.from
SpråksyntaxArrow functions, async/await, class
Web APIfetch, IntersectionObserverService Worker (kräver inbyggt stöd)

Polyfill vs transpilering: skillnader och interaktion

Transpilering konverterar ny syntax till gammal (const → var, () => {} → function() {}). Polyfill lägger till saknade metoder och objekt (Promise, Array.includes). Dessa två mekanismer kompletterar varandra: transpilering säkerställer syntaktisk kompatibilitet, polyfills säkerställer fullständighet av API. Babel + core-js — standardkombinationen för fullt stöd.

Babel @babel/preset-env med alternativet useBuiltIns bestämmer vilka polyfills som behövs baserat på målwebbläsare. useBuiltIns: “usage” analyserar vilka API:er som används i koden och ansluter endast nödvändiga polyfills från core-js. useBuiltIns: “entry” ansluter alla polyfills för målwebbläsare via en enda import av core-js/stable.

Exempel: polyfill för Array.prototype.includes

js
// Kontrollera förekomst och lägg till 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,
  });
}

// Användning — nu säker i vilken webbläsare som helst
const arr = [1, 2, 3, 4, 5];
console.log(arr.includes(3)); // true

Polyfillen för Array.prototype.includes kontrollerar om metoden är definierad i prototypen Array. Om inte — skapar en egenskap via Object.defineProperty med flaggorna writable: true, configurable: true. Implementeringen följer ES2016-specifikationen: null/undefined-kontroll, konvertering till objekt, arbete med negativ fromIndex. Efter att polyfillen lagts till fungerar anropet arr.includes(3) i alla webbläsare, inklusive Internet Explorer 11.

core-js: standardbiblioteket för polyfills

core-js — det mest kompletta polyfillbiblioteket för JavaScript, som stöder alla stage-4-förslag från TC39 (ECMAScript-standarden). core-js innehåller polyfills för Promise, Symbol, Map, Set, WeakMap, WeakSet, Array-metoder, String-metoder, Object-metoder, Number-metoder, Math-metoder, Reflect, globalThis och alla stage-4 proposals. Den aktuella versionen core-js 3.38+ täcker ES5–ES2025.

core-js integreras med Babel via @babel/preset-env och alternativet useBuiltIns. Utan denna integration skulle utvecklaren manuellt behöva importera varje polyfill: import “core-js/stable/array/includes”. @babel/preset-env lägger automatiskt till nödvändiga importer baserat på målwebbläsare från .browserslistrc. Detta minskar bundle-storleken — endast nödvändiga polyfills ansluts.

Exempel: polyfill för fetch

Fetch API — ett av de mest polyfillade Web API:erna. Inbyggd implementering av fetch finns i Chrome 42+ (2015), Safari 10.1+ (2017), Firefox 39+ (2015), men saknas i Internet Explorer och gamla WebViews. Polyfillen whatwg-fetch emulerar fetch via XMLHttpRequest. Alternativ — använd isomorphic-fetch (polyfill för Node.js och webbläsare) eller det universella biblioteket axios som inte kräver polyfills.

js
// Ladda fetch-polyfill endast för gamla webbläsare
if (typeof self.fetch !== "function") {
  import("whatwg-fetch").then(module => {
    self.fetch = module.fetch;
    console.log("fetch polyfill loaded");
  });
}

// Använda fetch (fungerar både med polyfill och inbyggt 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);
  }
}

Dynamisk import av fetch-polyfill via import() garanterar att moderna webbläsare inte laddar överflödig kod. Polyfillen laddas asynkront och blockerar inte huvudtråden. Efter laddning ersätter self.fetch den inbyggda implementeringen eller lägger till den saknade. Detta är en teknik för progressiv förbättring: moderna webbläsare får endast inbyggd kod, gamla — extra polyfill.

Integration av core-js med 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 — målwebbläsare
> 0.5%
last 2 versions
not dead
not op_mini all
ie >= 11
not ios_saf < 12

useBuiltIns: “usage” analyserar koden och lägger endast till de polyfills som faktiskt används. corejs.version anger versionen av core-js i projektet. targets.browsers bestämmer miniminivån för webbläsare — ju äldre webbläsare, desto fler polyfills ansluts. .browserslistrc används inte bara av Babel utan även av Autoprefixer, PostCSS och Stylelint för konsekvent målning.

Polyfill.io och dynamisk laddning av polyfills

Polyfill.io — en tjänst (och bibliotek med samma namn) som dynamiskt bestämmer vilka polyfills användarens webbläsare behöver och returnerar endast dessa. Polyfill.io använder User-Agent-huvudet för att bestämma webbläsarversionen och levererar den minimala uppsättningen polyfills. Detta minskar mängden överförda data jämfört med en universell polyfill-bundle.

Anslutning av Polyfill.io görs via en <script>-tagg före applikationens huvudkod. Tjänsten analyserar User-Agent och returnerar en JavaScript-fil med polyfills endast för denna webbläsare. Chrome får ingen polyfill, IE 11 får den fullständiga uppsättningen. Detta är det optimala tillvägagångssättet för prestanda: moderna webbläsare laddar inte överflödig kod.

Ansluta Polyfill.io

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

<!-- Lokal version av Polyfill.io -->
<script src="/js/polyfill.js"></script>
<script>
  // funktionsdetektion för fetch
  if (!self.fetch) {
    loadScript("/js/fetch-polyfill.js");
  }
</script>

Parametern features i URL:en för Polyfill.io anger vilka polyfills som ska laddas. Möjliga värden: metodnamn (Array.prototype.includes), globala objekt (Promise) eller flaggor (es6, es2016). Flaggan “default” ansluter basuppsättningen för modern JavaScript. För produktionsprojekt rekommenderas att vara värd för Polyfill.io på eget CDN eller använda en lokal version av biblioteket för kontroll över tillgängligheten.

Polyfills i mobilapplikationer och WebView

WebView i mobilapplikationer (Android WebView, WKWebView på iOS) — en speciell miljö för polyfills. WebView-versionen beror på operativsystemets version och installerad uppdatering av Chrome System WebView (Android) eller WKWebView från iOS Safari. I gamla Android-versioner (4.4, 5.0) är WebView baserad på Chromium 30–37 — utan stöd för fetch, Promise, IntersectionObserver.

React Native använder JavaScriptCore (iOS) eller Hermes (Android) — dessa motorer implementerar ES6+ på olika sätt. JavaScriptCore på iOS stöder de flesta ES6-funktioner men kan sakna vissa stage-3-förslag. Hermes (används som standard i React Native 0.70+) stöder en begränsad uppsättning av ES-standarden — för den är polyfills obligatoriska.

Kontrollera stöd i WebView

js
// Funktionsdetektion för WebView
const polyfills = [];

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

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

// IntersectionObserver (behövs för lat laddning)
if (typeof IntersectionObserver === "undefined") {
  polyfills.push("IntersectionObserver");
}

// Dynamisk laddning av 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 för WebView kontrollerar förekomsten av kritiska API:er (Promise, fetch, IntersectionObserver) och laddar dynamiskt polyfills endast för de som saknas. Detta garanterar att moderna WebViews (Chrome 100+ på Android 12) inte laddar överflödig kod och gamla WebViews (Android 5.0) får nödvändigt stöd.

Vanliga frågor

Behövs polyfills för React Native?

React Native på Hermes kräver polyfills för vissa ES-metoder: Array.flat, Array.flatMap, globalThis, TextEncoder. Det rekommenderas att ansluta core-js eller react-native-polyfill-globals för produktionsbyggen. JavaScriptCore på iOS stöder fler funktioner men kan också kräva polyfills för stage-3-förslag.

Påverkar polyfills prestandan?

Polyfills minskar prestandan med 1–5%, eftersom JavaScript-implementeringen är långsammare än den inbyggda C++-implementeringen i motorn. Till exempel är polyfill Promise i ren JS långsammare än inbyggt Promise i V8. För de flesta applikationer är skillnaden dock omärkbar. För kritisk kod rekommenderas att kontrollera förekomsten av inbyggd implementering via feature detection.

Vad är skillnaden mellan polyfill och transpilering?

Transpilering konverterar syntax: const → var, pilfunktioner → function. Polyfill lägger till nya objekt/metoder: Promise, Array.includes, fetch. Transpilering fungerar i byggfasen, polyfill laddas vid körning. Båda mekanismerna är nödvändiga för fullt stöd av modern kod i gamla miljöer.

Kan man undvika polyfills år 2026?

Ja, om målpubliken endast använder moderna webbläsare (Chrome 90+, Safari 15+, Firefox 90+). För projekt som stöder gamla enheter eller företagsanvändare (Internet Explorer 11 används fortfarande inom den offentliga sektorn) är polyfills obligatoriska. Analysera din publiks webbläsarstatistik via Google Analytics.

Hur stor är core-js polyfills?

core-js i full byggnad väger ~85 KB (gzip). Vid användning av useBuiltIns: “usage” i Babel ansluts endast nödvändiga polyfills, vilket minskar storleken till 5–30 KB beroende på målwebbläsare. För moderna webbläsare (Chrome 100+) kan ingen polyfill behövas.

Sammanfattning

  • Polyfill — emulering av saknat API i körningsmiljön, vilket säkerställer kompatibilitet för modern kod med gamla miljöer
  • core-js — standardbibliotek för polyfills för ES5–ES2025, integrerbart med Babel via @babel/preset-env
  • Polyfill.io — tjänst för dynamisk laddning av polyfills baserat på webbläsarens User-Agent
  • Transpilering + polyfills — omfattande lösning: Babel konverterar syntax, core-js lägger till saknade API:er
  • Feature detection — kontroll av förekomsten av inbyggd implementering innan polyfill laddas för prestanda
  • WebView och Hermes kräver obligatoriska polyfills för fetch, Promise och IntersectionObserver i gamla versioner

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också