Post title (static)
Post sub-title (static)
This is the post content with images that is rendered by the server.
The next section contains the interactive social buttons component which includes its script.
--- name: islands-architecture description: Teaches the islands architecture pattern for partial hydration. Use when building content-heavy sites where most of the page is static and only small regions need interactivity. context: fork allowed-tools: Read, Grep, Glob paths: - "**/*.js" - "**/*.ts" license: MIT metadata: author: patterns.dev version: "1.1" related_skills: - "module-pattern" - "singleton-pattern" --- # Islands Architecture ## Table of Contents - [When to Use](#when-to-use) - [Instructions](#instructions) - [Details](#details) - [Source](#source) ## When to Use - Use this for primarily static websites that need sprinkles of interactivity (blogs, product pages, news sites) - This is helpful when you want to reduce the volume of JavaScript shipped to the client - Use this when SEO and fast initial page loads are priorities alongside selective interactivity ## Instructions - Identify static and dynamic regions of each page separately - Use frameworks like Astro, Marko, or Eleventy that support islands architecture - Hydrate interactive components independently using `client:visible` or similar directives - Keep the majority of the page as static HTML with zero JavaScript cost ## Details Loading and processing excess JavaScript can hurt performance. However, some degree of interactivity and JavaScript is often required, even in primarily static websites. We have discussed variations of Static Rendering that enable you to build applications that try to find the balance between: 1. Interactivity comparable to Client-Side Rendered (CSR) applications 2. SEO benefits that are comparable to SSR applications. The core principle for SSR is that HTML is rendered on the server and shipped with necessary JavaScript to rehydrate it on the client. Rehydration is the process of regenerating the state of UI components on the client-side after the server renders it. Since rehydration comes at a [cost](https://addyosmani.com/blog/rehydration/), each variation of SSR tries to optimize the rehydration process. This is mainly achieved by partial hydration of critical components or streaming of components as they get rendered. However, the net JavaScript shipped eventually in the above techniques remains the same. The term [Islands architecture](https://jasonformat.com/islands-architecture/) was popularized by Katie Sylor-Miller and Jason Miller to describe a paradigm that aims to reduce the volume of JavaScript shipped through "islands" of interactivity that can be independent delivered on top of otherwise static HTML. Islands are a component-based architecture that suggests a compartmentalized view of the page with static and dynamic islands. The static regions of the page are pure non-interactive HTML and do not need hydration. The dynamic regions are a combination of HTML and scripts capable of rehydrating themselves after rendering. ### Islands of dynamic components Most pages are a combination of static and dynamic content. Usually, a page consists of static content with sprinkles of interactive regions that can be isolated. For example: 1. Blog posts, news articles, and organization home pages contain text and images with interactive components like social media embeds and chat. 2. Product pages on e-commerce sites contain static product descriptions and links to other pages on the app. Interactive components such as image carousels and search are available in different regions of the page. 3. A typical bank account details page contains a list of static transactions with filters providing some interactivity. Static content is stateless, does not fire events, and does not need rehydration after rendering. After rendering, dynamic content (buttons, filters, search bar) has to be rewired to its events. The DOM has to be regenerated on the client-side (virtual DOM). This regeneration, rehydration, and event handling functions contribute to the JavaScript sent to the client. The Islands architecture facilitates server-side rendering of pages with all of their static content. However, in this case, the rendered HTML will include placeholders for dynamic content. The dynamic content placeholders contain self-contained component widgets. Each widget is similar to an app and combines server-rendered output and JavaScript used to hydrate the app on the client. In progressive hydration, the hydration architecture of the page is top-down. The page controls the scheduling and hydration of individual components. Each component has its hydration script in the Islands architecture that executes asynchronously, independent of any other script on the page. A performance issue in one component should not affect the other. ### Implementing Islands The Island architecture borrows concepts from different sources and aims to combine them optimally. Template-based static site generators such as [Jekyll](https://jekyllrb.com/) and [Hugo](https://gohugo.io/) support the rendering of static components to pages. Most modern JavaScript frameworks also support [isomorphic rendering](https://en.wikipedia.org/wiki/Isomorphic_JavaScript), which allows you to use the same code to render elements on the server and client. Jason's post suggests the use of [`requestIdleCallback()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback) to implement a scheduling approach for hydrating components. Static isomorphic rendering and scheduling of component level partial hydration can be built into a framework to support Islands architecture. Thus, the framework should: 1. Support static rendering of pages on the server with zero JavaScript. 2. Support embed of independent dynamic components via placeholders in static content. Each dynamic component contains its scripts and can hydrate itself using requestIdleCallback() as soon as the main thread is free. 3. Allow isomorphic rendering of components on the server with hydration on the client to recognize the same component at both ends. #### Frameworks Different frameworks today are capable of supporting the Islands architecture. Notable among them are: 1. **Marko**: [Marko](https://markojs.com/) is an open-source framework [developed](https://tech.ebayinc.com/engineering/the-future-of-marko/) and [maintained](https://tech.ebayinc.com/engineering/ebay-launches-marko-5/) by eBay to improve server rendering performance. It supports Islands architecture by combining streaming rendering with automatic partial hydration. HTML and other static assets are streamed to the client as soon as they are ready. Automatic partial hydration allows interactive components to hydrate themselves. Hydration code is only [shipped for interactive components](https://medium.com/@mlrawlings/maybe-you-dont-need-that-spa-f2c659bc7fec), which can change the state on the browser. It is isomorphic, and the Marko compiler generates optimized code depending on where it will run (client or server). 2. **Astro**: [Astro](https://astro.build/) is a static site builder that can generate lightweight static HTML pages from UI components built in other frameworks such as React, Preact, Svelte, Vue, and others. Components that need client-side JavaScript are loaded individually with their dependencies. Thus it provides built-in partial hydration. Astro can also lazy-load components depending on when they become visible. 3. **Eleventy + Preact:** [Markus Oberlehner](https://markus.oberlehner.net/blog/building-partially-hydrated-progressively-enhanced-static-websites-with-isomorphic-preact-and-eleventy/#lazy-hydration) demonstrates the use of Eleventy, a static site generator with isomorphic Preact components that can be partially hydrated. It also supports lazy hydration. The component itself declaratively controls the hydration of the component. Interactive components use a `WithHydration` wrapper so that they are hydrated on the client. Note that Marko and Eleventy pre-date the definition of Islands provided by Jason but contain some of the features required to support it. **Astro**, however, was built based on the definition and inherently supports the Islands architecture. #### Sample implementation The following is a sample blog page implemented using Astro. The page SamplePost imports one interactive component, SocialButtons. This component is included in the HTML at the required position via markup. ```astro // Component Imports import { SocialButtons } from '../../components/SocialButtons.js';
Post sub-title (static)
This is the post content with images that is rendered by the server.
The next section contains the interactive social buttons component which includes its script.