lazy-viewport-loader
v1.0.2
Published
Lazy load functions when elements enter viewport using IntersectionObserver
Maintainers
Readme
lazy-viewport-loader
⚡ 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.
The Problem
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.
The Solution
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.
Installation
npm install lazy-viewport-loaderQuick Example
import { 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.
Usage Examples
Basic Usage
import { useLoadFunction } from 'lazy-viewport-loader'
// Load analytics when footer is visible
useLoadFunction(
() => import('./analytics.js'),
'footer'
)With Arguments
// Load video player with configuration
useLoadFunction(
() => import('./videoPlayer.js'),
'#video-section',
['video-id-123', { autoplay: false, quality: 'hd' }]
)Custom Intersection Options
// Load 200px before element enters viewport
useLoadFunction(
() => import('./comments.js'),
'#comments',
[],
{
threshold: 0,
rootMargin: '200px' // Start loading 200px before visible
}
)Load at 50% Visibility
// Load when element is 50% visible
useLoadFunction(
() => import('./gallery.js'),
'#image-gallery',
[images],
{ threshold: 0.5 }
)Manual Control
const observer = useLoadFunction(
() => import('./module.js'),
'#target'
)
// Stop observing manually if needed
observer.stopObserving()API
useLoadFunction(importFn, element, args, options)
Parameters
| 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' }) |
Returns
Observer instance with control methods:
stopObserving()- Manually stop observing the element
IntersectionObserver Options
threshold: Number between 0-1.0= any pixel visible,1= fully visiblerootMargin: Start loading before element is visible (e.g.,'100px','200px 0px')
Real-World Use Cases
📊 Heavy Chart Library (400KB+)
// Load Chart.js only when user scrolls to charts section
useLoadFunction(
() => import('chart.js'),
'#analytics-dashboard',
[chartConfig]
)🎥 Video Player (200KB+)
// Load video player library on-demand
useLoadFunction(
() => import('./videoPlayer.js'),
'.video-container',
[videoUrl, playerOptions]
)🗺️ Interactive Maps (500KB+)
// Load Google Maps/Leaflet only when map section is visible
useLoadFunction(
() => import('./mapInitializer.js'),
'#map-section',
[coordinates, mapConfig],
{ rootMargin: '300px' } // Preload 300px before visible
)💬 Comments Section
// Load comments widget when user scrolls down
useLoadFunction(
() => import('./commentsWidget.js'),
'#comments',
[],
{ threshold: 0.25 } // Load when 25% visible
)📸 Image Gallery with Heavy Dependencies
// Load image gallery library (lightbox, zoom, etc.)
useLoadFunction(
() => import('./imageGallery.js'),
'.gallery-grid',
[images, galleryOptions]
)Performance Benefits
✅ 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
Browser Support
Works in all modern browsers that support IntersectionObserver:
- Chrome 51+
- Firefox 55+
- Safari 12.1+
- Edge 15+
For older browsers, use an IntersectionObserver polyfill.
How It Works
- 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
Module Requirements
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
}License
MIT
Contributing
Issues and pull requests are welcome on GitHub.
Made with ⚡ for better web performance
