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 определяет, какие полифиллы нужны на основе target-браузеров. useBuiltIns: "usage" анализирует, какие API используются в коде, и подключает только нужные полифиллы из core-js. useBuiltIns: "entry" подключает все полифиллы для target-браузеров через единый импорт 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 автоматически добавляет необходимые импорты на основе target-браузеров из .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 заменяет нативную реализацию или добавляет отсутствующую. Это техника прогрессивного enhancement: современные браузеры получают только нативный код, старые — дополнительный полифилл.

Интеграция 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>
  // feature detection для fetch
  if (!self.fetch) {
    loadScript("/js/fetch-polyfill.js");
  }
</script>

Параметр features в URL Polyfill.io указывает, какие полифиллы загружать. Возможные значения: названия методов (Array.prototype.includes), глобальных объектов (Promise), или флаги (es6, es2016). Флаг "default" подключает базовый набор для современного JavaScript. Для production-проектов рекомендуется размещать 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
// feature detection для 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 году?

Можно, если target-аудитория использует только современные браузеры (Chrome 90+, Safari 15+, Firefox 90+). Для проектов с поддержкой старых устройств или корпоративных пользователей (Internet Explorer 11 всё ещё используется в госсекторе) полифиллы обязательны. Анализируйте статистику браузеров вашей аудитории через Google Analytics.

Какой размер полифиллов core-js?

core-js в полной сборке весит ~85 КБ (gzip). При использовании useBuiltIns: "usage" в Babel подключаются только нужные полифиллы, что уменьшает размер до 5–30 КБ в зависимости от target-браузеров. Для современных браузеров (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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также