HTML, CSS & the Browser

Polyfill

Definition

A polyfill checks whether the native thing exists and, when it does not, defines it under the same name with the same behaviour. After that your own code calls the standard method and never knows the difference. The familiar ones are fetch for old browsers, Promise, Array.prototype.includes, IntersectionObserver and smooth scrolling. There is a limit: a polyfill can only recreate what JavaScript can reach, so you can patch in a missing method but you cannot patch in a CSS property the rendering engine does not implement, which is where a fallback rule takes over instead. A shim is the neighbouring word, used for code that smooths over differences rather than implementing a standard exactly.

Why It Matters

Loading polyfills nobody needs is the commonest way a small page turns heavy. A blanket bundle covering everything can add 40 to 80 kilobytes that every modern browser downloads, parses and throws away, and that shows up directly in page speed. Loading them behind a test costs nothing at all to the browsers that already have the feature. The opposite mistake is worse in kind rather than degree: skipping one you genuinely need produces a hard failure, since an undefined method throws, the script stops, and everything below it on the page never gets built.

How It Works

The test comes first and it is usually one line: if (!window.Promise), or if (!('scrollBehavior' in document.documentElement.style)). When the test fails the polyfill is loaded and defines the missing name on the global object or on a prototype. Load order matters, because the patch has to finish before any code that depends on it, which is why polyfills tend to be plain blocking script tags in the head rather than deferred ones. A hosted service reads the User-Agent and sends only what that browser lacks, though pinning any third-party script to a self-hosted copy, or guarding it with subresource integrity, is safer than trusting a remote file you do not control. Once the native feature ships everywhere your visitors actually are, the polyfill is dead weight and should come out.

Real-World Example

An interactive report at annual-figures.99helpers.site uses IntersectionObserver to fade its charts in on scroll, and on a five-year-old tablet nothing appears at all. The console names the method as undefined. A three-kilobyte polyfill loaded behind a feature test restores the behaviour on that device and adds nothing for anyone else. Published on 99helpers as two files, the change is one upload.

Common Mistakes

  • Shipping a catch-all polyfill bundle to every visitor — most of them already have every feature in it and pay the download regardless
  • Loading a polyfill with defer and calling the feature from an earlier script — the patch arrives after the code that needed it
  • Trying to polyfill CSS — script can imitate some layout behaviour, but a rendering feature the engine lacks needs a fallback rule, not a shim

Related Terms

Put a file online in seconds

Drop in a document, an image, a page or a whole static website and share the link — free, with no build step and no server to set up.

Host a file free →