@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
3
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.