Reshoot

Auto-generate responsive images

Overview

Reshoot is a JavaScript library that makes rendering responsive and lazy-loaded images effortless and without overhead.

Background

The images on this website are all powered by Reshoot.

Problem

Getting responsive image loading right is hard. Only the image in the right dimension should be downloaded by the browser to save bandwidth. A preview placeholder should be shown before the completion of download to improve user experience. Moreover, cross-browser compatibility and error handling is non-trivial to cater for.

Introduction

Reshoot aims at being the last responsive image loading you ever need by helping you to:

  • generate low-quality image preview (lqip) and HTML5 image srcset
  • minify image asset for different screen resolutions and DPIs
  • render responsive, smart and lazy-loaded images in React project effortlessly and without overhead

It consists of three parts.

  • webpack-loader that emits low-quality image preview (lqip) and responsive images, and returns meta info of the images
  • babel-macro that transpile reshoot('image.jpg', { a: 1, b: 2 }) into require('image.jpg!@reshoot/loader?a=1&b=2')
  • React component that is even faster and sleeker than the legendary react-ideal-image

Usage

Add the following loader config to Webpack config.

{
  loader: '@reshoot/loader',
  options: {
    name: '[contenthash:8].[ext]',
    shape: { mime: false }
  }
}

Import @reshoot/macro and @reshoot/react.

import React from 'react';
import { render } from 'react-dom';

import Reshoot from '@reshoot/react';
import reshoot from '@reshoot/macro';

sessionStorage.clear();

const color = '#FDDFB0';

function Example({ title }) {
  return (
    <React.Fragment>
      <h2 style={{ paddingLeft: 10 }}>{title}</h2>
      <div className="grid-container">
        <Reshoot {...reshoot('./image.jpg', { color })} />
        <Reshoot
          {...reshoot('./image.jpg', { color })}
          src="image.jpg"
          srcSet={null}
        />
        <Reshoot {...reshoot('./image.jpg', { color })} placeholder={false} />
      </div>
    </React.Fragment>
  );
}

render(
  <Example title="Client-side Rendered" />,
  document.getElementById('root')
);