Every year, developers from all around the world get together to take a look at what the future of technology holds for them: Google I/O, annual May conference about all things digital, technical, and more. While a huge portion of keynotes and talks is dedicated to Google’s products (e.g. Google Pixel, Android, Google Home, Google Assistant, Google Search), Mathias Bynens and Sathya Gunasekaran reveal what new JavaScript features the team will ship.
With Google Chrome being a staple of modern web development, watching the team’s presentation allows us to peek into the latest JavaScript features — and how it can change in the future. In this article, we’ll detail every new JavaScript feature that the Chrome team discussed in their keynote — brand new JavaScript development techniques that help modern web apps come to life.
The bigger picture: JavaScript, Node.js, and V8 engine
JavaScript has come a long way from a simple web-only scripting language to an indispensable tool of modern software and web development: web apps in the browser, servers and command-line tools via Node.js, cross-platform desktop apps via Electron, cross-platform mobile apps via React Native — and this reinforces the “JavaScript is everywhere” motto. JavaScript developers are incredibly in-demand — now is the best time to prepare for your next JavaScript interview! (Interview questions part 1 and part 2)
By extension, technologies like Node.js and Chrome V8 engine are heavily influenced by the way JavaScript is developed: Node.js is a JavaScript run-time environment which finally freed web developers from limiting sandboxed environments (e.g. Java).
The V8 engine is Google’s backbone of JavaScript: it compiles, executes, and manages JS code in browsers like Chrome and its Chromium-based siblings: Opera and revamped Microsoft Edge. In essence, V8 engine powers JavaScript and enables it to do things that would be considered as “magic” just 30 years ago when the Web started. The teams at Google are constantly improving the engine’s performance — and this is what they have to show:
V8 engine improvements
As the engine is tasked with ensuring that the given web app doesn’t load slower than the operating system itself, making improvements to it is crucial. Here’s what current Chrome, version 74, has to offer:
- 2x raw JavaScript parsing speed on real-world websites compared to Chrome 61, which was released in September 2017.
- The main thread has been lifted out of heavy parsing and compilation work to improve website startup: it has been decreased by 40%.
- Memory consumption on Android Go devices decreased by 20% compared to Chrome 70, released in October 2018.
- In Node.js (comparing version 7 with version 12), promises have gotten 11 times faster.
Class field changes
These changes allow the developer to make class definition simpler — now, constructors are not required to define fields. Using ES2015 class syntax, we can write this code:
class IncreasingCounter { constructor() { this._count = 0; } get value() { console.log("Getting the current value..."); return this._count; } increment() { this._count++; } }
And the new version with updated public class fields looks like this:
class IncreasingCounter { _count = 0; get value() { console.log("Getting the current value..."); return this._count; } increment() { this._count++; } }
If we want to prevent direct access to the “count” property, we can add the ‘#’ symbol to its name — that way, they wouldn’t be accessible from outside the class body, resulting in SyntaxError when accessed.
Supported by: Chrome and Node.js.
Array#flat and flatMap
These new features, as their names suggest, operate with arrays and maps. Array#flat allows creating a flattened version of an array. In the example below, the two-level array is flattened by one via calling the flat() function. The function can flatten the given array any number of times and even keep on flattening until the array contains no more nested arrays when we call array.flat(Infinity).
// Flatten one level: const array = [1, [2, [3]]]; array.flat(); // results in [1, 2, [3]] array.flat(Infinity); // results in [1, 2, 3]
To improve performance, the flatMap method can be used to flatten an array:
[2, 3, 4] .map(duplicate).flat(); // less efficient [2, 3, 4] .flatMap(duplicate); // more efficient
These features are already available in Chrome, Firefox, Safari, and Node.js.
Intl APIs and locale-specific features
Sometimes, the website data needs to be localized so as to be more accessible to non-English speakers: this need is echoed by the latest study conducted by Airbnb: The online population continues to grow at a rate of nearly 1M per day, and only 9 out of 100 newcomers use, speak, or write in English.
The localization process usually includes formatting dates and numbers or providing plural form selection — this usually means sending a lot of locale data to the user which may hinder website performance.
With Intl APIs, however, we can avoid causing this unnecessary load. A good example can be found in using phrases like “5 minutes ago”, “yesterday”, “last week”, “next quarter” to denote a point in time, instead of using precise timestamps or full dates — and the Intl.RelativeTimeFormat API can do exactly that. Thanks to this new API, the browser ships the data without increasing the project bundle size.
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' }); rtf.format(-1, 'day'); // results in "yesterday" rtf.format(0, 'day'); // results in "today" rtf.format(1, 'day'); // results in "tomorrow" rtf.format(-1, 'week'); // results in "last week" rtf.format(0, 'week'); // results in "this week" rtf.format(1, 'week'); // results in "next week"
Available in: Chrome, Firefox, and Node.js.
BigInt improvement
BigInt(), as the name suggests, allows for precise calculations involving large integers. It’s characterized by the “n” symbol appended to the end of a number, e.g. 6n. When should it be used? As the Number primitive can only reliably represent whole numbers up to 253, BigInt comes into play when bigger numbers are concerned:
1234567890123456789 * 123; // results in 151851850485185200000, but a bunch of zeros at // the end give away the fact that the result is wrong 1234567890123456789n * 123n; // returns the correct result which is 151851850485185185047n
BigInt’s update is related to improved language-wide API support: as showcased by the Google team, BigInt can now be formatted via the “toLocaleString” method — and it will support local-aware formatting style. A good example is grouping the digits per thousand: “1,000” in English, “1.000” in German, or “1 000” in French.
To make formatting multiple numbers/BigInts more efficient, you can use the Intl.NumberFormat API — this will allow you to create a single formatter instance and reuse it over and over:
1234567890123456789n.toLocaleString(‘en’); // slower, // results in 12,345,678,901,234,567,890 const nf = new Intl.NumberFormat(‘en”); nf.format(1234567890123456789n); // faster with the same result
Shipping in: Firefox Nightly, Node.js, sometime later in Safari (shipped in Chrome last year)
Separators in numeric literals
Other features that the Chrome team introduced improve readability and maintainability: a good example is the new separator feature. Parsing numbers with many repeating digits is unnecessarily complicated — so now JavaScript will support underscore (“_”) separators that group the digits by thousands. Introduced back in 2018, this feature finally gets full support.
// before 10000000000 // now 10_000_000_000
Shipping in: Chrome 75, also supported by transpilers (e.g. Babel)
Conclusion
Since its first installment back in 2008, Google I/O has been a great source of the latest web development trends. Although some products are, unfortunately, headed for Google Cemetery, we’ll see some awesome new features and tools that make web development exciting. For more coverage of events like Google I/O… well, you know what to do with that form below. 🙂