React compiler magic 🧙🔮

Issue #336.October 30, 2024.2 Minute read.
Bytes

Today’s issue: Giving Angular devs too much power, making your app feel more native, and bringing signals into the Polly Pocket universe.

Welcome to #336.


Eyeballs logo

The Main Thing

Alvin and the Chipmunks in an alley

useMemo, useCallback, and React.memo about to fr*ck your app up

React compiler magic 🧙🔮

It’s officially the Season of the Witch, so it makes sense that React just got a lot more magical with last week’s beta release of the React Compiler.

This new build-time tool is similar to Svelte’s beloved compiler, but some developers are still skeptical – asking questions like, Why do we need this? How will it affect performance? Is this somehow Vercel’s fault?

But let’s put down those torches and pitchforks (for now) and try to understand this new black magic before burning it at the stake complaining about it on Twitter.

Why does React need a compiler? React’s default model is to re-render every time a state change occurs – but sometimes, you want to opt out of this behavior to improve performance. That requires you to add manual memoization, which often leads to code that is more brittle, error-prone, and harder for other developers to understand.

That’s where the new compiler comes in – or as Mark Erikson put it, a true, no-kidding, parse-the-AST-and-run-through-numerous-optimization-passes compiler.

Here’s how it works:

  • Auto Memoization: Instead of manually adding useMemo, useCallback or React.memo, the React compiler finds where unnecessary re-renders are going to occur and automatically generates the memoization code for you, so that all code is memoized by default.

  • Function Outlining (experimental): This compiler technique extracts code from a “hot” path and applies more granular memoization, leading to better cache utilization – AKA it automatically splits code into smaller pieces that are easier to memoize.

  • JSX Element Inlining (experimental): This reduces the number of function calls by converting components into elements, where appropriate, resulting in React’s runtime doing less work to create the UI tree.

Bottom Line: The compiler definitely requires you to trust the black magic of React more than ever before – but it’s already produced some significant performance wins for various Meta apps, plus some noteworthy developer productivity gains.

And if I have to choose between trusting React more or trusting my coworkers more, I’m gonna choose the one who didn’t drop me on my head during the trust fall exercises at the last team offsite.

        

LocalXpose logo

Our Friends
(With Benefits)

A kid waking up in his bed looking scared

When you notice a flood of requests to your unsecured localhost tunnel

LocalXpose lets you expose your localhost to the internet

It provides secure, easy-to-use tunnels that make sharing effortless – whether you’re testing webhooks, showcasing a web app for clients, or collaborating with team members.

All you do is run your app locally, create a tunnel with one command, and LocalXpose generates a public URL that’s fully secured with e2e encryption.

“But how is this different from other local-to-WAN proxy tools?” TLDR, it gives you better security with more powerful features:

  • Advanced access control and auth lets you manage permissions with IP whitelisting, basic auth, key auth, and more (see the docs).

  • Support for multiple protocols like HTTP, TLS, UDP, and TCP lets you securely expose databases, SSH, and other services besides just web apps.

  • More goodies like personalized custom domains, a built-in file server, requests logging, and lots more.

Use it for free – and see why over 200,000 developers love LocalXpose.


Spot the Bug logo

Spot the Bug

Sponsored by Infinite Red

We are expert US-based consultants who have specialized in high-quality React Native development since 2015! Hire us to build, optimize, deploy, and support your React Native app.

let x = 5
let y = 10
[x, y] = [y, x]

Cool Bits logo

Cool Bits

  1. Samuel wrote about some changes their team is making to BlueSky’s React Native app to make it feel more native. Who could’ve guessed that the secret was just to make the borders thinner.

  2. Reaper from the Preact team wrote about how to simplify your islands architecture using nothing but a folder structure, a webpack config, and three pouches of Zyn your own ingenuity.

  3. Oso is hosting a free deep dive on How Google handles Authorization at scale. You’ll learn how Google built its own relationship-based authorization system called Zanzibar, plus the key tradeoffs of building a system like this for your own application vs. using an Authorization as a Service like Oso. [sponsored]

  4. Brandon Roberts added support for Web Sockets to Analog, the full-stack Angular framework. I’m not sure that it’s a good idea to give Angular devs this much power, but that’s for the gods to decide.

  5. Geoff Graham wrote about unleashing the power of scroll driven animations on the recently resurrected CSS Tricks blog. Welcome back, old friend.

  6. The Cloudflare team published a blog post about “fragment piercing” and “micro frontends”. I was very relieved to find that it did not include any references to Prince Albert.

  7. NativeWind just released v4.1 of its library that lets you use Tailwind CSS in React Native.

  8. Maxime Heckel wrote an in-depth article about crafting painterly shaders. Every time I read their blog, I walk away thinking that I should really learn what shaders are.

  9. Ahmad Alfy wrote a post about how to link to specific content on a page using text fragments.

  10. Dev Agrawal created Solid Socket, an experimental new library that brings signals to WebSockets. I’m still waiting for him to publish Solid-Pocket and finally bring signals into the Polly Pocket cinematic universe.


Spot the Bug logo

Spot the Bug: Solution

Sponsored by Infinite Red

If you run this code you get a “ReferenceError: y is not defined” error. This is because the JavaScript engine does not automatically insert a semicolon after 10 because the subsequent line can be parsed as a continuation of the expression. Meaning, JavaScript interprets the code like this:

let x = 5;
let y = 10[x, y] = [y, x];

To fix the issue, we can update our code to use semicolons or wrap the expression in parentheses:

let x = 5;
let y = 10;
([x, y] = [y, x]);

It’s comforting to know Douglas Crockford is (probably) out there still shaking his fist at this “insanely stupid code”.