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

react-precious-image

v0.0.2

Published

Adaptive image component

Downloads

4

Readme

Build Status Code Coverage version downloads MIT License

All Contributors PRs Welcome Code of Conduct

Watch on GitHub Star on GitHub Tweet

The problem

I need React component to asynchronously load images, which will adapt based on network, which will allow a user to control, which image to load.

This solution

Image component which will lazy load images:

  • Do not load images if they are not visible
  • Require image dimensions to generate placeholders, to prevent browsers layout bounce when images get loaded
  • Require placeholder (lqip, sqip or solid color) to improve perceived load speed.
  • If a client has a good internet connection, a component will load images as soon as user scrolls to it, no additional action required from the user.
  • If a client has a bad internet connection, a component will generate placeholder and "button", which will let a user decide if they want to load an image or not.

Additionally:

  • When load starts there is no additional indicator of loading state (clean placeholder), but if it takes more than specified threshold additional indicator appears and a user can cancel the download
  • If an error occurred while downloading an image, a component will provide a visual indication and will allow retry load
  • If a browser is offline and an image is not loaded yet, a component will provide a visual indicator of this case, so a user would know an image is not loaded and there is no way to load it at the moment

Table of Contents

Installation

This module is distributed via npm which is bundled with node and should be installed as one of your project's devDependencies:

npm install --save-dev react-precious-image

Usage

import React from 'react'
import lqip from 'lqip.macro'
import {AdaptiveLoad} from 'react-precious-image'

import image from './images/doggo.jpg'
const lqip = lqip('./images/doggo.jpg')

const App = () => (
  <AdaptiveLoad
    lqip={{lqip}}
    src={image}
    alt="doggo"
    width={3500}
    height={2095}
  />
)

Technical limitations

There is no way to reliably measure a speed of the connection unless browser provides facility for it. Theoretically, we can take the size of an image (provided upfront or read from HTTP headers) and divide by time spent downloading it, but connection capacity will be equally split between all parallel downloads, so this is not precise, and we need to wait for the finish of download to get the final value.

If browser provides navigator.connection.effectiveType it will be used to detect a speed of connection: 'slow-2g', '2g' are considered to be slow; '3g' is (sometimes) considered slow, '4g' and everything else is considered as fast.

If a browser doesn't provide navigator.connection.effectiveType and threshold provided component will broadcast event (to other components) in case of surpassing threshold and all components which haven't started download yet will treat current browser connection as slow. The threshold is the time (in ms) till component considers a load of image fast enough, if a component gets over the threshold it will show an indicator of slow load and user will be able to cancel the download.

If current browser connection considered to be slow all components fallback to manual-load mode.

If current browser connection considered to be fast all components use lazy-load mode, e.g. they will start download as soon as user scrolls to it.

Inspiration

  • Lazy load - this is a technique known from jQuery ages.
  • Specify image dimensions - a recommendation from PageSpeed and later AMP project
  • Use placeholder to improve perceived load speed. LQIP - the technique used by Facebook and Medium. Solid color placeholder - the technique used by Google, Twitter and Pinterest.
  • Overlay icons - to indicate the state of the image and give the user control over it. The technique used by Twitter.
  • Use WebP format, if it is supported by the browser. Recommendation from PageSpeed
  • Use image size according to the screen size. The idea comes from srcset and @media queries

Other Solutions

I'm not aware of any which supports all features, if you are please make a pull request and add it here!

Contributors

Thanks goes to these people (emoji key):

| stereobooster💻 📖 🚇 ⚠️ | | :---: |

This project follows the all-contributors specification. Contributions of any kind welcome!

LICENSE

Code - MIT

Icons - Apache License 2.0