@jameswilliamquinn2018/preact-lazy-load
v1.0.1
Published
`preact-lazy-load` is a lightweight library for implementing lazy loading in Preact applications. It includes components for lazy loading images, iframes, and background images, with fallback support for older browsers.
Downloads
16
Maintainers
Readme
To extract the code into an npm library that can be easily implemented in a new Preact app, you will need to structure your code as a reusable package. Here’s a step-by-step guide to creating an npm package for lazy loading in Preact:
Step-by-Step Guide
1. Set Up the NPM Package
Create a new directory for your library:
mkdir preact-lazy-load cd preact-lazy-load
Initialize the npm package:
npm init -y
Install Preact as a dependency:
npm install preact
Create the required directory structure:
mkdir src touch src/index.js src/LazyImage.js src/LazyIframe.js src/LazyBackgroundImage.js
2. Write the Library Code
src/index.js
This file will export all the components.
export { default as LazyImage } from './LazyImage';
export { default as LazyIframe } from './LazyIframe';
export { default as LazyBackgroundImage } from './LazyBackgroundImage';
src/LazyImage.js
import { h } from 'preact';
import { useRef, useEffect } from 'preact/hooks';
const LazyImage = ({ src, srcset, sizes, alt }) => {
const imgRef = useRef(null);
useEffect(() => {
if ('loading' in HTMLImageElement.prototype) {
imgRef.current.src = src;
imgRef.current.srcset = srcset;
} else {
setupLazyLoadingFallback();
}
function setupLazyLoadingFallback() {
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
imgRef.current.src = src;
imgRef.current.srcset = srcset;
observer.unobserve(imgRef.current);
}
});
}, { rootMargin: '0px 0px 50px 0px' });
observer.observe(imgRef.current);
} else {
imgRef.current.src = src;
imgRef.current.srcset = srcset;
}
}
}, [src, srcset]);
return (
<img
ref={imgRef}
sizes={sizes}
loading="lazy"
alt={alt}
/>
);
};
export default LazyImage;
src/LazyIframe.js
import { h } from 'preact';
import { useRef, useEffect } from 'preact/hooks';
const LazyIframe = ({ src, title }) => {
const iframeRef = useRef(null);
useEffect(() => {
if ('loading' in HTMLIFrameElement.prototype) {
iframeRef.current.src = src;
} else {
setupLazyLoadingFallback();
}
function setupLazyLoadingFallback() {
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
iframeRef.current.src = src;
observer.unobserve(iframeRef.current);
}
});
}, { rootMargin: '0px 0px 50px 0px' });
observer.observe(iframeRef.current);
} else {
iframeRef.current.src = src;
}
}
}, [src]);
return (
<iframe
ref={iframeRef}
loading="lazy"
title={title}
></iframe>
);
};
export default LazyIframe;
src/LazyBackgroundImage.js
import { h } from 'preact';
import { useRef, useEffect } from 'preact/hooks';
const LazyBackgroundImage = ({ src, children }) => {
const divRef = useRef(null);
useEffect(() => {
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
divRef.current.style.backgroundImage = `url(${src})`;
divRef.current.setAttribute('data-loaded', 'true');
observer.disconnect();
}
});
}, { rootMargin: '0px 0px 50px 0px' });
observer.observe(divRef.current);
} else {
// Fallback for older browsers
divRef.current.style.backgroundImage = `url(${src})`;
divRef.current.setAttribute('data-loaded', 'true');
}
}, [src]);
return (
<div ref={divRef} className="lazy-background">
{children}
</div>
);
};
export default LazyBackgroundImage;
3. Add Styles
Since styles need to be included for the library to work correctly, create a style.css
file and include it in the package.
Create src/style.css
:
.lazy-background {
opacity: 0;
transition: opacity 0.3s;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.lazy-background[data-loaded] {
opacity: 1;
}
Modify src/index.js
to include the styles:
import './style.css';
export { default as LazyImage } from './LazyImage';
export { default as LazyIframe } from './LazyIframe';
export { default as LazyBackgroundImage } from './LazyBackgroundImage';
4. Bundle the Library
You will need to set up a bundler like Rollup to bundle your library. Here is an example configuration using Rollup.
Install Rollup and necessary plugins:
npm install --save-dev rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-babel @rollup/plugin-terser
Create
rollup.config.js
:import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import babel from '@rollup/plugin-babel'; import { terser } from '@rollup/plugin-terser'; export default { input: 'src/index.js', output: { file: 'dist/index.js', format: 'esm', sourcemap: true, }, plugins: [ resolve(), commonjs(), babel({ exclude: 'node_modules/**', presets: ['@babel/preset-env', '@babel/preset-react'] }), terser(), ], external: ['preact'] };
Add build scripts to
package.json
:"scripts": { "build": "rollup -c" },
5. Build and Publish the Library
Build the library:
npm run build
Publish the package:
npm publish
6. Use the Library in a New Preact App
Create a new Preact app:
npx preact-cli create default my-new-preact-app cd my-new-preact-app
Install the library:
npm install preact-lazy-load
Use the library in your Preact app:
src/index.js
import { h, render } from 'preact';
import App from './components/App';
import './style.css';
render(<App />, document.body);
src/components/App.js
import { h } from 'preact';
import { LazyImage, LazyIframe, LazyBackgroundImage } from 'preact-lazy-load';
const App = () => (
<div>
<h1>Native Lazy Loading in Preact</h1>
<h2>Lazy Load Image</h2>
<LazyImage
src="path/to/image.jpg"
srcset="path/to/image-320w.jpg 320w, path/to/image-480w.jpg 480w"
sizes="(max-width: 600px) 320px, 480px"
alt="Description of image"
/>
<h2>Lazy Load Iframe</h2>
<LazyIframe
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
title="Sample Video"
/>
<h2>Lazy Load Background Image</h2>
<LazyBackgroundImage
src="path/to/background-image.jpg"
>
<p>Content overlaying the background image</p>
</LazyBackgroundImage>
</div>
);
export default App;
With this setup, you have created an npm library for lazy loading components in Preact that can be easily integrated into any Preact project.