JavaScript performance beyond bundle size

Nolan Lawson, on how we might focus too much on JavaScript bundle size:

Performance is a multi-faceted thing. It would be great if we could reduce it down to a single metric such as bundle size, but if you really want to cover all the bases, there are a lot of different angles to consider.

He digs into other factors that have an influence:

  • Parse/compile time
  • Execution time
  • Power usage
  • Memory usage
  • Disk usage

JavaScript performance beyond bundle size →

Before You React.memo()

Dan Abramov shares 2 techniques to try before resorting to optimize with React.memo()

In this post, I want to share two different techniques. They’re surprisingly basic, which is why people rarely realize they improve rendering performance.

These techniques are complementary to what you already know! They don’t replace memo or useMemo, but they’re often good to try first.

Covered Solutions:

  1. Move State Down
  2. Lift Content Up

Before You memo() →

Easily see the JavaScript Keyboard Event KeyCodes with

Handy helper tool by Wes Bos: simply press any key and see the results for KeyboardEvent.which, KeyboardEvent.key,KeyboardEvent.code, etc.

As a user with an AZERTY keyboard layout I often have a broken experience on sites that respond to first row of keys, e.g. QWERTY. As those sites respond to KeyboardEvent.key — which differs from layout to layout — I cannot simply use the first row, but have to reach for the Q and W keys on the second and third row.

To properly implement key presses independent of the keyboard layout, it’s recommended to use e.keyCode as that will yield the same keyCode. As per MDN:

The KeyboardEvent.code property represents a physical key on the keyboard (as opposed to the character generated by pressing the key). In other words, this property returns a value that isn’t altered by keyboard layout or the state of the modifier keys.

For example: pressing A on AZERTY will yield KeyQ. Pressing Q on QWERTY will also yield KeyQ as they’re the same physical key.

JavaScript Event KeyCodes →

How I Build JavaScript Apps In 2021

Tim Daubenschütz on how he builds JavaScript Apps In 2021

  1. I avoid build processes.
  2. I avoid transpiling.
  3. I avoid the new and shiny.
  4. I test EvErYtHiNg.
  5. I optimize for performance and quality.
  6. I use my own work
  7. I use open source to my advantage.

Don’t agree 100% with the third point though, as React Hooks and Function Components — the example he mentions — are a big step ahead to me.

What I don’t do is try to keep up with all other frameworks though — an impossible task — but focus on one of them (e.g. React) and go really deep in it. (And of course I’m also going all-in on VanillaJS, a very safe bet to make 😉)

How I Build JavaScript Apps In 2021 →

Via Jeremy

Observing Rendered DOM Nodes

Sam Thorogood has been looking into all kinds of changes that can happen to DOM Nodes:

This post will explain how to be notified when:

  • an element is added or removed from the DOM
  • the bounding box of an element changes (i.e., resizes)
  • an element moves around the page for any reason

Expect some ResizeObserver, IntersectionObserver, and MutationObserver sprinkled all over the post.

Observing rendered DOM nodes →

Related: On Twitter Denis Radin chimed in with his StyleObserver.js to track style changes.

What’s new in ES2021

With the January meeting of TC39 behind us, the Stage-4 features that will make it into ES2021 have been selected.

💁‍♂️ Stage-4?

The Technical Committee which is concerned with the standardization of ECMAScript (e.g. TC39) has a 5 stage process in place, ranging from stage-0 to stage-4, by which it develops a new language feature.

Stage-4 is the Finished Stage and indicates that the proposal is ready to become part of the ECMAScript Specification.

The following features will be part of ES2021, which will be formalised mid-2021:

Apart from the linked-to posts above, Pawel Grzybek has done a writeup on all features. Additionally you can check all posts tagged es2021 on the V8 blog.

☝️ Note that you can use (most of) these features today already, as browsers start rolling them out (unflagged) when they hit Stage-3. So no, you don’t have to wait until mid-2021 to start using them.

Don’t use functions as callbacks unless they’re designed for it

Solid advice by Jake:

Here’s an old pattern that seems to be making a comeback:

import { toReadableNumber } from 'some-library';
const readableNumbers =;

Here’s the problem:

// We think of:
const readableNumbers =;
// …as being like:
const readableNumbers = => toReadableNumber(n));
// …but it's more like:
const readableNumbers =, index, arr) =>
  toReadableNumber(item, index, arr),

You might have encountered this yourself when combining map with parseInt, as its second parameter defines the base to use 😅

Don’t use functions as callbacks unless they’re designed for it →

map is one of the array methods I use a lot, along with filter and reduce. This post right here explains them using a simple example.

Cancel JavaScript Event Listeners with AbortController

One of the new features that was added in Chrome 88 is the ability to pass an AbortController‘s signal into addEventListener.

const controller = new AbortController();
const { signal } = controller;

document.querySelector('…').addEventListener('foo', (e) => {
  // …
}, {signal});

By calling controller.abort();, you can remove the listener from the event target, just like when calling element.removeEventListener.

💁‍♂️ Did you know you can use the AbortController to abort promises? It was its first intended use case when it was introduced back in 2017.


An excellent use-case here is that you can cancel multiple Event Listeners at once using it, as shared by Jake Archibald:

In the example above there are two competing event listeners. Whenever one of them finishes controller.abort(); is called, thus also removing the other one. Cool!


🔥 Like what you see? Want to stay in the loop? Here's how:

Snowpack v3.0

Version 3.0 of the aforementioned Snowpack got released, and it’s quite exciting I must say!

  • Pre-bundled streaming imports – Import any npm package, on-demand.
  • Integrated build optimizations – Built-in bundling, preloading, minification, and more.
  • JavaScript API – Integrate with Snowpack’s brand new native JS API.
  • Node.js Runtime API – Import your Snowpack-built files directly into Node.js.

The streaming imports will most likely have the biggest impact on us all:

Streaming imports make it possible to import any package directly into your project, pre-built and pre-bundled for immediate use. It’s the power of the entire JavaScript ecosystem, at your fingertips.

With streaming imports we can now simply write import statements, and Snowpack will fetch the package for us from Skypack — No npm install needed!

And since it uses esbuild under the hood it’s fast. Blazing fast.

Snowpack v3.0 →