Polyfill: шта је то, принцип рада и библиотеке за емулацију API

Аутор: IT Sectr Објављено: 2026-05-19 Време читања: 9 мин

Polyfill (полифил) — код који емулира недостајућу функционалност (API, методе, објекте) у окружењима где она није имплементирана нативним путем. Polyfill омогућава коришћење савремених могућности JavaScript, CSS или Web API у старим прегледачима и извршним окружењима. Према MDN Web Docs, полифили су кључни алат прогресивног побољшања и обезбеђења унакрсне компатибилности прегледача.

Главно

  • Polyfill — софтверска емулација недостајућег API у извршном окружењу где овај API није имплементиран
  • core-js — стандардна библиотека полифила за савремени JavaScript са подршком за све stage-4 предлоге
  • Polyfill.io — сервис који динамички доставља полифиле само за прегледач корисника
  • Транспилација vs polyfill: транспилација претвара синтаксу (arrow function → function), polyfill додаје нове методе (Array.includes, Promise)
  • Feature detection — провера постојања нативне имплементације пре учитавања полифила ради избегавања конфликата

Шта је Polyfill?

Polyfill — фрагмент кода (обично JavaScript) који имплементира функционалност коју извршно окружење не подржава нативним путем. Термин је предложио Реми Шарп 2009. године као игру речи: Polyfill — аналог кита (Polyfilla) који попуњава пукотине у зиду. Polyfill попуњава празнине између стандарда и подршке у одређеном прегледачу или извршном окружењу.

Polyfill не мења постојећи код — он проширује извршно окружење. Ако прегледач не подржава Array.prototype.includes, полифил додаје ову методу у прототип Array пре извршавања главног кода. Полифили могу да емулирају нове глобалне објекте (Promise, Map, Set, Symbol), статичке методе (Array.from, Object.assign) и методе прототипова.

Feature detection — обавезан механизам пре инсталације полифила. Уместо провере user-agent (који прегледач), треба проверити постојање методе: if (!Array.prototype.includes) { Array.prototype.includes = ... }. Ово гарантује да полифил неће преписивати нативну имплементацију ако већ постоји. Google Analytics и други сервиси прикупљају податке о подршци API ради анализе.

Када су се појавили полифили

Први полифили појавили су се у ери Internet Explorer 6–8 (2005–2009), када су програмери открили јаз између W3C стандарда и имплементације у прегледачима. Термин је увео Реми Шарп 2009. на конференцији BarCamp London. Први масовни полифил био је html5shiv (2009) — библиотека која додаје подршку за HTML5 ознаке (<section>, <article>, <nav>) у Internet Explorer.

Са појавом ES6 (2015) и годишњим циклусом ажурирања ECMAScript, број потребних полифила је порастао. Сваке године стандард додаје нове методе (Array.includes, String.padStart, Object.fromEntries, Promise.allSettled) које стари прегледачи не подржавају. core-js, започет као es6-shim 2014, постао је универзално решење. До 2026. core-js садржи преко 5000 модула полифила за ES5–ES2025.

Шта се може а шта не може полифиловати

КатегоријаМоже се полифиловатиНе може се полифиловати
Методе прототиповаArray.includes, String.startsWith
Глобални објектиPromise, Map, Set, Symbol
Статичке методеObject.assign, Array.from
Синтакса језикаArrow functions, async/await, class
Web APIfetch, IntersectionObserverService Worker (захтева нативну подршку)

Polyfill vs транспилација: разлике и интеракција

Транспилација претвара нову синтаксу у стару (const → var, () => {} → function() {}). Polyfill додаје недостајуће методе и објекте (Promise, Array.includes). Ова два механизма се допуњују: транспилација обезбеђује синтаксну компатибилност, полифили обезбеђују потпуност API. Babel + core-js — стандардна комбинација за потпуну подршку.

Babel @babel/preset-env са опцијом useBuiltIns одређује који полифили су потребни на основу циљних прегледача. useBuiltIns: „usage” анализира који API-и се користе у коду и повезује само потребне полифиле из core-js. useBuiltIns: „entry” повезује све полифиле за циљне прегледаче кроз јединствени import core-js/stable.

Пример: полифил за Array.prototype.includes

js
// Провера постојања и додавање полифила
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,
  });
}

