β‘ Boost your website performance by lazy-loading heavy JavaScript functions only when they're needed.
Stop loading everything upfront. Load modules only when users scroll to them.
You have a heavy JavaScript module (e.g., 400KB chart library, video player, map widget) that slows down your initial page load. Users might never even scroll to that section, but you're forcing them to download it anyway.
lazy-viewport-loader uses IntersectionObserver to load JavaScript modules only when the target element enters the viewport. This dramatically improves initial load time and performance scores.
npm install lazy-viewport-loaderimport { useLoadFunction } from 'lazy-viewport-loader'
// Load a 400KB chart library only when user scrolls to #chart-container
useLoadFunction(
() => import('./heavyChartLibrary.js'), // 400KB module
'#chart-container', // Target element
[chartData, chartOptions] // Arguments to pass
)Result: The heavy module is downloaded and executed only when #chart-container becomes visible.
import { useLoadFunction } from 'lazy-viewport-loader'
// Load analytics when footer is visible
useLoadFunction(
() => import('./analytics.js'),
'footer'
)// Load video player with configuration
useLoadFunction(
() => import('./videoPlayer.js'),
'#video-section',
['video-id-123', { autoplay: false, quality: 'hd' }]
)// Load 200px before element enters viewport
useLoadFunction(
() => import('./comments.js'),
'#comments',
[],
{
threshold: 0,
rootMargin: '200px' // Start loading 200px before visible
}
)// Load when element is 50% visible
useLoadFunction(
() => import('./gallery.js'),
'#image-gallery',
[images],
{ threshold: 0.5 }
)const observer = useLoadFunction(
() => import('./module.js'),
'#target'
)
// Stop observing manually if needed
observer.stopObserving()| Parameter | Type | Required | Description |
|---|---|---|---|
importFn |
Function |
Yes | Dynamic import function (e.g., () => import('./module.js')) |
element |
string |
Yes | CSS selector for the element to observe |
args |
Array |
No | Arguments to pass to the imported function (default: []) |
options |
IntersectionObserverInit |
No | IntersectionObserver options (default: { threshold: 0, rootMargin: '100px' }) |
Observer instance with control methods:
stopObserving()- Manually stop observing the element
threshold: Number between 0-1.0= any pixel visible,1= fully visiblerootMargin: Start loading before element is visible (e.g.,'100px','200px 0px')
// Load Chart.js only when user scrolls to charts section
useLoadFunction(
() => import('chart.js'),
'#analytics-dashboard',
[chartConfig]
)// Load video player library on-demand
useLoadFunction(
() => import('./videoPlayer.js'),
'.video-container',
[videoUrl, playerOptions]
)// Load Google Maps/Leaflet only when map section is visible
useLoadFunction(
() => import('./mapInitializer.js'),
'#map-section',
[coordinates, mapConfig],
{ rootMargin: '300px' } // Preload 300px before visible
)// Load comments widget when user scrolls down
useLoadFunction(
() => import('./commentsWidget.js'),
'#comments',
[],
{ threshold: 0.25 } // Load when 25% visible
)// Load image gallery library (lightbox, zoom, etc.)
useLoadFunction(
() => import('./imageGallery.js'),
'.gallery-grid',
[images, galleryOptions]
)β
Faster initial page load - Only load what's immediately visible
β
Lower bandwidth usage - Users don't download modules they never see
β
Better Core Web Vitals - Improved FCP, LCP, and TTI scores
β
Automatic cleanup - Observer stops after first trigger
β
Mobile-friendly - Especially beneficial for users on slow connections
Works in all modern browsers that support IntersectionObserver:
- Chrome 51+
- Firefox 55+
- Safari 12.1+
- Edge 15+
For older browsers, use an IntersectionObserver polyfill.
- Observe: Watches when the target element enters the viewport
- Import: Dynamically imports the module when visible
- Execute: Calls the exported function with provided arguments
- Cleanup: Automatically stops observing after loading
Your imported module should export a function as default or named export:
// module.js
export default function initializeFeature(arg1, arg2) {
// Your code here
}
// or
export function initializeFeature(arg1, arg2) {
// Your code here
}MIT
Issues and pull requests are welcome on GitHub.
Made with β‘ for better web performance