
https://www.youtube.com/watch?v=h6cYVLBlSPM
아일랜드 아키텍쳐는 Katie Sylor-Miller, Jason Miller가 제안했습니다.
현대의 웹은 정적 콘텐츠와 동적인 콘텐츠가
섞여 있습니다. 정적 콘텐츠의 경우 상태를 다루거나 유저가 이벤트 인터렉션을 하지 않기 때문에 서버사이드 렌더링 직후 re-hydration 과정이 필요하지 않습니다.
동적 콘텐츠는 인터렉티브해야 하기 때문에 서버사이드 렌더링 이후 event를 다룰 수 있고 상태 값을 동작할 수 있도록 재조정 과정을 거쳐야 합니다.
리엑트의 서버사이드 렌더링의 경우 리엑트18에서 나온 selective hydration 덕분에 hydration의 우선순위를 설정할 수 있긴 하지만 페이지 전체가 hydration의 대상이 되는 것은 여전합니다.

hydration의 전체 대상이 되는 회색 영역
SSR에서 re-hydration은 어려운 문제입니다.
전체 영역중에 일부 영역만 서버에서 렌더링한 html과 불일치가 일어나면 올바르게 hydration된게 아니라고 간주하고 CSR로 다시 전체 페이지를 렌더링하는등의 대응이 필요합니다.

hydration이 실패한 영역
아일랜드 아키텍쳐는 전체 페이지를 서버사이드에서 렌더링하고 다시 클라이언트사이드에서 hydration하는 방식을 사용하지 않고 정적 콘텐츠는 SSR을 사용하고 동적 콘텐츠는 slot이라고 하는 공간을 html 에 만들어 CSR 영역을 최소화 합니다.
이 slot은 placeholder라고 부르기도 하는데 이 slot들은 react 뿐만 아니라 다른 프레임워크들로도 채울 수 있습니다. 각 slot은 독립적으로 hydration 됩니다.
아래 그림에서 파란색 영역은 정적영역이고 나머지 영역들만 hydration의 대상이됩니다.

SSR 을 사용하는 주 이유는 SEO와 First paint 타임을 줄이기 위해서입니다. 정적 콘텐츠 영역은 그대로 노출시키고 접근성도 저하시키지 않을 수 있고
다운로드되는 javascript의 번들 사이즈도 최소화 시킬 수 있습니다.
굳이 라는 생각이 드실 수 있습니다. 제가 처음 아일랜드 아키텍쳐를 접했을때 굳이라는 생각이 들었거든요.
SSR을 사용하는 것은 불가피한데 로딩되는 JS 청크의 사이즈를 최소화하는 것이 아일랜드 아키텍처의 장점입니다.
SPA를 사용하는 이유가 웹의 인터렉션의 영역이 많아져서인데 정적 콘텐츠 영역이 페이지의 대부분을 차지하는 경우가 생각보다 제한된 유즈케이스에서만 가능하지 않나 싶었거든요.
그리고 인터렉티브한 영역을 사용할 때는 hydration 과정은 불가피하고 SSR도 사용할만한데 성능을 쥐어짜기 위해 별도의 문법과 렌더링 패턴 구현 방법을 구현하는게 불필요하다는 생각이 들었습니다. 
출처: 구글 검색 squeeze
그래도 알아야 할 건 알아야겠죠
잘 안쓸 것 같은 렌더링 패턴도 알아뒀더니 사용할 떄가 있더라고요.
Astro는 아일랜드 아키텍쳐를 사용하여 웹을 만들 수 있게 도와주는 도구입니다.

아스트로는 리엑트나 스벨트, 뷰등 여러 프레임워크로 만들어진 컴포넌트들로 UI를 구성할 수 있게 해주며 컴포넌트별로 hydration 필요유무를 판단해줍니다.