// Коришћење — сада безбедно у било ком прегледачу
const arr = [1, 2, 3, 4, 5];
console.log(arr.includes(3)); // true

Полифил за Array.prototype.includes проверава да ли је метода дефинисана у прототипу Array. Ако није — креира својство кроз Object.defineProperty са заставицама writable: true, configurable: true. Имплементација прати спецификацију ES2016: провера null/undefined, конверзија у објекат, рад са негативним fromIndex. Након додавања полифила, позив arr.includes(3) ради у свим прегледачима, укључујући Internet Explorer 11.

core-js: стандардна библиотека полифила

core-js — најпотпунија библиотека полифила JavaScript, која подржава све stage-4 предлоге TC39 (ECMAScript стандард). core-js садржи полифиле за Promise, Symbol, Map, Set, WeakMap, WeakSet, Array методе, String методе, Object методе, Number методе, Math методе, Reflect, globalThis и све stage-4 proposals. Актуелна верзија core-js 3.38+ покрива ES5–ES2025.

core-js се интегрише са Babel кроз @babel/preset-env и опцију useBuiltIns. Без ове интеграције, програмер би морао ручно да увезе сваки полифил: import „core-js/stable/array/includes”. @babel/preset-env аутоматски додаје потребне импорте на основу циљних прегледача из .browserslistrc. Ово смањује величину пакета — повезују се само потребни полифили.

Пример: полифил за fetch

Fetch API — један од најчешће полифилованих Web API. Нативна имплементација fetch доступна је у Chrome 42+ (2015), Safari 10.1+ (2017), Firefox 39+ (2015), али недостаје у Internet Explorer и старим WebView. Полифил whatwg-fetch емулира fetch кроз XMLHttpRequest. Алтернатива — користимо isomorphic-fetch (полифил за Node.js и прегледач) или универзалну библиотеку axios, која не захтева полифиле.

js
// Учитавање полифила fetch само за старе прегледаче
if (typeof self.fetch !== "function") {
  import("whatwg-fetch").then(module => {
    self.fetch = module.fetch;
    console.log("fetch polyfill loaded");
  });
}

// Коришћење fetch (ради и са полифилом и са нативним 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);
  }
}

Динамички import полифила fetch кроз import() гарантује да савремени прегледачи не учитавају непотребан код. Полифил се учитава асинхроно и не блокира главну нит. Након учитавања, self.fetch замењује нативну имплементацију или додаје недостајућу. Ово је техника прогресивног побољшања: савремени прегледачи добијају само нативни код, стари — додатни полифил.

Интеграција core-js са 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 — циљни прегледачи
> 0.5%
last 2 versions
not dead
not op_mini all
ie >= 11
not ios_saf < 12

useBuiltIns: „usage” анализира код и додаје само оне полифиле који су стварно коришћени. corejs.version указује верзију core-js у пројекту. targets.browsers одређује минимални ниво прегледача — што су прегледачи старији, то ће више полифила бити повезано. .browserslistrc користе не само Babel, већ и Autoprefixer, PostCSS и Stylelint за доследно циљање.

Polyfill.io и динамичко учитавање полифила

Polyfill.io — сервис (и библиотека истог имена) који динамички одређује који полифили су потребни прегледачу корисника и враћа само њих. Polyfill.io користи заглавље User-Agent за одређивање верзије прегледача и испоручује минимални скуп полифила. Ово смањује количину пренетих података у поређењу са универзалним пакетом полифила.

Повезивање Polyfill.io врши се кроз <script> ознаку пре главног кода апликације. Сервис анализира User-Agent и враћа JavaScript датотеку са полифилима само за овај прегледач. Chrome неће добити ниједан полифил, IE 11 ће добити комплетан скуп. Ово је оптималан приступ за перформансе: савремени прегледачи не учитавају непотребан код.

Повезивање Polyfill.io

html
<!-- Polyfill.io: динамичко учитавање -->
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=Promise%2CArray.prototype.includes%2CObject.assign%2Cfetch"></script>

<!-- Локална верзија Polyfill.io -->
<script src="/js/polyfill.js"></script>
<script>
  // detekcija karakteristika за fetch
  if (!self.fetch) {
    loadScript("/js/fetch-polyfill.js");
  }
</script>

