Skip to content
/ lazy Public
forked from pagespeed-pro/lazy

A lightweight lazy loader based on `window.IntersectionObserver` with tiny fallback for old browsers.

Notifications You must be signed in to change notification settings

ArekZw/lazy

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status Version npm version Latest Stable Version

Lazy Image and Iframe Loader

A lightweight lazy loader based on Intersection Observer V2 with a tiny fallback for old browsers.

$lazy(
   selector, /* string, Node, NodeList or observer config object */
   callback /* optional: custom in-view callback for manual lazy loading */
);	

Documentation is available on docs.style.tools/lazy.

Install via npm

npm install @style.tools/lazy --save

Install via PHP Composer

composer require styletools/lazy

Config

The selector entry accepts multiple configuration formats including a string, an Array, a Node, NodeList or a JSON object with observer configuration.

Simple config

{
   "selector": "[data-src]",
   "threshold": 0.006,
   "rootMargin": "0px"
}

Custom observer config

{
   "selector": "[data-src]",
   "observer": {
      "threshold": 0.006,
      "rootMargin": "0px",
      "trackVisibility": true,
      "delay": 100
   }
}

The array based index config is a compressed format to save size in the HTML document.

  • [0] = selector
  • [1] = threshold OR observer config when an object
  • [2] = rootMargin

Simple config

["[data-src]", 0.006, "0px"]

Custom observer config

["[data-src]", {
   "threshold": 0.006,
   "rootMargin": "0px",
   "trackVisibility": true,
   "delay": 100
}]

Event

When an element enters the viewport the event $lazy is fired on the element. The event contains a reference to the HTML node and the IntersectionObserverEntry.

// listen for $lazy event on any element
$(document)[0].addEventListener('$lazy', console.log);

// selectively listen for $lazy event on images using jQuery
jQuery('img').on('$lazy', console.log);

The event data is available via event.detail.

$lazy event

Custom callback

When using a custom callback the $lazy script essentially functions as a simple in-view solution that can be used for many purposes.

$lazy('div#id', function(entries) {
	// entries is a Array of `IntersectionObserverEntry` or HTML Nodes
	// you need to manually verify if the browser supports Intersection Observer

	if (window.IntersectionObserver) {
		// entries[0] = IntersectionObserverEntry
		// entries[0].target = element
	} else {
		// entries[0] = element
	}
})

data-l JSON config

To enable usage in combination with a strict Content-Security-Policy the script can be configured using a data-l attribute on the script source element.

<script data-l='{
   "selector": "[data-src*=&apos;cdn.domain.com&apos;]", 
   "observer": { 
      "threshold": [1.0],
      "trackVisibility": true,
      "delay": 100
   }
}'>
// dist/lazy-data-attr.js (source)
</script>

Multiple configurations are supported via the special multi-token ||. The token needs to be included at the begining and each configuration needs to be valid JSON.

||{config...}||{second config...}

Polyfill

$lazy includes a polyfill for IntersectionObserver. It can be automatically loaded when using $async.

Example using $async with data-c based config

<script data-c='[
  {
    "ref": "lazy",
    "src": "dist/lazy-data-attr+polyfill.js",
    "attributes": {
     "data-l": "[\"selector\", 0.006, \"0px\"]"
    },
    "load_timing": "domReady",
    "cache": "localstorage"
  },
  {
    "ref": "lazy-polyfill",
    "src": "dist/intersectionobserver-polyfill.js",
    "load_timing": {
      "type": "method",
      "method": "$lazypoly"
    },
    "cache": "localstorage"
  }
]'>
/* $async IIFE with timing and API module */
</script>

In the example, the $async timing method method defines window.$lazypoly which will automatically load the polyfill for browsers that require the polyfill. It uses localStorage for instant loading.

Alternatively, when using $lazy without $async, you can manually define window.$lazypoly with a function that returns a Promise or a object containing a .then method.

window.$lazypoly = function() {

   // load polyfill
   // ...

   return {
      then: function(callback) {

         // wait until polyfill is loaded and resolve callback

         callback();
      }
   }
};

When using $async you can alternatively use window.$lazypoly with a string or a object to pass to $async.js which could load anything.

Alternatively, when including $lazy inline, the data-poly attribute enables to define a string to pass to $async.js.

<script data-l='... lazy config ...' data-poly='... config to pass to $async.js to load polyfill ...'>
// dist/lazy-data-attr+polyfill.js
</script>

Example Performance API timings

$lazy polyfill from localStorage

About

A lightweight lazy loader based on `window.IntersectionObserver` with tiny fallback for old browsers.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 95.0%
  • HTML 5.0%