The ECMAScript Internationalization API Specification (ECMA-402, or
Intl) provides key locale-specific functionality such as date formatting, number formatting, plural form selection, and collation. The Chrome V8 and Google Internationalization teams have been collaborating on adding features to V8’s ECMA-402 implementation, while cleaning up technical debt and improving performance and interoperability with other browsers.
Underlying architectural improvements #
V8 uses specialized
Sets, etc). With this approach, V8 can pre-allocate the required number of internal slots and generate fast accesses to these, rather than grow the object one property at a time leading to slower performance and worse memory usage.
DateTimeFormat) were generic
JSObjects that had to transition through several property additions for their internal slots.
Another artifact of not having a specialized
JSObjects was that type checking was now more complex. The type information was stored under a private symbol and type-checked on both the JS and C++ side using expensive property access, rather than just looking up its shape.
Modernizing the codebase #
With the current move away from writing self-hosted builtins in V8, it made sense to use this opportunity to modernize the ECMA402 implementation.
Moving away from self-hosted JS #
By rewriting the builtins in C++, it became much faster to access the ICU APIs as there is no runtime call overhead now.
Improving ICU #
Intl to ICU in V8’s implementation, we found and fixed several ICU bugs.
Intl APIs based on our ICU work.
As a result of this work, we improved the performance of the Internationalization API by optimizing several fast paths and caching the initialization of the various
Intl objects and the
toLocaleString methods on
For example, creating a new
Intl.NumberFormat object became around 24× faster.
Note that for better performance, it’s recommended to explicitly create and reuse an
Intl.Collator object, rather than calling methods like
Intl features #
All of this work has provided a great foundation to build new features on and we’re continuing to ship all the new Internationalization proposals that are in Stage 3.
Intl.RelativeTimeFormat has shipped in Chrome 71,
Intl.ListFormat has shipped in Chrome 72,
Intl.Locale has shipped in Chrome 74, and
timeStyle options for
Intl.DateTimeFormat and BigInt support for
Intl.DateTimeFormat are shipping in Chrome 76.
Intl.Segmenter, and additional options for
Intl.NumberFormat are currently under development in V8, and we hope to ship them soon!
Many of these new APIs, and others further down the pipeline, are due to our work on standardizing new features to help developers with internationalization.
Intl.DisplayNames is a Stage 1 proposal that allows users to localize the display names of language, region or script display names.
Intl.DateTimeFormat#formatRange is a Stage 3 proposal that specifies a way to format date ranges in a concise and locale-aware manner. The unified
Intl.NumberFormat API proposal is a Stage 3 proposal that improves
Intl.NumberFormat by adding support for measurement units, currency and sign display policies, and scientific and compact notation. You can get involved in the future of ECMA-402 as well, by contributing at its GitHub repository.
Intl provides a feature-rich API for several operations needed in internationalizing your web app, leaving the heavy lifting to the browser, without shipping as much data or code over the wire. Thinking through the proper use of these APIs can lead your UI to work better in different locales. Due to the work by the Google V8 and i18n teams in collaboration with TC39 and its ECMA-402 subgroup, you can now access more functionality with better performance, and expect further improvements over time.