Параметар features у URL Polyfill.io одређује који полифили треба да се учитају. Могуће вредности: називи метода (Array.prototype.includes), глобалних објеката (Promise), или заставице (es6, es2016). Заставица „default” повезује основни скуп за савремени JavaScript. За производне пројекте препоручује се хостовање Polyfill.io на сопственом CDN-у или коришћење локалне верзије библиотеке ради контроле доступности.

Полифили у мобилним апликацијама и WebView

WebView у мобилним апликацијама (Android WebView, WKWebView на iOS) — посебно окружење за полифиле. Верзија WebView зависи од верзије оперативног система и инсталираног ажурирања Chrome System WebView (Android) или WKWebView из iOS Safari. У старим верзијама Android (4.4, 5.0) WebView се заснива на Chromium 30–37 — без подршке за fetch, Promise, IntersectionObserver.

React Native користи JavaScriptCore (iOS) или Hermes (Android) — ови мотори имплементирају ES6+ на различите начине. JavaScriptCore на iOS подржава већину ES6 функција, али можда нема неке stage-3 предлоге. Hermes (подразумевано коришћен у React Native 0.70+) подржава ограничен скуп ES стандарда — за њега су полифили обавезни.

Провера подршке у WebView

js
// Функционална детекција за WebView
const polyfills = [];

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

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

// IntersectionObserver (потребан за лењо учитавање)
if (typeof IntersectionObserver === "undefined") {
  polyfills.push("IntersectionObserver");
}

// Динамичко учитавање полифила
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 за WebView проверава постојање критичних API (Promise, fetch, IntersectionObserver) и динамички учитава полифиле само за оне које недостају. Ово гарантује да савремени WebView (Chrome 100+ на Android 12) не учитавају непотребан код, а стари WebView (Android 5.0) добијају неопходну подршку.

Често постављана питања

Да ли су полифили потребни за React Native?

React Native на Hermes захтева полифиле за неке ES методе: Array.flat, Array.flatMap, globalThis, TextEncoder. Препоручује се повезивање core-js или react-native-polyfill-globals за производне верзије. JavaScriptCore на iOS подржава више функција, али такође може захтевати полифиле за stage-3 предлоге.

Да ли полифили утичу на перформансе?

Полифили смањују перформансе за 1–5%, јер је JavaScript имплементација спорија од нативне C++ имплементације у мотору. На пример, полифил Promise у чистом JS је спорији од нативног Promise у V8. Међутим, за већину апликација разлика је неприметна. За критични код препоручује се провера постојања нативне имплементације кроз feature detection.

По чему се полифил разликује од транспилације?

Транспилација претвара синтаксу: const → var, стреличасте функције → function. Полифил додаје нове објекте/методе: Promise, Array.includes, fetch. Транспилација ради у фази изградње, полифил се учитава у runtime. Оба механизма су неопходна за потпуну подршку савременог кода у старим окружењима.

Може ли се избећи коришћење полифила 2026. године?

Може, ако циљна публика користи само савремене прегледаче (Chrome 90+, Safari 15+, Firefox 90+). За пројекте који подржавају старе уређаје или корпоративне кориснике (Internet Explorer 11 се још увек користи у државном сектору) полифили су обавезни. Анализирајте статистику прегледача ваше публике кроз Google Analytics.

Која је величина полифила core-js?

core-js у потпуној изградњи тежи ~85 KB (gzip). При коришћењу useBuiltIns: „usage” у Babel повезују се само потребни полифили, што смањује величину на 5–30 KB у зависности од циљних прегледача. За савремене прегледаче (Chrome 100+) можда неће бити потребан ниједан полифил.

Закључак

  • Polyfill — емулација недостајућег API у извршном окружењу, обезбеђујући компатибилност савременог кода са старим окружењима
  • core-js — стандардна библиотека полифила за ES5–ES2025, интегрисана са Babel кроз @babel/preset-env
  • Polyfill.io — сервис динамичког учитавања полифила на основу User-Agent прегледача
  • Транспилација + полифили — комплексно решење: Babel претвара синтаксу, core-js додаје недостајуће API
  • Feature detection — провера постојања нативне имплементације пре учитавања полифила ради перформанси
  • WebView и Hermes захтевају обавезне полифиле за fetch, Promise и IntersectionObserver у старим верзијама

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође