Slide 1

Slide 1 text

Proprietary + Confidential 2022 Polyfilling the Web Forward addyosmani@

Slide 2

Slide 2 text

Proprietary + Confidential The modern web is composed of layers.

Slide 3

Slide 3 text

Proprietary + Confidential The Platform Foundation Applications

Slide 4

Slide 4 text

Proprietary + Confidential Hardware (CPU, GPU, RAM) and Network Operating System The Platform Foundation Applications

Slide 5

Slide 5 text

Proprietary + Confidential Hardware (CPU, GPU, RAM) and Network Operating System Web Browsers Polyfills / Transforms The Platform Foundation Applications

Slide 6

Slide 6 text

Proprietary + Confidential Hardware (CPU, GPU, RAM) and Network Operating System JavaScript Frameworks & Tools Components The Platform Foundation Applications Infrastructure Web Browsers Polyfills / Transforms

Slide 7

Slide 7 text

Google | Confidential & Proprietary Definition A polyfill is a piece of JavaScript code that is intended to exactly simulate a native, interoperable feature of the web platform, for the purpose of allowing website developers to use modern web features in older browsers. Polyfilling the web forward

Slide 8

Slide 8 text

Google | Confidential & Proprietary Definition A transpiler takes the syntax that older browsers won’t understand (e.g. classes, ‘const’, arrow functions), and transforms them into syntax they will understand (functions, ‘var’, functions). Polyfilling the web forward

Slide 9

Slide 9 text

Polyfills & Transforms come in many flavors Web APIs Web Animations API Clipboard API ResizeObserver Custom Elements ShadowDOM CSS Container Queries CSS Scoping Paint Worklet Custom Properties Focus Visible JavaScript / ECMAScript Decorators Top level await Optional Chaining Nullish Coalescing Pipeline operator Private methods

Slide 10

Slide 10 text

Web: ResizeObserver Polyfill \ import ResizeObserver from 'resize-observer-polyfill'; const ro = new ResizeObserver((entries, observer) => { for (const entry of entries) { const {left, top, width, height} = entry.contentRect; console.log('Element:', entry.target); console.log(`Element's size: ${ width }px x ${ height }px`); console.log(`Element's paddings: ${ top }px ; ${ left }px`); } }); ro.observe(document.body);

Slide 11

Slide 11 text

CSS: Container Queries Polyfill \ const supportsContainerQueries = "container" in document.documentElement.style; if (!supportsContainerQueries) { import("container-query-polyfill"); } // … @container (min-width: 200px) { /* ... */ }

Slide 12

Slide 12 text

ECMAScript Transform: Nullish Coalescing \ // before running the transpiler height = height ?? 100; // after running the transpiler height = (height !== undefined && height !== null) ? height : 100;

Slide 13

Slide 13 text

Tl;dr: Polyfills are an important layer. Polyfills / Transforms

Slide 14

Slide 14 text

standards write design doc create launch bug begin implementing roll out to canary/dev request beta approval request stable approval enable by default identify + understand design write it down ship standard intent to implement enable by default intent to ship if web-facing if failed intent to deprecate intent to remove remove adoption check-in landed web platform launch chrome launch web platform removal first TAG check-in external blink contributors old/existing features (2nd impl ships) final TAG sign-off grow + iterate intent to experiment if need to experiment chromium intent to implement Life of a browser feature

Slide 15

Slide 15 text

Google | Confidential & Proprietary Polyfilling the Web forward Guiding principles for Web features Discuss & Design Idea discussion and Incubation. The first step is identifying a specific need, or use case. An Explainer may be written at this phase. Implement First native implementations (as trial/behind flag). Specification should be iterated on. Web Platform Tests. Interop Multiple interoperable implementations across browsers. Universal support Stable support for the feature across all major browsers and platforms. Polyfills bridge this gap

Slide 16

Slide 16 text

Privileged & Confidential Who are polyfill stakeholders? ● Polyfill authors? ○ Browser engineers ○ Web developers ○ Framework authors ○ Web infrastructure ○ Community ● Website developers ● Library and framework authors ● Polyfill distributors (eg. polyfill.io) ● Spec editors

Slide 17

Slide 17 text

Privileged & Confidential Guidance for browser engineers ● If you are developing a new feature for the web, polyfills can be hugely beneficial in helping to roll out that feature. ● Don't be constrained by what is 'polyfillable' [discuss?] ● Make your feature easily detectable ● Work with polyfill authors Polyfills and the evolution of the Web Platform

Slide 18

Slide 18 text

Proprietary + Confidential Polyfills are often more complex than we might guess.

Slide 19

Slide 19 text

BigInt // arbitrary-precision integers \ 1234567890123456789 * 123; // → 151851850485185200000 ❌ 1234567890123456789n * 123n; // → 151851850485185185047n ✅ // Originally, BigInt was only supported in Chrome. // Hard to transpile to ES5 with Babel et al. Changes behavior of operators (like +, >= etc).

Slide 20

Slide 20 text

JSBI for BigInt \ import JSBI from './jsbi.mjs'; const max = JSBI.BigInt(Number.MAX_SAFE_INTEGER); const two = JSBI.BigInt('2'); const result = JSBI.add(max, two); console.log(result.toString()); // → '9007199254740993'

Slide 21

Slide 21 text

Privileged & Confidential Can everything be polyfilled? No. ● Transpilers and polyfills can’t do everything. ● A good general rule is this: ○ If it’s new syntax, you can probably transpile it ○ If it’s a new object or method, you can probably polyfill it ○ If it’s something clever that the browser does outside of your code, you may be out of luck.

