Dispatch Web
All posts

Islands: how we use React without paying for it everywhere

Why most of a marketing site should be plain HTML, where interactivity earns its JavaScript, and the mistake we found on this site while writing this post. Measured, and fully referenced.


The previous post explained what React is and gave the evidence for its benefits. It also named the cost: React runs in your visitor’s browser, and everything that runs there has to be downloaded and executed first. This post is about how we keep that cost small. The approach is called islands. It is simple to explain, and while writing this we found a place on our own site where we had broken the rule. The fix is measured below.

The problem islands solve

For most of the last decade a website was built one of two ways. Either the server sent finished HTML and the page was static, or the server sent an empty shell and a JavaScript application drew the whole page in the browser. The second way is how most “modern” sites are built, and it has a hidden delay. Addy Osmani and Jason Miller describe it in Google’s guide to rendering on the web: server-rendered pages “can appear to be loaded and interactive, but can’t actually respond to input until the client-side scripts for components are executed and event handlers have been attached”[1]. That step, running scripts to make the HTML interactive, is called hydration[1].

The amount of script has kept growing. The HTTP Archive’s 2024 Web Almanac puts the median page at 558 kilobytes of JavaScript on mobile and 613 on desktop, up 14% in a year[2]. All of it competes for the one thread the browser uses to respond to taps and clicks. Google’s guidance is that “any task that takes longer than 50 milliseconds is a long task”[3], and its responsiveness metric, Interaction to Next Paint, is only rated good when interactions complete “below or at 200 milliseconds”[4]. A page that hydrates a whole application to show a paragraph of text spends that budget before the visitor has done anything.

What an island is

Katie Sylor-Miller, then at Etsy, coined the term “component island” in 2019, and Jason Miller, the creator of Preact, wrote it up in 2020[5]. His definition is one sentence: “render HTML pages on the server, and inject placeholders or slots around highly dynamic regions”[6]. Everything outside those regions is plain HTML. The pattern library patterns.dev puts it this way: “An ‘islands’ page is a static HTML document with small, independent zones of interactivity dropped into it. Each interactive zone ships its own JavaScript and hydrates on its own schedule; the rest of the page stays plain HTML.”[7]

The word independent matters. Astro, the framework we build on, explains that separate islands “load in parallel and hydrate in isolation, meaning that the header becomes interactive immediately without having to wait for the heavier carousel lower down the page”[5]. A slow island cannot hold the rest of the page hostage.

Deciding when each island wakes up

Islands do not all have to load at once. Astro gives each one an instruction that says when its JavaScript should arrive[8]:

  • Immediately. client:load will “load and hydrate the component JavaScript immediately on page load”. We use this for the job board on the home page, because it is the first thing on the screen and it moves.
  • When the browser is idle. client:idle waits until “the page is done with its initial load”. Right for things that matter but not first.
  • When it scrolls into view. client:visible waits until “the component has entered the user’s viewport”. The giving-back application form sits at the bottom of a long page, so its JavaScript does not load unless the visitor gets there.
  • Only on some screens. client:media waits until “a certain CSS media query is met”, so a phone-only control costs a desktop visitor nothing.

The instruction is a design decision, made per component, and it is written down in the code where the next developer can see it.

The mistake we found on this site

The rule sounds obvious: use React where a page needs it. The subtle failure is using React for something small. A React island, however tiny, needs the React runtime, and that runtime is the same size whether it is running a form or a clock.

When we measured this site’s pages for this post, every page was loading the runtime. The reason was two components in the header: the mobile menu and the Perth clock. Both had been written as React islands out of habit. On a content page like this one, with no form and no board, they were the only JavaScript, and they were bringing about 60 kilobytes of compressed script with them.

We rewrote both as plain HTML with a few lines of ordinary script. The table shows the JavaScript each page now sends, compressed, measured from the production build on 3 June 2026. The home page and the forms keep React because they use it; this article does not.

Page What runs on it JavaScript before JavaScript now
This article Menu, clock 60 KB 1 KB
Home Job board, menu, clock 62 KB 61 KB
Build your brief Brief builder, menu, clock 66 KB 65 KB

The home page barely changed, because the board needs React anyway. The article page lost 98% of its JavaScript. Nothing a visitor can see is different. That is the whole lesson of islands in one table: the cost is not React, it is React where it is not needed.

Where React earns its place

On this site React runs three things: the job board on the home page, the brief builder, and the giving-back application. Each one holds state that changes as you act, across several steps, with validation and a server round trip. That is the work React is built for, and writing it by hand would be slower and buggier.

The menu, the clock, the accordion of questions on the home page, the tables and every word of text are HTML and CSS. The test we apply is short: if the browser can do it in HTML and CSS, or in a few dozen lines of plain script, it is not an island.

For your site the same test applies. A price calculator, a multi-step enquiry, a product filter: islands. A hero, a menu, a photo gallery, a list of services, a map embed: HTML. A quote that proposes a full JavaScript application for a brochure site is proposing the median page from the Almanac, and you will pay for it in the metrics Google measures[9].

What islands are not good at

Islands are the right shape for a site that is mostly content with pockets of interaction. They are the wrong shape for a site that is really an application. patterns.dev names the friction: “Two islands cannot share React state directly. You can move shared state to URL params, cookies, a tiny store mounted as its own island, or custom DOM events”[7]. When most of a page needs to know what the rest of the page is doing, you have outgrown islands, and the honest answer is a different architecture with a different price. If your brief describes that, we will say so rather than force it onto a static site.

Check any site in a minute

You do not need us to verify this. Open a page in Chrome, press F12, choose the Network tab, filter by JS, and reload. The total at the bottom is the JavaScript that page sends. Or paste the address into Google’s PageSpeed Insights and read the “Reduce unused JavaScript” line. Our own figures are published on the home page with the date they were taken.

If you are planning a build and want to know which parts of it would be islands, the brief builder takes three minutes and the answer comes back with a fixed price.

Reference list

All sources accessed 3 June 2026.

  1. Osmani, A. and Miller, J. (2019, updated 2026) Rendering on the Web. web.dev, Google. https://web.dev/articles/rendering-on-the-web
  2. Amjad, A. H. and Goel, N. (2024) 'JavaScript', in The 2024 Web Almanac. HTTP Archive. https://almanac.httparchive.org/en/2024/javascript
  3. Google (n.d.) Optimize long tasks. web.dev. https://web.dev/articles/optimize-long-tasks
  4. Google (n.d.) Interaction to Next Paint (INP). web.dev. https://web.dev/articles/inp
  5. Astro (n.d.) Islands architecture. Astro documentation. https://docs.astro.build/en/concepts/islands/
  6. Miller, J. (2020) Islands Architecture. 11 August 2020. https://jasonformat.com/islands-architecture/
  7. patterns.dev (n.d.) Islands Architecture. https://www.patterns.dev/vanilla/islands-architecture/
  8. Astro (n.d.) Template directives reference: Client directives. Astro documentation. https://docs.astro.build/en/reference/directives-reference/
  9. Google (n.d.) Web Vitals. web.dev. https://web.dev/articles/vitals

Unfamiliar word? Every term in this post is defined in one sentence in the glossary.

Written by Dispatch Web. Corrections and questions: send them through the brief builder and mark them as a note; they reach the same board.