jlengstorf/responsive-lazyload.js

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# Lazyload Images Responsively

[![Build Status](https://travis-ci.org/jlengstorf/responsive-lazyload.js.svg?branch=master)](https://travis-ci.org/jlengstorf/responsive-lazyload.js) [![Code Climate](https://codeclimate.com/github/jlengstorf/responsive-lazyload.js/badges/gpa.svg)](https://codeclimate.com/github/jlengstorf/responsive-lazyload.js) [![Test Coverage](https://codeclimate.com/github/jlengstorf/responsive-lazyload.js/badges/coverage.svg)](https://codeclimate.com/github/jlengstorf/responsive-lazyload.js/coverage)

This package was inspired by <https://github.com/ivopetkov/responsively-lazy/>. It uses very similar markup, but significantly simplifies the way image replacement is handled under the hood. It also adds an optional fallback for when JavaScript is disabled.

## Quick Start

Check out [the examples](https://git.io/lazyload) for copy-pasteable code and more information about usage.

### Option 1: Using a Build Tool

This example assumes [webpack](https://webpack.github.io/).

#### 1. Install the module using [npm](https://www.npmjs.com/package/responsive-lazyload).

```sh
npm install --save responsive-lazyload
```

#### 2. Include the module and initialize lazyloading.

Load the module and initialize lazyloading in your app's script:

```js
import responsiveLazyload from 'responsive-lazyload';

responsiveLazyload();
```

#### 3. Include the stylesheet.

Include the following in the `<head>` of your document.

```html
<link rel="stylesheet" 
      href="node_modules/responsive-lazyload/dist/responsive-lazyload.min.css">
```

#### 4. Add a lazyloaded image to your markup.

Place the lazyload markup anywhere in your app's markup:

```html
<div class="js--lazyload">
  <img alt="a lazyloaded image"
       src="http://placekitten.com/400/300"
       srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
       data-lazyload="http://placekitten.com/400/300 1x,
                      http://placekitten.com/800/600 2x">
</div>
```

For more information and configuration options, see [the examples](https://jlengstorf.github.io/responsive-lazyload.js/).

### Option 2: Using unpkg

**NOTE:** While unpkg is a fantastic tool, adding additional HTTP requests to your project will slow it down. For that reason, this approach is not recommended.

#### 1. Include the script in your markup.

Just before the closing `</body>` tag, add the lazyloading script:

```html
<script src="https://unpkg.com/responsive-lazyload/dist/responsive-lazyload.umd.js" defer></script>
```

#### 2. Include the styles in your markup.

Include the following in the `<head>` of your document:

```html
<link rel="stylesheet" 
      href="https://unpkg.com/responsive-lazyload/dist/responsive-lazyload.min.css">
```

#### 3. Initialize lazyloading.

The initialization function is stored inside a global object called `responsiveLazyload`. Initialize lazyloading by adding the following just below the script include:

```html
<script>
  responsiveLazyload();
</script>
```

#### 4. Add a lazyloaded image to your markup.

Place the lazyload markup anywhere in your app's markup:

```html
<div class="js--lazyload">
  <img alt="a lazyloaded image"
       src="http://placekitten.com/400/300"
       srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
       data-lazyload="http://placekitten.com/400/300 1x,
                      http://placekitten.com/800/600 2x">
</div>
```

For more information and configuration options, see [the examples](https://jlengstorf.github.io/responsive-lazyload.js/).

## Markup

The markup to implement this is:

```html
<div class="js--lazyload js--lazyload--loading">
  <img alt="image description"
       src="/images/image@2x.jpg"
       srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
       data-lazyload="/images/image-300x150.jpg 300w,
                    /images/image-600x300.jpg 600w,
                    /images/image.jpg 690w,
                    /images/image@2x.jpg 1380w">
</div>
```

### Markup Details

- The classes can be changed, but must be updated in the call to `responsiveLazyload()`.
- The initial `srcset` is a blank GIF, which avoids an unnecessary HTTP request.
- The _actual_ `srcset` is added as `data-lazyload`.

The way `responsiveLazyload()` works is to check if the image is inside the viewport, and — if so — swap out the `srcset` for the `data-lazyload`. This is much simpler than duplicating browser behavior to choose the optimal image size; instead, we just give the browser a `srcset` and let it do its thing.

On browsers that don’t support `srcset`, the regular `src` attribute is used, so this should degrade gracefully.

### Markup With Fallback for Browsers Without JavaScript Enabled

To ensure that an image is still visible, even if JavaScript is disabled, add a `<noscript>` block with the properly marked up image using `srcset` without the lazyloading solution:

```html
<div class="js--lazyload js--lazyload--loading">
  <img alt="image description"
       src="/images/image@2x.jpg"
       srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
       data-lazyload="/images/image-300x150.jpg 300w,
                    /images/image-600x300.jpg 600w,
                    /images/image.jpg 690w,
                    /images/image@2x.jpg 1380w">
  <noscript>
    <img alt="image description"
         src="/images/image@2x.jpg"
         srcset="/images/image-300x150.jpg 300w,
                 /images/image-600x300.jpg 600w,
                 /images/image.jpg 690w,
                 /images/image@2x.jpg 1380w">
  </noscript>
</div>
```

## JavaScript Options

To enable lazyloading, add the following to your initialization script:

```js
import responsiveLazyload from 'responsive-lazyload';

responsiveLazyload({
    containerClass: 'js--lazyload',
    loadingClass: 'js--lazyload--loading',
    callback: () => {},
});
```

option           | default                 | description
---------------- | ----------------------- | -----------------------------------
`containerClass` | `js--lazyload`          | Determines which elements are targeted for lazyloading.
`loadingClass`   | `js--lazyload--loading` | Applied to containers before loading. This is useful for adding loading animations.
`callback`       | `() => {}`              | Fired on _each_ image load. Useful for adding custom functionality after an image has loaded.

## Development

To run this module locally for development, follow these steps:

```sh
# Clone the repo.
git clone git@github.com:jlengstorf/responsive-lazyload.js.git

# Move into the repo.
cd responsive-lazyload.js/

# Install dependencies.
npm install

# Run the build script.
npm run build
```

### Testing

Tests are built using [Jest](https://facebook.github.io/jest/). Run them with:

```sh
npm test

# Or, to remove all the extra crap npm spits out and only show test output:
npm test --silent
```