I read about islands architecture a long time ago and really appreciated it when I tried Astro for my projects. At that time Astro was very new but I totally get it. If you ever used WordPress, the idea is familiar already. You have a page, you drop widgets into it (a comments section, a recent posts list, a search bar). Each widget does its own thing, does not interfere with the others.

Islands architecture is exactly that mental model. Except instead of generating all the widget JavaScript upfront, you delay each one.

The WordPress Comparison

Think of a typical WordPress page. The header, the article body, the footer (all rendered as plain HTML from the server). Then you have widgets in the sidebar: a search box, a tag cloud, a newsletter signup. Each widget is self-contained. You add it, configure it, and it renders in its own little box.

Now imagine instead of shipping jQuery and all the widget scripts on every page load, you tell each widget: "hydrate when you are ready." The search box hydrates immediately because users might use it. The newsletter widget hydrates when the browser is idle. The tag cloud (maybe it does not need JavaScript at all, it is just links).

That is islands architecture. Each interactive region is an island with its own JavaScript bundle, its own hydration schedule, and zero dependency on the rest of the page.

Why This Helps Lighthouse Scores

This matters most for content pages (blogs, documentation, news articles). These pages are 80-90% static text. In a traditional React or Vue setup, you ship the entire component tree and hydrate everything top-down even if only 10% of the page is interactive. The JavaScript cost is front-loaded regardless.

Here is how Lighthouse weights its performance score as per Chrome docs:

  • Total Blocking Time (30%)
  • Largest Contentful Paint (25%)
  • Cumulative Layout Shift (25%)
  • First Contentful Paint (10%)
  • Speed Index (10%)

Islands architecture improves most of these directly:

FCP (10% weight): The page HTML is server-rendered and ships immediately. No JavaScript blocks the first paint. The browser paints the article text and images right away.

LCP (25% weight): The largest element on a content page is usually a hero image or article heading (both static HTML). No hydration needed for the main content to appear. LCP hits fast because the browser is not competing with JavaScript parsing.

TBT (30% weight): This is the big one. Most pages ship megabytes of JavaScript that the main thread has to parse and execute. With islands, only the interactive widgets ship any JS. The comments widget loads on idle. The newsletter popup loads on scroll. The main thread stays free for actual user interactions.

CLS (25% weight): Server-rendered HTML means the layout is set before any JavaScript runs. No layout shifts from widgets popping in after hydration.

Jason Miller, who popularised the term, describes it as HTML pages with placeholders around dynamic regions. You render the full page on the server, then each island upgrades itself independently. Astro calls these hydration directives (client:load, client:idle, client:visible) and they map directly to the priority of each widget.

For my blog here, I use Eleventy which already outputs static HTML. Adding islands on top would mean shipping JavaScript only for the parts that actually need it (comments, maybe a search bar, nothing else). The rest is just HTML. Which is how it should be for a content site.

The Takeaway

If your page is mostly text, islands architecture makes sense. You are not building a SPA. You are building a document with some interactive widgets dropped in. WordPress bloggers understood this intuitively (the widgets just did not have the performance vocabulary for it). Now we do.

Further reading: