HTML Tutorial 0/139 lessons ~6 min read Lesson 125

    Islands & Partial Hydration

    islands & partial hydration islands and partial hydration deliver seo-friendly static html while attaching j islands architecture and partial hydration

    Course progress0%
    Focus
    18 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Islands architecture and partial hydration ship mostly static HTML and attach JavaScript only to interactive regions ("islands"). Astro popularized islands; React Server Components and Qwik push selective hydration further. The goal is the same: cut JS bytes and main-thread work on content-heavy pages without surrendering SEO-rich HTML.

    Business problem

    Business pressure: Marketing pages loaded 400KB of React to power one carousel and a newsletter form. LCP and INP suffered; ad spend ROI dropped. Islands let teams keep static HTML for 95% of the DOM and hydrate 5% — measurable CWV wins.

    • Perf budget: Content sites target <100KB JS — full hydrate blows the budget.
    • SEO: Static HTML body with island markers preserves crawlable content.
    • DX: Teams want component ergonomics without shipping a root createRoot on every page.

    Why this feature exists

    Platform motivation: Full-document hydration duplicated server HTML work on the client — wasteful for blogs, docs, and landing pages. Frameworks introduced island boundaries so only components with client:* directives (or equivalent) ship JS.

    • History: MPA static sites → SPA everything → islands/partial hydrate as correction.
    • Alternative rejected: iframes for widgets — SEO, a11y, and styling pain.
    • Modern role: Astro, Marko, Fresh, Qwik, Next client components — same architectural idea, different syntax.

    Browser internals

    Inside the engine: Server sends HTML with markers (e.g. data-astro-cid, q:slot). Parser builds full DOM. Island scripts load with async/type=module, hydrate only matching subtrees — rest stays inert HTML.

    • Hydration mismatch: Server and client HTML must match inside island boundaries or React throws.
    • Event delegation: Some frameworks defer listener attachment until island visible (Intersection Observer).
    • Ordering: Islands must not block LCP element — defer non-critical island scripts.

    Rendering workflow

    Rendering path: SSG/SSR produces HTML string. Build step extracts island dependency graph. Browser paints static content; island bundles load in parallel; hydration runs per island, not full tree.

    • Static shell: Immediate FCP/LCP from HTML/CSS.
    • Island boot: Separate entry chunks — cache independently.
    • Partial hydrate: Framework skips inert server component subtrees entirely on client.

    Feature deep dive

    Island boundaries — declare interactivity explicitly; default is static. Pass serializable props from server to island via attributes or embedded JSON with CSP-safe encoding.

    • Directive: client:load, client:visible, client:idle — trade TTI for bytes.
    • Props: Serialize to DOM — never pass functions from server HTML.
    • Styling: Scoped CSS per island vs global design tokens — plan specificity.
    html
    <!-- Static HTML (no JS) -->
    <article>
    <h1>Launch recap</h1>
    <p>Full article text for SEO and screen readers.</p>
    </article>
    <!-- Island: hydrates on visible -->
    <div data-island="cart-button" data-props='{"sku":"ABC"}'>
    <button type="button">Add to cart</button>
    </div>
    <script type="module" src="/islands/cart-button.js" async></script>

    Accessibility analysis

    A11y architecture: Static content is immediately available to assistive tech. Islands that replace static placeholders must preserve accessible names and not steal focus on hydrate.

    • Buttons: Server HTML should use real <button> — not div upgraded on hydrate.
    • Live regions: Island cart updates need aria-live after enhancement loads.

    SEO impact

    SEO architecture: Islands excel on content sites — article body is pure HTML. Avoid island-only product titles or prices; crawlers must see them in source.

    • View-source test: Primary keywords in static HTML, not injected post-hydrate.
    • JSON-LD: Server-rendered in <script type="application/ld+json"> — outside islands.

    Security considerations

    Security boundary: Serialized props in HTML attributes are injection targets — use JSON encoding and CSP. Each island bundle is a supply-chain surface — subresource integrity where possible.

    • Props XSS: Never interpolate user content into data-props without encoding.
    • Island scripts: Scope permissions — cart island should not access admin APIs.

    Performance impact

    Performance: Islands directly improve INP and TBT by reducing hydrate scope. Choose client:visible for below-fold widgets.

    • LCP: Do not hydrate hero — static image and text.
    • INP: Fewer hydrated components = fewer main-thread listeners.
    • Bytes: Track per-page island bundle sum in CI budget.

    Real production example

    Production pattern: Docs site on Astro: MDX content static; client:visible for code playground; client:load only for site search. RUM compares LCP before/after migrating from Next full hydrate.

    • Metrics: 62% JS reduction; LCP −1.1s mobile p75.
    • CI: Fail build if new island uses client:load without perf review.

    Enterprise usage

    Enterprise: Marketing within large org adopts islands while app team stays on SPA — shared design system ships CSS + web components as static-friendly islands.

    • Platform: Approved island directives and prop serialization library.
    • Governance: Architecture review when island count >5 per page.

    Common production failures

    What breaks in prod: Hydration mismatch on island after A/B test changed server HTML. Or client:load on every widget — recreated full-app hydrate problem.

    • Incident: Double cart buttons — server HTML + client render both visible until CSS hack.
    • Perf: 12 islands with client:load — TBT regression; fixed with visible/idle directives.

    Architecture review questions

    • Which components truly need client directives on this page?
    • Is primary content visible in view-source without executing JS?
    • What hydration mismatch tests run in CI?
    • How are island props serialized safely?
    • What is total island JS weight vs budget?

    Hands-on project

    Project: Convert a static article page to islands: static article + one interactive poll (visible) + one search box (idle). Measure JS weight and Lighthouse performance.

    • Deliverable: HTML output, island entries, before/after byte count.

    Interview questions

    Islands vs partial hydration vs RSC — how do you explain the trade-off?(Advanced)

    All reduce client JS by keeping most markup server/static. Islands are explicit component boundaries with separate bundles; partial hydration skips inert subtrees; RSC sends server components without client reference. Choose based on framework ecosystem and team skill.

    Follow-up: When would you still full-hydrate?

    Try it yourself

    Edit the HTML, CSS, or JS panels — the preview updates as you type.

    Try it yourself

    Preview

    Summary

    Islands and partial hydration deliver SEO-friendly static HTML while attaching JavaScript only where needed. Staff engineers enforce island budgets, safe prop serialization, and hydration tests to avoid recreating SPA bloat on content pages.

    Ready to mark this lesson complete?Track your journey across the entire course.