Slide 22

Slide 22 text

Privileged & Confidential Don’t serve unnecessary polyfills ● It is generally better to optimize for modern browsers, so performing efficient client-side feature detection and waiting for an extra script to load on older browsers is usually a good trade off. However, if the full set of polyfills you might need in the worst case constitutes a negligible overhead, then you could choose to serve the full set to all browsers. ● Polyfill authors may choose to throw a warning if a polyfill is loaded when not needed, though care should be taken not to create unnecessary noise. If unnecessarily loading a particular polyfill creates a significant performance or security concern, a warning is appropriate.

Slide 23

Slide 23 text

Promises - in many browsers since 2014

Slide 24

Slide 24 text

Promises - still being polyfilled in 2022

Slide 25

Slide 25 text

One of many features still being polyfilled

Slide 26

Slide 26 text

Privileged & Confidential Loading polyfills as needed ● polyfill.io is a service that inspects the browser’s User-Agent and serves a script with polyfills targeted specifically at that browser. ○ The polyfill.io script will add 50-300 ms to your Time to Interactive. The script is (obviously) hosted on a server different from yours, and loading stuff from a different server is costly. The browser will have to spend extra 50-300 ms to setup a connection to the server, and this means adding 50-300 ms to your Time to Interactive. ● module/nomodule is a pattern when you serve scripts for modern browsers with , and scripts for older browsers with <script nomodule>: ○ This pattern relies on the fact that old browsers – ones that don’t support ES2015 – will not load type="module" scripts – and will load nomodule ones. Which means you can use nomodule to serve ES2015 polyfills exactly to browsers that need them! ● @babel/preset-env has an option called useBuiltIns. With this option, you can make Babel cherry-pick polyfills for specific browsers

Slide 27

Slide 27 text

module/nomodule \

Slide 28

Slide 28 text

Risks of premature polyfilling ● Early, speculative polyfills help shape the standards process. However, any JavaScript library that defines a property of the global object or extends a prototype of a global constructor using a proposed or generically useful name, risks creating problems for the development of the Web if that library becomes widely used, prior to the standardization and implementation of the feature it seeks to create or emulate. ● EXAMPLE: Mootools Array.prototype.contains => .includes ○ The standardization of Array.prototype.contains in JavaScript ran into problems. ● Polyfill authors can avoid these problems if their version of the feature can be used under a custom name, regardless of the existence of any native implementation of the same or similar feature under a different name.

Slide 29

Slide 29 text

Things that are hard to get right: performance ● The runtime nature of more complex polyfills can sometimes mean their performance in browsers is significantly different to browsers that natively support a feature, so this is always worth keeping an eye on. ● Historically, developers used solutions like Modernizr and Yepnope to conditionally load polyfills in supported browsers, while in modern times developers often take a lighter weight approach to checking (or defer to configuration steps like present-env and conditional polyfill loading to handle such checks for them). ● As the number of web platform features increases, the amount of polyfill code required to make website developers' application code run in older browsers may become extremely large - in some cases exceeding the size of the application code that depends on it. This has implications for performance, both in terms of parsing the polyfill code, and the time required to download it. ● Consideration should be given to whether excessively large polyfill bundles place a punitive cost burden on users with the least ability to pay that cost: those with older devices which may be on metered connections paying for data in very small increments.

Slide 30

Slide 30 text

ShadowDOM polyfill vs ShadyDOM

Slide 31

Slide 31 text

Look for signs of quality in polyfills, such as: ● Comprehensive test suite, especially if it includes relevant Web Platform Tests ● Effects on the performance profile of your site, measured using in-browser profiling tools or other auditing or monitoring tools or services Additional recommendations for polyfill authors Understand stability Some features are not worth polyfilling. Instead, consider: ● Progressive enhancement ● Transpilation (eg. Babel) ● Lo-fi mode (aka. "Basic" mode, "m." etc) Consider the least capable devices

Slide 32

Slide 32 text

Proprietary + Confidential There is a lot that library authors can keep in mind.

Slide 33

Slide 33 text

Guidance for library authors on shipping polyfills yourself ● In deciding whether to ship polyfill-like code inside your library, you should consider questions such as: ○ How much of the feature are you using? If you want a large feature but your use of it could be emulated in naive 10-line implementation, then it's better to do that than to bundle a spec-compliant polyfill. ○ How large is the polyfill code relative to your library code? If it's a tiny polyfill (such as for a Number.isNaN implementation) then the overheads are negligible and not worth any concern. However, in some cases a polyfill might exceed the size of the library. ○ Are there multiple polyfills available? If developers have a choice of polyfills for this feature, you may want to choose the one that works best with your library. If there's only one canonical option, it's easier to assume that the developer will use it. ○ Does your library provide a good experience only when the feature is available natively? If a polyfill allows your library to work but in an unacceptably slow or buggy way, it probably should not ship as part of the library. Polyfills and the evolution of the Web Platform

Slide 34

Slide 34 text

Proprietary + Confidential Discuss

Slide 35

Slide 35 text

Privileged & Confidential Further reading ● “What is a Polyfill?” by Remy Sharp ● Polyfills and the evolution of the Web Platform was influential. ● Polyfills are a part of the web ● Inspiration for the term replica: The Eiffel Tower in Las Vegas ● Useful clarification of “polyfill” and related terms: “Polyfills and the evolution of the Web”. Edited by Andrew Betts. ● Polyfills, shims and Ponyfills