 This is Satya. Hey everyone. My name is Matias, and we work on the V8 team at Google V8 is the JavaScript engine and the web assembly engine that's used in Google Chrome and in other embedders such as Node and Electron Other Chromium-based browsers such as Opera and very soon Microsoft Edge also built on top of V8 JavaScript started out as the scripting language of the web and to this day It's still a crucial piece of web technology But today JavaScript's reach extends far beyond just the web to the entire surrounding platform So if we take a step back from V8 and Chrome We can see that JavaScript allows you to create engaging web apps across a wide variety of browsers With Node JavaScript can be used to build command line tools servers and other applications With Electron, JavaScript and other web technologies can be used to build cross-platform desktop apps React Native enables building cross-platform mobile apps JavaScript can even run on low-cost IoT devices nowadays JavaScript is everywhere So as a developer learning JavaScript or improving your JavaScript skills is an excellent time investment At Google you want to enable this enormous JavaScript ecosystem We do so in multiple ways TC39 is the committee that governs the evolution of ECMAScript, which is the standard behind the JavaScript language We actively participate in these standardization efforts together with other browser vendors and industry stakeholders bringing back feedback from us as implementers and from the developer community On top of our participation in the standards process we constantly improve our own JavaScript engine V8 We boost its performance, reduce its memory usage, and we implement new language features as they're being standardized Our mission is to lead real-world performance for modern JavaScript and WebAssembly and to enable developers to build a faster future web You might notice WebAssembly is also implemented in V8 alongside JavaScript Our presentation today focuses just on JavaScript features But this is a separate WebAssembly presentation at IO. If you're interested check out DeepTNCerma's web assembly for web developers talk later today Now let's discuss what we mean when we say real-world performance We've stepped away from synthetic benchmarks where someone sits down and writes code specifically for benchmarking purposes Such code often does not reflect real-world usage And so optimizing for these scenarios as a JavaScript engine has limited impact Instead we now focus on optimizing real websites and JavaScript applications. Let's walk through some example improvements Since Chrome 61 we've doubled our raw JavaScript parsing speed as measured on real-world websites On top of that we've managed to move up to 40% of parsing and compilation work off of the main thread So that it no longer blocks website startup 40% and we're working to increase this percentage even further Our efforts are not just visible in Chrome, but also in Node Overall promises got up to 11 times faster between node 7 and node 12 promise.all in particular got up to 13 times faster To put that in Chrome version numbers. That's Chrome 55 compared to Chrome 74 But performance is not just about parsed speed and runtime performance memory consumption also pays a big role And that's why between Chrome 70 and Chrome 76 We worked to reduce overall memory consumption by 20% as measured on Android Go devices running real-world web apps So we've improved startup performance by boosting JavaScript parsing speed we've improved runtime performance by optimizing async and promises and We've significantly reduced memory consumption along the way and those are just some examples of what we've been working on Wait, is something wrong with our slides? That does look funky, but I think we talked about this last year in a regular expression This would be a look behind. I see so I guess it's time to look back All righty then Exactly one year ago. We were right here at Google I o telling you about lots of exciting new JavaScript features and some of those features were pretty cutting edge They were still being standardized at the time and So unfortunately for many features. We had to say that they weren't yet supported in all modern environments But today one year later feature support looks a lot better In fact, all the features you see here are now fully supported across modern browsers and node You no longer have to polyfill or transpile these features when targeting modern environments That means you can ship smaller JavaScript bundles So your apps load faster and you get those juicy performance improvements as well On top of that some of the other features we talked about have received updates since last year Let's take a look at what's changed starting off with class fields Here's a code example that creates an instance of a class named increasing counter Note that accessing a value execute some code In this case it logs a message before returning the result. Now ask yourself How would you implement this in JavaScript? So here's how increasing counter could be implemented using the familiar ES 2015 class syntax The class installs the value getter and An increment method on the prototype But more interestingly The class as a constructor that creates an instance property underscore count and sets its default value to zero We currently use the underscore prefix to denote that count should not be used directly by the consumers of the class But that's just a convention. The privacy is not enforced by the language Anyway, that's what this class looks like using the old familiar class syntax The new public class fail syntax allows us to simplify the class definition The count property is now nicely declared at the top of the class We no longer need a constructor just to define some fields pretty neat But the count property is still a public property In this particular example, we want to prevent direct access to that property and That's where private fields come in so the new private field syntax is similar to public fields Except you mark the fields as being private by using the hash symbol You can think of the hash as being as part of the field name This is more than just fancy syntax private fields are actually private This means they're not accessible from outside the class body when you try you get a syntax error Class field syntax is especially convenient when dealing with subclasses that introduce additional fields Consider this animal base class for example To create a cat subclass that introduces an additional instance property You previously have to call super to run the constructor of the animal base class Before creating this property. That's a lot of boilerplate just to indicate that cats don't like taking bots Luckily with the class field syntax it removes the need for the whole constructor including the awkward super call All the text at the class field is just that one line Chrome supports both public and private class fields and so does node and More class features are coming soon. We're working on adding support for private methods and private getters and setters Another feature we previewed last year is string match all which is useful when dealing with regular expressions It's common to repeatedly apply the same regular expression on a string to get all the matches and to some extent This is already possible today by using the string match method in this example We find all the words that consist of hexadecimal digits only and then we log each match However, this only gives you the substrings that match Usually you don't just want the substrings You also want additional information such as the index of each substring or the capturing groups within each match And it's already possible to achieve that by writing your own loop and then keeping track of the match objects yourself But it's a little annoying and just not very convenient The new string match all API makes this easier than ever before you can now write a very simple for off loop to get all the match objects String match all is especially useful for regular expressions with capture groups It gives you the full information for each individual match Including the capturing groups the general idea is that you just write a simple for off loop and string match All takes care of everything else for you String match all is already supported in Chrome Firefox and node for other browsers a polyfill is available Last year. We also talked about the numeric separators proposal. Here's a quick recap Large numeric controls are difficult for the human eye to parse quickly Especially when there are lots of repeating digits like in the first example To improve readability a new JavaScript feature enables underscores as separators in numeric literals So instead of writing these numbers like this You can now write them like this grouping the digits per thousand Now it's easier to tell that the first number is in fact a trillion and the second number isn't the order of a billion This small feature helps improve readability for all kinds of numeric literals Last year this feature wasn't supported anywhere yet the deals of the proposal were still being worked out But since then the open issues have been resolved and browsers can now start implementing it and Numeric separators are already shipping in Chrome 75 and transpilers like Babel support them, too Speaking of numbers we have some news about big int as well Here's a quick reminder why big int is useful in this example. We're multiplying two numbers now I'm no mad genius, but this doesn't look right to me Looking at the least significant digits nine and three We know that the result of the multiplication should end in seven because nine times three is 27 But instead the result ends in a bunch of zeros that cannot be the correct results Now let's try this again with big ins instead And this time we do get the correct result big ins make it possible to accurately perform large integer calculations in JavaScript Now what's new compared to last year is that big int now has much better API support within the language For example, you can now format a big int in a locale aware manner by using the two locale string method This now works just like it does for regular numbers in English For example, it's common to use commas to group the digits per thousands in German periods are used instead and in French it's spaces if You plan on supporting multiple numbers or formatting multiple numbers or big ins using the same locale It's more efficient to use the Intel number format API that way You can create a single formatter instance and then just reuse that as many times as you need it this API now supports big ins as well and Of course numeric separators work with big in literals as well This means that you can now both use separators to keep your source code readable and Produce strings with correctly formatted numbers using locale specific separators all in vanilla JavaScript I think that's pretty cool Now last year big ins had just chipped in Chrome and they were not available anywhere else yet But now big ins are shipping in Firefox nightly and in node and an implementation is also underway in Safari On top of that. There's now a transpiler and a polyfill story available for big ins. It's called JS bi Now let's talk about some new exciting features that we've been working on since last year First up is or a flat and flat map Or a flat returns a flattened version of a given or a The or a in this example is two levels deep It contains an array which in turn contains another or a We can call flat to flatten the or a by one level The default depth is one, but you can pass any number to recursively flatten up to that depth To keep flattening recursively until the result contains no more nested arrays. We can pass infinity Here's another example We have a duplicate function that takes a value and returns an array that contains the value twice If we apply duplicate to each value in an array, we end up with a nested array You can then call flat to flatten the array But this since this pattern is so common in functional programming There's now a dedicated flat map method for it Flat map is a little bit more efficient compared to doing a map followed by a flat separately Are a flat and flat map or already available in Chrome Firefox Safari and node Another cool new addition to the built-in JavaScript library is object from entries You may have used the object entries API before that one has been around for a while For each key value pair in an object It gives you an array where the first element is the key and the second element is the value and This is especially useful in combination with for off because you can then very elegantly iterate over all the key value pairs in an object Now unfortunately, there's no easy way to go from the entries result back to an equivalent object until now The new object from entries API performs the inverse of object entries This makes it really easy to reconstruct an object based on its entries. Now. Why is this useful? Well one common use case is transforming objects You can now do this by iterating over the objects entries and then using array methods that you are probably already familiar with In this example, we're filtering the object to only get keys of length one That is we only want the keys x and y but not the key ABC We then map over the remaining entries and return an updated key value pair for each in this example we double the value by multiplying it by two and The end result is a new object containing only the properties x and y with the new values JavaScript also supports maps which are often a more suitable data structure than regular objects So in code that you have full control over you might already be using maps instead of objects However, as a developer you don't always get to choose the representation Sometimes the data that you're operating on comes from an external API or from some library function That gives you an object instead of a map an Object entries made it easy to convert objects into maps But the inverse is equally useful even if your code is using maps You might need to serialize your data at some point for example to turn it into JSON to send an API request or Maybe you need to pass the data to another library that expects an object instead of a map In these cases you need to create an object based on the map data an object from entries makes this trivial With both object entries and object from entries in the language You can now really easily convert between maps and objects both ways Object from entries is already shipping in Chrome Firefox Safari and in node for older browser versions A polyfill is available Another new feature seems like a small one, but it's a big improvement So here's the problem Libraries and polyfills sometimes need access to the global this value To write universal JavaScript that works everywhere Regardless of whether you're in a browser in node or in a JavaScript engine shell directly You need code like this to access the global this in Browsers you can use window Except in web workers or service workers windows not available. So you have to check for self as well In node you can use global instead But in standalone JavaScript shells none of these work See you can try falling back to whatever this object is currently available But outside of browsers that still won't work with it modules since they don't run in the global scope Or in strict mode functions since there this is undefined Also bundlers often wrap source code in which case this might refer to something else entirely You cannot rely on this code being run in the global scope in all cases So even though we're trying really hard for this code snippet It still doesn't support standalone JavaScript engine shells doesn't support modules in all environments It doesn't support strict mode functions in all environments and it might even break in more scenarios when you start bundling it Getting the global this sounds like it would be simple, but it's actually painful to do so in practice and That's why we have a new global this feature that gives you easy access to the global this regardless of the environment Global this is already supported in Chrome Firefox Safari and node Note that most modern code won't need access to the global this With JavaScript modules you can declaratively import and export functionality without messing with global state Global this is still useful for polyfills and other libraries that need global access Stable sort is another one of those changes that sounds like a small improvement, but it actually has a big impact Let's say you have an array of dogs and each dog has a name and the rating if this sounds like a weird example You should know that there's a Twitter account that specializes in exactly that don't ask Anyway, the array is pre-sorted alphabetically by name But what if you want to sort this array by rating so that the highest rated dogs show up first? You would use array sort for this and you would pass in a custom callback that compares the ratings and This is the result that you would probably expect the dogs are now sorted by rating But within each rating. They're still sorted alphabetically by name. They retain their relative original order For example shoko and ghost have the same rating of 14 But shoko appears before ghost in the sort result because that's the order they had in the original array as well To get this result. However, you cannot just use any sorting algorithm It has to be a so-called stable sort and for a long time the JavaScript spec didn't require sort stability for array sort Instead it left it up to the implementation and Because this behavior wasn't specified you could also get this sort result where ghost now suddenly appears before shoko in other words JavaScript developers could not rely on sort stability and in practice it was even more confusing than that Because some JavaScript engines would use a stable sort for short arrays, but an unstable sort for larger arrays That was really confusing because developers would test their code They would see a stable result, but then suddenly get a completely unstable result when the array was slightly bigger But there's some good news we propose the spec change that makes array sort stable and it was accepted and All major JavaScript engines now implement a stable array sort It's just one last thing for you as a JavaScript developer to worry about V8 also implements several Intel APIs that provide key local specific functionality such as date formatting number from adding plural form selection and Collation in JavaScript These APIs allow you to localize your websites without having to ship hundreds of kilobytes of locale data to the user Let's look at some of the new features. We've added recently Modern web applications often use phrases like yesterday 42 seconds ago or in three quarters instead of full dates or timestamps The interactive time format API can generate these phrases for you for each language you support This code example creates a relative time for matter for the English language We set the numeric option to auto to tell the formator it can use phrases like yesterday instead of one day ago the formator recognizes several time units such as seconds minutes hours days months quarters and weeks We pass it a number and a unit and it returns a string that represents this relative time and This doesn't just work for English, but for other languages like Tamil as well Previously developers had no choice, but to implement such APIs themselves One problem with implementing a localized later time formator Is that you need a list of customary words or phrases such as yesterday or last quarter for each language you support The Unicode CLDR provides this data, but to use it in JavaScript. It has to be shipped alongside other library code This unfortunately increases the bundle size for such libraries Which negatively impacts load time farce compile time and memory consumption With the new Intel Redo time format API the browser ships the data so you get the functionality without paying the cost The relative time format API is available in Chrome, Firefox and Node Modern web applications often use lists consisting of dynamic data and they require local specific formatting of such lists For example a photo viewer app might display a message like this photo includes person a b and c The Intel list format API can help you format such strings for any given language using the local specific list conventions a Text-based game might have a different kind of lists. It could say something like choose your favorite hero XY or Z The list format API supports that too using the disjunction type Now because each language has different list formatting conventions and words Implementing a localized list format in JavaScript is non trivial Not only does this require a list of all the words such as and or or for each language you want to support in Addition you need to encode the exact formatting conventions for all those languages The Intel list format API takes care of all of that for you The list format proposal is available in Chrome and Node for other browsers a polyfill is available It's common for websites to display date intervals or date ranges to show the span of an event Such as a hotel reservation The billing period of a service or I don't know a big decked out a professional in Monview The format range method provides a convenient way of formatting ranges in a local specific manner In the above example we create Two dates and print the date using date time format Date time format is an existing API that has been shipping in all browsers for a while So one way to print the date range is to use the regular locale unaware string formatting You format the start date you format the end date and piece them together into a string here The second dates month and your calendar fields are redundant only day provides new information So instead with the new format range method we can display only the relevant fields and none of the repeating ones The format range method is available behind a flag in Chrome and we plan to ship it very sooner in The previous examples you may have noticed the locale ID that we passed to the various Intel constructors such as EN for English Intel locale offers a powerful mechanism to deal with such locale It enables easily extracting local specific preferences such as not only the language But also the calendar the numbering system the hour cycle the region and so on The Intel locale proposal is now available in Chrome and node. You can use a polyfill for all the browsers If you've used promises before you might already be familiar with a lovely async await syntax Instead of chaining promise callbacks using then you can nicely await the result of a promise This syntax has been around for a while now. However, awaits can only occur within an async function But there are use cases for wanting to use await at the top level But currently this isn't possible One workaround is taking all your top-level code wrapping it up in an async function that you then call Another approach is to wrap your top-level code in an immediately invoked async function expression But a new proposal enables the use of await at the top level removing the need for these workarounds Now the Chrome DevTools console already wraps your input in an async function behind the scenes if the input contains a wait So it looks like top-level awaits already works in the console But that's not because we implement the proposal. We don't The exact details of the top-level await proposal are still being worked out and as such it's still too early to implement it It's not currently supported everywhere So now that we're on the subject of promises and async code, let's talk about promise API's Currently there are two promise combinators in JavaScript the static method all and race Promise.all lets you know when either all input promises have fulfilled or when one of them rejects Promise.race lets you know as soon as one of the input settles Which means either fulfills or rejects These are independently useful and have different use cases So imagine if the user clicks a button and you want to load some style sheets so you can render a completely new UI This program kicks off an HTTP request for each style sheet in parallel Then you only want to start running the new UI after all the requests succeed But if something goes wrong You want to instead display an error message as soon as possible without waiting for any other work to finish In such a case you could use promise.all You want to know when all promises are fulfilled or as soon as one of them rejects Promise.race is useful if you want to run multiple promises and either Do something with the first successful result that comes in in case one of the promise fulfills or Do something as soon as one of the promise rejects That is if one of the promise rejects you wanted to preserve that Rejection and treat that error case separately Here we do exactly that We kick off a computationally expensive task that might take a long time But we race it against a promise that rejects after two seconds Depending on the first promise to fulfill or reject we either render the computer result or the error message in two separate code parts There was a top-level await in that example by the way So those are the existing promise combinators all and race Two new proposals are currently making their way through the standardization process Promise.all-settled and promise.any With these additions there will be a total of four promise combinators in JavaScript each enabling different use cases Promise.all-settled gives you a signal when all of the input promises are settled and that means they're either fulfilled or Rejected this is useful in those cases where you don't really care about the state of the promise You just want to know when the work is done regardless of whether it was successful For example, you can kick off a series of independent API calls and then use promise.all-settled to make sure that they're all completed Before doing something else like removing a loading spinner Promise.any gives you a signal as soon as one of the promises fulfills This is similar to promise.race except any doesn't reject early when one of the promises rejects This code example checks which endpoint responds the fastest and then logs it Only if all of the requests fail do we end up in the catch block where we can then handle the errors Promise.any is still in the early stages of being standardized and it's not supported anywhere yet But promise.all-settled on the other hand is already available in Chrome 76 and in Firefox nightly For other browsers a polyfill is available Next up are weak references Generally references to objects are strongly held in JavaScript Meaning that as long as you have a reference to an object that object won't be garbage collected Currently weak maps and weak sets are the only way to weekly reference an object Adding an object to a weak map or a weak set doesn't prevent it from being garbage collected Weak references are a more advanced API that provide a window into the lifetime of an object So here we have a get image function that takes a name and perform some expensive operation to generate another object like a binary blob of image data To improve performance we store the image in a cache Now we don't have to perform the expensive operation again for the same name But there's a problem Maps hold on to the keys and values strongly So the image names and data can never be garbage collected So this steadily increases memory and causes a memory leak Note that using a weak map would not help you as weak maps don't support strings as keys a New proposal makes it possible to solve the memory leak by creating a weak reference Do the image and storing that in the cache instead of the image itself So when the garbage collector realizes that it's running out of memory it can clean up some of the images But there's still a problem here The map still holds on to the name strings forever Because those are the keys in the cache Ideally those strings would be removed as well The weak graphs proposal have a has a solution for that as well With the new finalization group API we can register a callback to run when the garbage collector zaps a registered object So here we register a callback to remove the keys from the cache when the image objects are garbage collected So our final implementation looks like this Given an image name we look up its corresponding weak reference in the cache If the weak reference still points to something we can return the cached image data If there's no cash entry yet or if the cached data has already been garbage collected We compute the image data Create a new weak reference to it Store the image name and weak reference in the cache Register a finalizer that removes the image name from the cache Once the image data is garbage collected and return the image The weak reps proposal is still going through the standardization process We have an experimental implementation in a v8 behind a flag already, but we won't ship it until the proposal is finished Now we've talked about lots of amazing JavaScript features today with for drying degrees of support I'm very excited to see how much the JavaScript landscape has evolved over the past year And we look forward to increased support and adoption of these new features across the entire ecosystem And who knows maybe next year we'll be back here at Google IO announcing that all these cutting-edge features are now supported everywhere Wouldn't that be nice fingers crossed If you have any feedback at all on this session or have any questions about modern JavaScript And don't hesitate to let us know on Twitter Thanks for listening and enjoy the rest of IO Thank you