Package Exports
- react-cool-img
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-cool-img) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
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
Features
- 🖼 Placeholders for satisfying various image loading states (e.g. loading image > actual image > error image).
- 🛋 Lazy image loading with modern, performant implementation, using IntersectionObserver.
- ⏳ An image can wait to be downloaded while it's in the viewport (and user is seeing it) for a set time by debounce.
- 🤖 Built-in auto-retry mechanism. User won't miss out your important information.
- 🚫 Abort any current image downloads on component unmount potentially saving bandwidth and browser resources.
- 🔍 Support server-side rendering.
- 📜 Support TypeScript type definition.
- 🦠 Tiny size (~ 2kB gzipped). No external dependencies, aside for the
react
andreact-dom
. - 🔧 Easy to use.
⚠️ 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://a-cool-image"
error={errorImage}
alt="React Cool Img"
/>
);
Don't want an image placeholder? No worries, you can use CSS or inline styles 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: 'silver', width: '480', height: '320' }}
src="https://a-cool-image"
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 | |
lazy |
boolean | true |
Turn on/off lazy-loading Using Intersection Observer |
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 |
observerConfig |
object | { root: null, rootMargin: '50px', threshold: 0.01, debounce: 300 } |
See the observerConfig section |
retry |
object | { count: 3, delay: 2, acc: '*' } |
See the retry section |
... |
Find more props and events |
observerConfig
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 ifnull
.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.debounce: number
- specifies how much to wait in milliseconds that the image has to be in viewport before starting to load. This can help avoid wasting bandwidth and processing time while the user scrolls quickly past them. A value of 0 means the image to be loaded immediately.
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 givendelay
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 givendelay
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.
Intersection Observer Polyfill
Intersection Observer API has already gained wide support by most modern browsers (check it). If you wish to support full browser then you need polyfill.
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.