Skip to content

Astro islands and the cost of JavaScript

The median page shipped 632 KB of JavaScript to mobile in 2025. Islands architecture makes that number a decision rather than a default, but only if someone measures the bundle after every release.

By Luis Aguilar — Chief Technology Officer 4 min read
Hands holding a smartphone, the device that parses and executes the 632 KB of JavaScript a median mobile page shipped in 2025
The parse and execute cost lands on the device, not on the build server. Photo: Anna Shvets / Pexels.
Contents

Islands architecture renders a page as static HTML and hydrates only the components you mark as interactive. In Astro that mark is a client:* directive, and the default is zero JavaScript. The payload becomes a per-component decision rather than a framework-wide one, which is where the savings come from.

Key takeaways

  • The median mobile home page shipped 632 KB of JavaScript in 2025, against 911 KB of images and a total of 2.56 MB, per the HTTP Archive Web Almanac.
  • Astro components render to HTML with no client-side runtime. JavaScript ships only for components carrying a client:* directive.
  • The directive is the decision: client:load, client:idle, client:visible, client:media and client:only hydrate at different moments and cost different amounts of main thread.
  • 77% of mobile origins had good INP in 2025 against 97% on desktop, and lab Total Blocking Time rose 58% year over year.
  • Islands reduce shipped bytes. They do not reduce the work inside an island, and a single oversized island can still fail INP.

What the median page shipped in 2025

The 2025 Web Almanac, published on 15 January 2026, measured the median home page at 2.86 MB on desktop and 2.56 MB on mobile. JavaScript was the second-largest resource type after images on both.

Grouped bar chart: the median mobile home page shipped 632 KB of JavaScript and 911 KB of images, against 697 KB and 1,058 KB on desktop.
Mobile ships fewer bytes than desktop and has less capacity to execute them.
The HTTP Archive Web Almanac reported that the median mobile home page in 2025 used 632 KB of JavaScript, 911 KB of images and 122 KB of fonts. The desktop median was 697 KB of JavaScript and 1,058 KB of images (HTTP Archive, January 2026).

Two things follow. JavaScript is the resource type most under a development team's control, because a build step compresses images and cannot compress a component library. And a median mobile device parses and executes those 632 KB before the page responds to a tap.

What islands actually change

An Astro component renders to static HTML and ships no client-side runtime. A React, Vue or Svelte component inside an Astro page also renders to markup, and its JavaScript is stripped unless a directive asks for hydration.

That inverts the usual default. In a single-page application the whole tree hydrates and you opt out through code splitting. With islands, nothing hydrates and you opt in per component. The same decision gets made either way, but the safe answer is now the cheap one. It is the argument behind choosing a stack by constraint rather than habit: the framework should make the desired outcome the path of least effort.

Picking a directive is a measurement decision

Astro documents five client directives. client:load hydrates immediately and client:idle waits for the browser to go idle. client:visible waits until the component enters the viewport, client:media hydrates on a media query match, and client:only skips server rendering.

Default to `client:visible` and justify anything more eager. A header search toggle above the fold is a reasonable client:load. A footer accordion, a map, a carousel and a comment widget are all client:visible, and the difference is real work removed from the initial main thread window.

client:only deserves suspicion. It ships the component and renders nothing on the server, so its content is invisible to crawlers and to anyone before hydration completes. Use it for widgets that cannot render without browser APIs, not to silence a hydration mismatch.

What to leave static

Most of a marketing site is text, images and links, and none of that needs hydration. Navigation can be HTML and CSS. Accordions can be <details>. Form validation can start with the constraint validation API and add JavaScript only for what HTML cannot express.

Native elements also arrive with keyboard behavior and announced state already correct, which removes a class of defects that the European Accessibility Act makes expensive to leave in place.

Server islands cover the personalized parts

The usual objection to static output is personalization: a cart count, a logged-in name, a price by region. Astro 5.0, released on 3 December 2024, made server islands stable. A component marked server:defer renders a fallback inside the cached page, then fetches its own content on demand.

The page stays cacheable and one slow island does not block the rest. It is a rendering strategy rather than a hydration strategy, and it removes the most common reason teams abandon static output halfway through a build.

Measuring what you actually ship

Islands make it easy to believe the bundle is small. Measure it anyway, every release.

Statistic panel: 77% of mobile origins had good INP in 2025 against 97% on desktop, while lab Total Blocking Time rose 58%.
The gap is device class, which is why a per-route budget has to fail builds instead of appearing in a retro.

Track four numbers per template: JavaScript transferred, hydrated islands, Total Blocking Time in the lab, and field INP at the 75th percentile. INP counts an interaction as good at or below 200 ms, across input delay, processing duration and presentation delay.

The 2025 Web Almanac found 77% of mobile origins achieving good INP against 97% on desktop. Lab Total Blocking Time rose 58% compared with 2024: heavier execution, unevenly distributed by device class (HTTP Archive, January 2026).

A budget only works if it fails a build. Set a per-route ceiling in kilobytes, wire it into CI, and treat a breach like a failing test rather than a note in the retro.

FAQ

Does Astro make a site fast automatically?

No. It removes JavaScript you did not ask for and leaves the rest to you. A page with six eager islands, an unoptimized hero and a tag manager loading three vendors will be slow in any framework. The defaults help; the measurements decide.

How many islands is too many?

There is no fixed number, because cost depends on what each island does. The practical test is Total Blocking Time in the lab and INP in the field. If either moves the wrong way after a release, look at the island you added and what it imports.

Do islands help LCP?

Indirectly. LCP is usually decided by the hero image and the critical request chain, not by component hydration, so the fixes described in what actually moves LCP still apply. Islands mostly help responsiveness metrics by keeping the main thread free.

Does this approach survive a redesign?

Yes, if the content model is separate from the components. The hydration decision lives in the template; the content lives in the CMS. That is the same discipline as modelling content so it survives a redesign and keeping design tokens as the contract between design and code.

Start by listing every component that ships JavaScript and asking what breaks without it. Convert the honest answers to static markup, move the rest to client:visible, and reserve eager hydration for the first seconds of interaction. Then set a per-route budget and let it fail builds. In six months the useful question is whether teams held that budget after the third feature request. That, not the framework, decides the number a user downloads.

Share on

Related reading

Let's build what's next.

We create brands, products, and experiences that move your business forward.

Start a project
we are ONE

ONE News. What we build, and how it scales.

Sharp, practical insights on brand, technology and digital performance

Over 1000 subscribers

By subscribing, you agree to Onetouch's Terms of Use, and Privacy Policy.

Let’s start a new case of study together

01.

What do you need...

02.

Your budget is...

03.

Do you have a specific deadline?

04.

Attach a project brief if you’d like!

Attach a project brief if you’d like!

05.

About you...