Trim the Fat: A Practical Checklist for Cutting Astro Bundle Size and Boosting Page Speed
While Astro is designed to be "fast by default" through its Zero JavaScript philosophy, real-world applications often accumulate hidden bloat through...
Author’s note:
Question: What are the ways to reduce my bundle size in Astro? Identify the strategies here
Context: Context:
https://sarthakmishra.com/blog/optimizing-astro-bundle-size lists out a bunch of ideas. Generalize them and provide a checklist of Todos for me to optimize my page speeds
Executive Summary
While Astro is designed to be “fast by default” through its Zero JavaScript philosophy, real-world applications often accumulate hidden bloat through improper hydration strategies, heavy dependencies, and unoptimized assets. Research indicates that Astro sites can achieve 90% less JavaScript than comparable React frameworks 1, but realizing these gains requires active management.
The most effective strategies for 2026 involve three key levers: visibility (knowing what you ship), hydration discipline (loading code only when needed), and dependency swapping (replacing heavy runtimes).
| Strategy | Impact | Implementation Difficulty | Key Action |
|---|---|---|---|
| Hydration Tuning | High (up to 70% reduction) | Low | Audit client:* directives; move non-critical UI to client:visible or client:idle. |
| Runtime Swapping | High (~37KB savings) | Medium | Replace React (~40KB) with Preact (~3KB) or SolidJS. |
| Bundle Analysis | Medium (Diagnostic) | Low | Add rollup-plugin-visualizer to identify hidden large modules. |
| Asset Optimization | High (Payload size) | Low | Convert images to AVIF/WebP; subset fonts. |
1. Understanding Astro’s Default Performance Model
To optimize Astro, you must first understand how it differs from traditional Single Page Applications (SPAs).
1.1 The Zero-JS Philosophy
Astro’s core innovation is its “Zero JS” approach. By default, it renders components to pure HTML during the build process 2. Unlike React SPAs that ship the entire framework and application code to the browser regardless of usage, Astro strips away the JavaScript runtime for static content. This results in a site that is effectively “static by default” 1.
1.2 Islands Architecture
Astro employs an “Islands Architecture,” where the page is treated as a static ocean of HTML with isolated “islands” of interactivity 2.
- Traditional SPAs: Hydrate the entire page, blocking the main thread even for static text.
- Astro Islands: Only specific components (like a search bar or carousel) are hydrated.
- Result: This architecture allows each island to load its own minimal JavaScript bundle only when needed, drastically reducing page weight 3.
Data shows that this approach allows Astro sites to be 40% faster than React frameworks, sending 90% less JavaScript to the browser 1.
2. Visualizing What You’re Shipping
You cannot optimize what you cannot see. The first step in bundle reduction is generating a map of your current assets.
2.1 Implementing the Visualizer
The rollup-plugin-visualizer is the standard tool for analyzing Astro bundles. It generates a visual treemap of your modules, helping you spot large dependencies that shouldn’t be there 4.
Implementation Steps:
- Install the library:
npm install rollup-plugin-visualizer --save-dev - Add it to your
astro.config.mjs:
import { defineConfig } from 'astro/config';import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({ vite: { plugins: [visualizer({ emitFile: true, filename: "stats.html", })] }});- Run your build command.
- Open the generated
stats.htmlfile (located indist/for static sites ordist/client/for SSR) 4.
2.2 Interpreting the Data
When analyzing the report, look for:
- Unexpected Dependencies: Libraries you thought were tree-shaken but are fully included.
- Duplicate Packages: Multiple versions of the same library.
- Large Vendor Chunks: Single monolithic files containing all
node_modules.
Note: Because Astro hydrates partially, the build stats show all dependencies used across the site, but they do not perfectly represent the per-page bundle size the client receives 4.
3. Hydration Strategies & Client Directives
The most common cause of bloated Astro sites is the misuse of client directives. Using client:load indiscriminately turns your optimized Astro site back into a heavy SPA 1.
3.1 Choosing the Right Directive
Astro provides granular control over when JavaScript loads.
| Directive | Behavior | Best Use Case |
|---|---|---|
| (No Directive) | Renders as static HTML. No JS sent. | Static text, images, layout components. |
client:load | Hydrates immediately on page load. | Critical UI: Nav bars, Hero interactive elements 1. |
client:idle | Hydrates when the main thread is free. | Secondary UI: Social share buttons, newsletter forms 1. |
client:visible | Hydrates when component enters viewport. | Below-the-fold: Comments, footers, carousels 1. |
client:media | Hydrates when a media query matches. | Mobile-only sidebars or toggles 1. |
3.2 Real-World Impact
In a practical optimization case study, a developer reduced their first-screen JavaScript bundle from 150KB to 45KB simply by auditing directives 1:
- Navigation: Kept
client:load(needed immediately). - Comments Section: Switched to
client:visible(only loads when user scrolls down). - Share Buttons: Switched to
client:idle(non-urgent).
This change alone improved the Largest Contentful Paint (LCP) from 3.2 seconds to 1.6 seconds 1.
4. Pruning and Replacing Dependencies
Third-party libraries are often the heaviest part of a bundle.
4.1 React vs. Preact
If you are using React components within Astro, you are paying a “React Tax” of approximately 40KB (gzipped) for the runtime 5.
- React: ~40KB gzipped core.
- Preact: ~3KB gzipped core.
Switching to Preact (using preact-compat) is often a drop-in replacement that can reduce the total site size by up to 30% 5. This is particularly effective for simple interactive islands like toggles or forms.
4.2 Eliminating “Utility Bloat”
Common utility libraries often import far more code than necessary.
- Date Libraries: Replacing
moment.js(which can be 200KB+) with nativeDateorIntl.DateTimeFormatAPIs can save hundreds of kilobytes 1. - Lodash: Importing the full lodash library (
import _ from 'lodash') pulls in unused functions. Switch to native array methods or import specific sub-modules 1.
5. Advanced Code Splitting
Astro handles bundling automatically, using techniques like automatic code splitting and tree shaking to optimize performance 6. However, you can further tune this.
5.1 Route-Based Splitting
Code splitting breaks the application into smaller chunks based on routes or features. This ensures users only download the code necessary for the current page 7.
- Benefit: Reduces initial load time and parsing time.
- Mechanism: Astro automatically splits CSS and JS by page.
5.2 Tree Shaking
Modern bundlers (like Vite, used by Astro) perform tree shaking to remove “dead code”—exports that are defined but never imported 7. To maximize this:
- Use ES Modules (
import/export) instead of CommonJS (require). - Avoid side-effect imports where possible.
Bottom Line: Your Optimization Checklist
To achieve the best possible bundle size in Astro, follow this prioritized checklist:
- Audit Directives: Change
client:loadtoclient:visibleorclient:idlefor all non-critical components 1. - Visualize the Bundle: Run
rollup-plugin-visualizerto find hidden giants 4. - Swap Frameworks: If using React for simple islands, switch to Preact to save ~37KB 5.
- Drop Heavy Libs: Replace
moment.jsand fulllodashimports with native browser APIs 1. - Optimize Assets: Ensure images are compressed (AVIF/WebP) and fonts are subsetted 6.
- Isolate Interactivity: Break large monolithic components into smaller islands so static parts remain zero-JS 2.
References
Footnotes
Other Ideas