npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@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

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

  1. Create a new directory for your library:

    mkdir preact-lazy-load
    cd preact-lazy-load
  2. Initialize the npm package:

    npm init -y
  3. Install Preact as a dependency:

    npm install preact
  4. 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.

  1. Install Rollup and necessary plugins:

    npm install --save-dev rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-babel @rollup/plugin-terser
  2. 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']
    };
  3. Add build scripts to package.json:

    "scripts": {
      "build": "rollup -c"
    },

5. Build and Publish the Library

  1. Build the library:

    npm run build
  2. Publish the package:

    npm publish

6. Use the Library in a New Preact App

  1. Create a new Preact app:

    npx preact-cli create default my-new-preact-app
    cd my-new-preact-app
  2. Install the library:

    npm install preact-lazy-load
  3. 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.