In today’s world for-of loops are supported everywhere, so I patched the package again and swapped out the function implementation with the original one in the source. This one single change saves about 400ms. I’m always impressed by how much CPU time we burn on wasteful polyfills or outdated downtranspilation.
…
So many libraries in our ecosystem suffer from this issue. I really wish there was a way to update them all with one click. Maybe we need a reverse transpiler which detects down transpilation patterns and converts it back to modern code again.
Tag: javascript
# An introduction to the LibJS JavaScript engine
Slides for a presentation by Linus Groh on LibJS, Serenity OS’s JavaScript engine written from scratch.
Top-level await in JavaScript REPLs is a hack
Today I learned that top-level await in JavaScript REPLs, such as Chrome’s Developer Tools console and Node.js REPL, is a BIG HACK!
Top-level await is a feature of JavaScript that allows you to use await
outside of an async function, for example:
await Promise.resolve("cool")
Before it was added, the only way to use await was to wrap it in async function:
(async () => await Promise.resolve("cool"))()
However, top-level await only works within modules. This is a problem for REPLs, since they don’t make a module for every expression that you type. They basically use eval()
on it, running in the global scope: if you type x = 1
or var x = 1
, you expect x
to be a global variable.
So, await
wouldn’t work. But it does work! How? I initially thought they implemented some kind of a special eval-level await V8. Nope!
Turns out REPLs parse your expression and rewrite it into the async function! Both Node and Chrome use the acorn.js parser for that 🤯
If you type
await Promise.resolve('cool')
they turn it into
(async () => {return (await Promise.resolve('cool'));})()
What about global variables though? If you type var x = 1
. and wrap it in a function, the var will be local to the function. But we want it to be global.
Here’s the trick — they also rewrite variable definitions:
var x = 1; await Promise.resolve('ok');
turns into:
(async () => {void (x = 1); return (await Promise.resolve('ok'));})()
They strip var
/let
/const
from what now are function-scoped variables and just assign values to the global. Notice that your const
will not actually be a const, but that’s fine, since REPLs allow redeclaring and reassigning top-level const
and let
anyway.
One funny thing: before running this whole parser stuff, Chrome dev tools check if rewriting is needed at all by looking for “async” in your code. So, if you type console.log("async work")
, it will execute a tiny bit slower than console.log("meetings")
😜
If you want more details, read this processTopLevelAwait function in Node.
# Canvas Confetti
A fun library for making confetti blasts with JavaScript.
# Pixel Accurate Atkinson Dithering for Images in HTML
I have [al]ways liked the look of images processed with Atkinson Dithering, the algorithm used in the original Apple Macintosh.
Looks very nice, indeed. The author provides a custom HTML element implementing it.
# Announcing SvelteKit 1.0
After two years in development, SvelteKit has finally reached 1.0. As of today, it’s the recommended way to build Svelte apps of all shapes and sizes.
SvelteKit is a framework for building web apps with Svelte, similar to Next/Nuxt. It replaces Sapper from the previous version of Svelte.
# Developing the Bloomberg Terminal
A good talk by Paul Williams describing the internals of the Bloomberg Terminal software:
It combines a highly-scalable, proprietary data processing technology written in C++ with an embedded Chromium browser core and its V8 JavaScript engine. The result is a challenging, distributed run-time environment that must perform well and be measurable. The talk will cover some of the techniques used to develop and instrument this system.
Tiny Reacty stack
If you like your React and styled components, but want to reduce the size of your JavaScript bundles, consider the following tiny alternatives:
- Preact — 3 KB alternative to React, with a few kilobytes more if you want full compatibility.
- goober — 1 KB styled components alternative.
Preact also has its own interesting state library called signals. It’s tiny and enables rendering optimizations by avoiding virtual DOM in certain cases. (There is also a version of signals available for React if you need to switch back.)
# Bun v0.3.0
Today, Bun has two main priorities: stability and compatibility with Node.js and Web APIs. In v0.3.0, we’ve made significant progress toward both of these goals.
Bun is an interesting new Node.js alternative based on JavaScriptCore, with additional features, such as bundling, transpiling, and managing packages. It is written in Zig, gluing a lot of of third-party C and C++ code.
React Canvas — render React components to canvas
React.js is known for its virtual DOM, but as Facebook’s software engineer Bill Fisher said, the virtual DOM is only an implementation detail.
Last week we saw Facebook releasing React Native, which renders native OS components instead of DOM elements. Today Flipboard released React Canvas, a high performance React renderer for <canvas>
.
Continue reading “React Canvas — render React components to canvas”