---
import Counter from './components/Counter.jsx';
import TodoList from './components/TodoList.svelte';
---
<html>
<head>
<title>Island Architecture Example</title>
</head>
<body>
<header>
<h1>Island Architecture Example</h1>
</header>
<main>
<section>
<h2>Counter</h2>
<Counter client:only />
</section>
<section>
<h2>Todo List</h2>
<TodoList client:only />
</section>
</main>
<footer>
<p>Made with Astro</p>
</footer>
</body>
</html>
이 페이지는 헤더와 푸터를 정적콘텐츠로 가지고 있고 두 동적 콘텐츠 - 아일랜드를 가지고 있습니다.
Counter 컴포넌트는 리엑트로, TodoList는 스벨트로 작성되었습니다. 아스트로에서 client:only 디렉티브를 통해 동적 아일랜드임을 표기해 CSR에서 hydration이 필요한지를 설정할 수 있습니다.
이렇게 아스트로로 작성된 페이지들은 서버사이드에서 다음과 같은 html 파일로 변환됩니다.
<html>
<head>
<title>Island Architecture Example</title>
</head>
<body>
<header>
<h1>Island Architecture Example</h1>
</header>
<main>
<section>
<h2>Counter</h2>
<!-- placeholder for Counter component -->
<div id="astro-uxz9k" data-astro-id="uxz9k" data-astro-component="Counter"></div>
</section>
<section>
<h2>Todo List</h2>
<!-- placeholder for TodoList component -->
<div id="astro-uxz9l" data-astro-id="uxz9l" data-astro-component="TodoList"></div>
</section>
</main>
<footer>
<p>Made with Astro</p>
</footer>
<!-- scripts for hydration -->
<script type="module" src="/_astro/common.js"></script>
<!-- script for Counter component -->
<script type="module">
import { setup } from '/_astro/common.js';
import Component from '/_astro/Counter.js';
setup(Component);
</script>
<script type="module">
import { setup } from '/_astro/common.js';
import Component from '/_astro/TodoList.js';
setup(Component);
</script>
</body>
</html>
컴포넌트들은 각각의 별도로 번들된 JS 파일들로 만들어져 유저 인터렉션이 일어날때 필요할때만 로딩됩니다.
만들어진 html파일을 보면 매우 간단하고 깨끗합니다.
정적 콘텐츠는 순수한 html과 css로 이뤄져있고 동적 콘텐츠만 미리 만들어진 placeholders에 data 속성 값으로 표기되어있습니다. 이 data 속성값은 아스트로에게 어떻게 hydrate를 해야하는지를 알려줍니다.
이 페이지를 브라우저에서 렌더링하게 되면 html에 표기된대로 정적 콘텐츠가 먼저 보여지게 될 것입니다.
그리고 카운터 버튼에 클릭을 하거나 컴포넌트에 인터렉션을하면 그때 필요한 번들파일이 로딩됩니다.
이렇게 되면 브라우저가 불필요한 자바스크립트 번들을 다운로드할 필요가 없습니다.
<script>
import { onMount } from 'svelte';
let todos = [];
let input = '';
onMount(() => {
// fetch initial todos from an API
fetch('/api/todos')
.then(res => res.json())
.then(data => {
todos = data;
});
});
function addTodo() {
// add a new todo to the list
if (input) {
const newTodo = { id: Date.now(), text: input, done: false };
todos = [...todos, newTodo];
input = '';
}
}
function toggleDone(todo) {
// toggle the done status of a todo
todos = todos.map(t => t.id === todo.id ? { ...t, done: !t.done } : t);
}
function deleteDone() {
// delete all the done todos
todos = todos.filter(t => !t.done);
}
</script>
<style>
/* some styles for the component */
</style>
<div class="todo-list">
<h3>Todo List</h3>
<ul>
{#each todos as todo}
<li class="{todo.done ? 'done' : ''}">
<input type="checkbox" checked={todo.done} on:change={() => toggleDone(todo)} />
<span>{todo.text}</span>
</li>
{/each}
</ul>
<div class="actions">
<input type="text" bind:value={input} />
<button on:click={addTodo}>Add</button>
<button on:click={deleteDone}>Delete Done</button>
</div>
</div>
매번 유익한 글 재밌게 읽고 갑니다!! 👍👍
제가 쓴 글 렌더링 패턴의 8.아일랜드 문단에서 이 글을 언급해도 괜찮을까요~?~?