Coder Social home page Coder Social logo

londyf / react-cool-img Goto Github PK

View Code? Open in Web Editor NEW

This project forked from wellyshen/react-cool-img

0.0 1.0 0.0 6.09 MB

๐Ÿ˜Ž๐Ÿž A React <Img /> component let you handle image UX and performance as a Pro!

Home Page: https://react-cool-img.org

License: MIT License

JavaScript 12.54% TypeScript 87.46%

react-cool-img's Introduction

React Cool Img

React Cool Img is a lightweight React <Img /> component, which helps you handle image UX (user experience) and performance optimization as a professional guy ๐Ÿค“

It empowers the standard img tag by many cool features without breaking your original development experience. Ideally, it can be an img tag replacement for React.js.

โšก๏ธ Live demo: https://react-cool-img.org

build status coverage status npm version npm downloads npm downloads npm bundle size MIT licensed All Contributors PRs welcome Twitter URL

Features

โš ๏ธ Most modern browsers support Intersection Observer natively. You can also add polyfill for full browser support.

Requirements

react-cool-img is based on React Hooks. It requires react v16.8+ and react-dom v16.8+.

Installation

This package is distributed via npm.

$ yarn add react-cool-img
# or
$ npm install --save react-cool-img

Quick Start

The default props of the component has been fine-tuned for the purpose of loading optimization. Let's start it as the following example.

import Img from 'react-cool-img';

// Suggest to use low quality or vector images
import loadingImage from './images/loading.gif';
import errorImage from './images/error.svg';

const App = () => (
  <Img
    placeholder={loadingImage}
    src="https://the-image-url"
    error={errorImage}
    alt="React Cool Img"
  />
);

Don't want an image placeholder? No worries, you can use inline styles or CSS for it. The component is fully compatible with the development experience of normal img tag.

import Img from 'react-cool-img';

const App = () => (
  <Img
    style={{ backgroundColor: 'grey', width: '480', height: '320' }}
    src="https://the-image-url"
    alt="React Cool Img"
  />
);

API

The image component working similar with standard img tag and with the following props.

Prop Type Default Description
src string Image source. It's required
Support formats
srcSet string Image sources for responsive images. For src prop only
Reference article
sizes string Image sizes for responsive images. For src prop only
Reference article
width string Width of the image in px
height string Height of the image in px
placeholder string Placeholder image source
Support formats
error string Error image source. It'll replace Placeholder image
Support formats
alt string An alternate text for an image section
decode boolean true Use img.decode() to pre-decode the image before render it. Useful to prevent main thread from blocking by decoding of large image
lazy boolean true Turn on/off lazy loading
Using Intersection Observer
cache boolean true Instantly load images which have been cached when possible to abort the lazy loading behavior
Reference article
debounce number 300 How much to wait in milliseconds that the image has to be in viewport before starting to load. This can prevent images from being downloaded while the user scrolls quickly past them
observerOptions object { root: null, rootMargin: '50px', threshold: 0.01 } See the observerOptions section
retry object { count: 3, delay: 2, acc: '*' } See the retry section
... Find more props and events

observerOptions

All the properties are optional.

  • root: Element | null - the element that is used as the viewport for checking visibility of the target. Must be the ancestor of the target. Defaults to the browser viewport if not specified or if null.
  • rootMargin: string - margin around the root. Can have values similar to the CSS margin property, e.g. '10px 20px 30px 40px' (top, right, bottom, left). The values can be percentages. This set of values serves to grow or shrink each side of the root element's bounding box before computing intersections.
  • threshold: number - a single number between 0 and 1, which indicate at what percentage of the target's visibility the observer's callback should be executed. A value of 0 means as soon as even one pixel is visible, the callback will be run. 1 means that the threshold isn't considered passed until every pixel is visible.

retry

All the properties are optional.

  • count: number - specifies the number of times you want to retry. Set it to 0 will disable auto-retry.
  • delay: number - specifies the delay between retries in seconds.
  • acc: string | false - specifies how the delay should be accumulated with each retry. It accepts the following values:
    • '*' (default) - multiply delay after each subsequent retry by the given delay value, e.g. delay: 2 means retry will run after 2 seconds, 4 seconds, 8 seconds, and so on.
    • '+' - increment delay after each retry by the given delay value, e.g. delay: 2 means retry will run after 2 seconds, 4 seconds, 6 seconds, and so on.
    • false - keep the delay constant between retries, e.g. delay: 2 means retry will run every 2 seconds.

The Smart Way to Load Images

Lazy image loading via the Intersection Observer API is good. But could it be greater to download an image only when user want to see it? Or bypass lazy loading for cached images? The answer is yes and these features already be built into react-cool-img by the debounce and cache props.

By the debounce prop, an image can wait to be downloaded while it's in the viewport for a set time. In cases where you have a long list of images that the user might scroll through inadvertently. At this time loading images can cause unnecessary waste of bandwidth and processing time.

import Img from 'react-cool-img';

import defaultImg from './images/default.svg';

const App = () => (
  <Img
    placeholder={defaultImg}
    src="https://the-image-url"
    debounce={1000} // Default is 300 (ms)
    alt="React Cool Img"
  />
);

By the cache prop, images you already have cached will abort lazy loading until user visit your app next time. Lazy loading is set up for any remaining images which were not cached. This is helpful for UX, because there's not much extra work to load cached images immediately and is an easy win for making the UI looks more intuitive.

import Img from 'react-cool-img';

import defaultImg from './images/default.svg';

const App = () => (
  <Img
    placeholder={defaultImg}
    src="https://the-image-url"
    cache // Default is true, just for demo
    alt="React Cool Img"
  />
);

JavaScript Availability and SEO

There're two challenges when doing lazy image loading with server-side rendering. One is Javascript availability the other is SEO. Fortunately, we can use <noscript> tag to solve these problems. It will render the actual image as fallback if Javascript is disabled thus user won't see the image which be stuck with the placeholder. Moreover, the <noscript> tag ensure the image is indexed by search engine bots even if they cannot fully understand our JavaScript code. Take a look at how magic happens.

// src/Img/index.tsx

const Img = () => {
  // ...

  return (
    <>
      <img
        class="image"
        src="https://the-placeholder-image"
        alt="There's no magic"
      />
      <noscript>
        <img
          class="image"
          src="https://the-actual-image"
          alt="The magic begins in here..."
        />
      </noscript>
    </>
  );
};

Intersection Observer Polyfill

Intersection Observer has good support amongst browsers, but it's not universal. You'll need to polyfill browsers that don't support it. Polyfills is something you should do consciously at the application level. Therefore react-cool-img doesn't include it.

You can use W3C's polyfill:

$ yarn add intersection-observer
# or
$ npm install --save intersection-observer

Then import it at your app's entry point:

import 'intersection-observer';

Or load the polyfill only if needed:

if (!window.IntersectionObserver) require('intersection-observer');

Polyfill.io is an alternative way to add the polyfill when needed.

Contributors โœจ

Thanks goes to these wonderful people (emoji key):


Welly

๐Ÿ’ป ๐Ÿ“– ๐Ÿšง

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

react-cool-img's People

Contributors

allcontributors[bot] avatar greenkeeper[bot] avatar wellyshen avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.