Choose Theme

Detect Island Hydration in Astro

· 2 min read · #Astro #JavaScript
--

Debug which Astro islands are hydrating and when. Useful for optimizing bundle size.

src/utils/hydration-detector.ts
export function detectHydration(componentName: string) {
if (import.meta.env.DEV) {
const startTime = performance.now();
console.log(`🏝️ [Hydration] ${componentName} starting...`);
// Detect when hydration completes
queueMicrotask(() => {
const endTime = performance.now();
const duration = (endTime - startTime).toFixed(2);
console.log(
`✅ [Hydration] ${componentName} completed in ${duration}ms`
);
});
}
}
// Get bundle size estimate
export async function logBundleSize(componentName: string) {
if (import.meta.env.DEV && 'navigation' in window) {
const entries = performance.getEntriesByType('resource');
const scripts = entries.filter(
(e) => e.name.includes(componentName) && e.name.endsWith('.js')
);
scripts.forEach((script) => {
const size = ((script as any).transferSize / 1024).toFixed(2);
console.log(`📦 [Bundle] ${componentName}: ${size} KB`);
});
}
}

Usage in components:

src/components/LikeButton.astro
<button id="like-btn">Like</button>
<script>
import { detectHydration, logBundleSize } from '../utils/hydration-detector';
detectHydration('LikeButton');
// Your component logic
document.getElementById('like-btn')?.addEventListener('click', () => {
console.log('Liked!');
});
logBundleSize('LikeButton');
</script>

Console output:

🏝️ [Hydration] LikeButton starting...
✅ [Hydration] LikeButton completed in 3.42ms
📦 [Bundle] LikeButton: 4.23 KB

Advanced: Track all islands

src/utils/track-islands.ts
const hydratedIslands = new Set<string>();
export function trackIsland(name: string, directive: string) {
if (import.meta.env.DEV) {
const key = `${name}:${directive}`;
if (hydratedIslands.has(key)) {
console.warn(`⚠️ [Island] ${name} hydrated multiple times!`);
}
hydratedIslands.add(key);
console.log(`🏝️ [Island] ${name} (${directive})`);
}
}
// Call at end of script
setTimeout(() => {
console.log(`📊 Total islands hydrated: ${hydratedIslands.size}`);
}, 2000);

Why this helps:

  • Identify over-hydration (same component loaded twice)
  • Measure hydration performance
  • Optimize client:load vs client:visible vs client:idle
  • Find bundle size opportunities

Related