DEV Community

Cover image for Lazy-Load Angular SVG Components as Separate JS Chunks with Standalone Components
Ioseb Koplatadze
Ioseb Koplatadze

Posted on

Lazy-Load Angular SVG Components as Separate JS Chunks with Standalone Components

🧩 How to Lazy Load Standalone Angular Components as Separate JS Files β€” Ideal for On-Demand Icons

When you're building a large Angular app β€” especially with many SVG icons or visual components β€” loading all of them up front bloats your bundle and hurts performance.

What if you could:

  • Split each icon into its own JS chunk
  • And load them only when needed?

Thanks to Angular standalone components and dynamic import(), you can do exactly that.

This guide shows you how to create truly separate JS files (chunks) for each component, and load them on demand β€” perfect for things like icon libraries, feature flags, or infrequently used UI blocks.


βœ… TL;DR

You can:

  • Create standalone components (e.g., SVG icons)
  • Load each via import()
  • And Angular will split each into its own JS file
  • That JS chunk will only be downloaded when needed

Result? Blazing-fast first load πŸš€


πŸ›  Use Case: Load SVG Icons Only When Used

Let’s say you have a large icon set like:

/icons/ search-icon.component.ts home-icon.component.ts settings-icon.component.ts 
Enter fullscreen mode Exit fullscreen mode

Instead of importing them all and inflating your bundle, you'll:

βœ… Turn each into a standalone component
βœ… Dynamically load the needed icon at runtime
βœ… Let Angular generate a separate JS file (chunk) for each


πŸ›  Step-by-Step: Lazy Load as Separate Chunks

1. Create a Standalone SVG Component

// icons/search-icon.component.ts import { Component } from '@angular/core'; @Component({ standalone: true, selector: 'app-search-icon', template: \` <svg width="24" height="24" fill="none"> <path d="..." /> </svg> \`, }) export class SearchIconComponent {} 
Enter fullscreen mode Exit fullscreen mode

πŸ” No NgModule. It's a fully standalone component.


2. Use import() to Load It On Demand

In your host component:

import { ViewChild, ViewContainerRef } from '@angular/core'; @ViewChild('iconHost', { read: ViewContainerRef }) vcRef!: ViewContainerRef; loadSearchIcon() { import('./icons/search-icon.component').then(({ SearchIconComponent }) => { this.vcRef.clear(); this.vcRef.createComponent(SearchIconComponent); }); } 
Enter fullscreen mode Exit fullscreen mode

In your HTML:

<button (click)="loadSearchIcon()">Show Search Icon</button> <ng-container #iconHost></ng-container> 
Enter fullscreen mode Exit fullscreen mode

🧠 import() triggers Angular’s code-splitting β€” so the icon is excluded from the main bundle and gets its own JS file.


3. Build with Optimization On

Run this command:

ng build --configuration production 
Enter fullscreen mode Exit fullscreen mode

Now check your output folder (dist/), and you should see something like:

main.<hash>.js runtime.<hash>.js polyfills.<hash>.js icons-search-icon-component.<hash>.js βœ… 
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ That last file is your lazy-loaded icon, automatically split into a separate JS chunk by Angular.


🎯 Why This is Awesome for SVG/Icon Libraries

  • ✨ Avoid bloating your main bundle
  • ⚑ Only load the icon when it’s actually needed
  • 🧩 Each icon is encapsulated as a component
  • πŸ“¦ Tree-shaking friendly β€” unused icons never load

πŸ“Œ Side Note: What About Libraries?

This setup also works in Angular libraries (e.g., in an Nx workspace or shared icon lib), with a few conditions:

  • βœ… Keep your icon components standalone: true
  • βœ… Import them with a direct relative path using import()
  • ❌ Do not re-export them in the library’s public-api.ts β€” or Angular will include them in the main bundle

Want a full working example inside a library setup? Drop a comment β€” it's just a minor adjustment.


πŸ§ͺ Bonus: Verify the Chunk

Want to confirm that the icon really became a separate JS file? Use Webpack’s bundle analyzer:

ng build --configuration production --stats-json npx webpack-bundle-analyzer dist/YOUR_APP_NAME/stats.json 
Enter fullscreen mode Exit fullscreen mode

You’ll see a separate chunk like:

icons-search-icon-component.<hash>.js 
Enter fullscreen mode Exit fullscreen mode

🧠 Final Thoughts

Angular’s support for standalone components + native dynamic import() makes it incredibly easy to split your code.

You now have:

  • Fully isolated, lazy-loadable components
  • Chunk-per-icon architecture
  • Faster startup times and less JS downloaded up front

No extra tooling. No webpack config hacks. Just clean Angular.


πŸ” Summary

Feature Supported?
Lazy-load individual SVG/icon components βœ… Yes
Force each into its own JS chunk βœ… Yes
Works with standalone components βœ… Yes
Use import() with direct file path βœ… Yes
Use inside an Angular library (with caveats) βœ… Yes
Re-export via public-api.ts ❌ No

Thanks for reading! πŸ™Œ

Top comments (0)