Skip to content

Commit 22ef3c4

Browse files
committed
yall.s 2.0.0 release.
1 parent 7b1c7d2 commit 22ef3c4

File tree

7 files changed

+90
-67
lines changed

7 files changed

+90
-67
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ script:
77
- npm run build
88
branches:
99
only:
10-
- shadowfax
10+
- master

README.md

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
# yall.js (Yet Another Lazy Loader)
22

3-
[![Build Status](https://travis-ci.org/malchata/yall.js.svg?branch=shadowfax)](https://travis-ci.org/malchata/yall.js) ![](http://img.badgesize.io/malchata/yall.js/shadowfax/dist/yall-2.0.0b.min.js?label=Uncompressed) ![](http://img.badgesize.io/malchata/yall.js/shadowfax/dist/yall-2.0.0b.min.js?compression=gzip&label=gzip)
3+
[![Build Status](https://travis-ci.org/malchata/yall.js.svg?branch=shadowfax)](https://travis-ci.org/malchata/yall.js) ![](http://img.badgesize.io/malchata/yall.js/shadowfax/dist/yall-2.0.0.min.js?label=Uncompressed) ![](http://img.badgesize.io/malchata/yall.js/shadowfax/dist/yall-2.0.0.min.js?compression=gzip&label=gzip)
44

5-
**Warning: This is a beta version, and has not been extensively tested in all browsers. It is _not_ production ready!**
6-
7-
yall.js is a featured-packed lazy loading library for `<img>`, `<picture>`, `<video>` and `<iframe>` elements, and works in all modern browsers plus IE11. It uses [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) where available, but falls back to `scroll`, `touchmove`, `resize`, and `orientationchange` events where necessary. It also queries the DOM using `querySelector` and `querySelectorAll`. It can also monitor the DOM for changes using [Mutation Observer](https://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/) to lazy load image elements that have been appended to DOM after initial page render, which can be desirable for single page applications. It can also (optionally) optimize use of browser idle time using [`requestIdleCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback).
5+
yall.js is a featured-packed lazy loading script for `<img>`, `<picture>`, `<video>` and `<iframe>` elements. It works in all modern browsers including IE11. It uses [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) where available, but falls back to `scroll`, `touchmove`, `resize`, and `orientationchange` events where necessary. It can also monitor the DOM for changes using [Mutation Observer](https://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/) to lazy load image elements that have been appended to the DOM after initial page render, which may be desirable for single page applications. It can also (optionally) optimize use of browser idle time using [`requestIdleCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback). To optimize decoding of `<img>` lazy loading for simple `src` and `srcset` use cases, yall.js uses [`Image.decode`](https://www.chromestatus.com/feature/5637156160667648) where available to decode images asynchronously before adding them to the DOM.
86

97
## Usage
108

11-
This is version 2 of yall.js, and introduces some breaking changes over version 1. While the first version only required you to include the script and tag elements with a special class, this script needs to be explicitly initialized like so:
9+
This is version 2 of yall.js, and introduces some breaking changes over version 1. While the first version only required you to include the script and tag elements with a `class` of `lazy`, this script needs to be explicitly initialized like so:
1210

1311
```html
1412
<script src="yall.min.js"></script>
1513
<script>document.addEventListener("DOMContentLoaded", yall);</script>
1614
```
1715

18-
The above syntax is sufficient if you don't want to pass in any options. [If you want to specify some options](#api-options), however, you'll need to use a slightly more verbose syntax:
16+
The above syntax is sufficient if you don't want to pass in any options. [If you want to specify options](#api-options), however, you'll need to use a slightly more verbose syntax:
1917

2018
```html
2119
<script src="yall.min.js"></script>
@@ -28,7 +26,7 @@ The above syntax is sufficient if you don't want to pass in any options. [If you
2826
</script>
2927
```
3028

31-
Lazy loading elements with yall is simple! Let's look at the simplest `<img>` element use case:
29+
From there, lazy loading elements with yall.js is simple! Let's look at the simplest `<img>` element use case:
3230

3331
```html
3432
<!-- A simple src-only <img> element example -->
@@ -61,85 +59,98 @@ You can also use yall.js to lazy load `<video>` elements! This is useful if you
6159
</video>
6260
```
6361

64-
The pattern is largely the same as it is with the `<picture>` use case, only the `lazy` class is applied to the `<video>` element. **Pro tip**: If you're embedding videos that don't emulate animated GIF behavior (i.e., non autoplaying video), it's better to lean on the [`preload` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#attr-preload) to defer loading rather than using yall.js.
62+
The pattern is largely the same as it is with the `<picture>` use case, only the `lazy` class is applied to the `<video>` element. **Tip**: If you're embedding videos that don't emulate animated GIF behavior (i.e., non autoplaying video), it's better to _not_ lazy load them. Instead, lean on the [`preload` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#attr-preload) to defer loading of video content.
6563

66-
As of version 2, you can also lazy load `<iframe>` elements! This looks pretty much just like a simple `<img>` example:
64+
As of version 2, you can also lazy load `<iframe>`s! This looks pretty much just like a simple `<img>` example:
6765

6866
```html
69-
<iframe class="lazy" data-src="some-other-document.html">
67+
<iframe class="lazy" data-src="some-other-document.html"></iframe>
7068
```
7169

7270
## What about users without JavaScript?
7371

7472
Easy! Slap on some `<noscript>` goodness:
7573

7674
```html
77-
<!-- For users without JavaScript -->
78-
<img class="lazy" data-src="/img/image-to-lazy-load.jpg" src="/img/placeholder.jpg" alt="Alternative text to describe image.">
75+
<!-- A <noscript> example using <img> with src and srcset. -->
76+
<img class="lazy" data-srcset="/img/image-to-lazy-load-2x.jpg 2x, /img/image-to-lazy-load-1x.jpg 1x" data-src="/img/image-to-lazy-load-1x.jpg" src="/img/placeholder.jpg" alt="Alternative text to describe image.">
7977
<noscript>
80-
<img src="/img/image-to-lazy-load.jpg" alt="Alternative text to describe image.">
78+
<img class="lazy" srcset="/img/image-to-lazy-load-2x.jpg 2x, /img/image-to-lazy-load-1x.jpg 1x" src="/img/image-to-lazy-load-1x.jpg" alt="Alternative text to describe image.">
8179
</noscript>
8280

83-
<!-- Here's a <video> example, too -->
81+
<!-- And a <picture> example. -->
82+
<picture>
83+
<source data-srcset="/img/image-to-lazy-load-2x.webp 2x, /img/image-to-lazy-load-1x.webp 1x" type="image/webp">
84+
<img class="lazy" data-srcset="/img/image-to-lazy-load-2x.jpg 2x, /img/image-to-lazy-load-1x.jpg 1x" data-src="/img/image-to-lazy-load-1x.jpg" src="/img/placeholder.jpg" alt="Alternative text to describe image.">
85+
</picture>
86+
<noscript>
87+
<picture>
88+
<source srcset="/img/image-to-lazy-load-2x.webp 2x, /img/image-to-lazy-load-1x.webp 1x" type="image/webp">
89+
<img class="lazy" srcset="/img/image-to-lazy-load-2x.jpg 2x, /img/image-to-lazy-load-1x.jpg 1x" src="/img/image-to-lazy-load-1x.jpg" alt="Alternative text to describe image.">
90+
</picture>
91+
</noscript>
92+
93+
<!-- Here's a <video> example, too. -->
8494
<video class="lazy" autoplay loop muted playsinline>
85-
<source data-src="video.webm" type="video/webm">
86-
<source data-src="video.ogv" type="video/ogg">
87-
<source data-src="video.mp4" type="video/mp4">
95+
<source data-src="video.webm" type="video/webm">
96+
<source data-src="video.ogv" type="video/ogg">
97+
<source data-src="video.mp4" type="video/mp4">
8898
</video>
8999
<noscript>
90-
<video autoplay loop muted playsinline>
91-
<source src="video.webm" type="video/webm">
92-
<source src="video.ogv" type="video/ogg">
93-
<source src="video.mp4" type="video/mp4">
94-
</video>
100+
<video autoplay loop muted playsinline>
101+
<source src="video.webm" type="video/webm">
102+
<source src="video.ogv" type="video/ogg">
103+
<source src="video.mp4" type="video/mp4">
104+
</video>
95105
</noscript>
96106

97-
<!-- Here's an <iframe> example for good measure -->
107+
<!-- Here's an <iframe> example for good measure. -->
98108
<iframe class="lazy" data-src="lazy.html"></iframe>
99109
<noscript>
100110
<iframe src="lazy.html"></iframe>
101111
</noscript>
102112
```
103113

104-
Then place a `no-js` class on the `<html>` element, and finally add this JavaScript one-liner in the `<head>` of the document:
114+
Then place a `no-js` class on the `<html>` element like so:
115+
116+
```html
117+
<html class="no-js">
118+
```
119+
120+
Finally, add this one line `<script>` before any `<link>` or `<style>` elements in the document `<head>`:
105121

106122
```html
107123
<!-- Remove the no-js class on the <html> element if JavaScript is on -->
108-
<script>document.documentElement.classList.remove("no-js");</script>
124+
<script>document.documentElement.classList.remove("no-js")</script>
109125
```
110126

111-
This snippet will remove the `no-js` class from the `<html>` element as the page loads, but if JavaScript is turned off, this will never happen. From there, you can add some CSS that hides elements with a class of `lazy` when the `no-js` class is present on the `<html>` element:
127+
Normally, this script will remove the `no-js` class from the `<html>` element as the page loads, but if JavaScript is turned off, this will never happen. From there, you can add some CSS that hides elements with a `class` of `lazy` when the `no-js` class is present on the `<html>` element:
112128

113129
```css
114130
/* Hide .lazy elements if JavaScript is off */
115-
.no-js .lazy{
131+
.no-js .lazy {
116132
display: none;
117133
}
118134
```
119135

120-
To see all use cases in action, check out the demos in the `test` folder and go from there.
136+
To see all use cases in action, check out the demos in the `test` folder.
121137

122138
## API options
123139

124-
_**Note:** These are not stable, yet! Some may change before version 2 is out of beta!_
125-
126-
When you call the main `yall` initializing function, you can pass an object in with some configuration options. Here are the current options available:
140+
When you call the main `yall` initializing function, you can pass an in an options object. Here are the current options available:
127141

128-
- `lazyClass` (default is `"lazy"`): The element class used by yall.js to find elements to lazy load. Change this is if a class attribute value of `lazy` conflicts with your application.
142+
- `lazyClass` (default is `"lazy"`): The element class used by yall.js to find elements to lazy load. Change this is if a `class` attribute value of `lazy` conflicts with your application.
129143
- `throttleTime` (default is `200`): In cases where Intersection Observer isn't available, standard event handlers are used. `throttleTime` allows you to control how often the code within these event handlers fire in milliseconds.
130-
- `idlyLoad` (default is `false`): If set to `true`, `requestIdleCallback` is used to optimize use of browser idle time to limit monopolization of the main thread. _**Note:** Enabling this could cause lazy loading to be delayed significantly more than you might be okay with! This option trades off some degree of seamless lazy loading in favor of optimized use of browser idle time. Test extensively!_
144+
- `idlyLoad` (default is `false`): If set to `true`, `requestIdleCallback` is used to optimize use of browser idle time to limit monopolization of the main thread. _**Notes:** This setting is ignored if set to `true` in a browser that doesn't support `requestIdleCallback`! Additionally, enabling this could cause lazy loading to be delayed significantly more than you might be okay with! This option trades off some degree of seamless lazy loading in favor of optimized use of browser idle time. Test extensively, and consider increasing the `threshold` option if you set this option to `true`!_
131145
- `idleLoadTimeout` (default is `100`): If `idlyLoad` is set to `true`, this option sets a deadline in milliseconds for `requestIdleCallback` to kick off lazy loading for an element.
132-
- `threshold` (default is `200`): The threshold (in pixels) for how far elements need to be within the viewport to begin lazy loading. This value affects lazy loading using Intersection Observer, as well as for legacy loading behavior relying on event handlers.
133-
- `observeChanges` (default is `false`): Use a Mutation Observer to examine the DOM for changes. This is useful if you're using yall.js in a single page application and want to lazy load resources for markup injected into page after the initial page render. _**Note:** This option is ignored if set to `true` in a browser that doesn't support Mutation Observer!_
146+
- `threshold` (default is `200`): The threshold (in pixels) for how far elements need to be within the viewport to begin lazy loading. This value affects lazy loading initiated by both Intersection Observer and legacy event handlers.
147+
- `observeChanges` (default is `false`): Use a Mutation Observer to examine the DOM for changes. This is useful if you're using yall.js in a single page application and want to lazy load resources for markup injected into the page after initial page render. _**Note:** This option is ignored if set to `true` in a browser that doesn't support Mutation Observer!_
134148
- `observeRootSelector` (default is `"body"`): If `observeChanges` is set to `true`, the value of this string is fed into `document.querySelector` to limit the scope in which the Mutation Observer looks for DOM changes. `document.body` is inferred by default, but you can confine it to any valid CSS selector (e.g., `div#main-wrapper`).
135149
- `mutationObserverOptions` (default is `{childList: true}`): Options to pass to the `MutationObserver` instance. Read [this MDN guide](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#MutationObserverInit) for a list of options.
136-
- `intersectionObserverOptions` (default is `{rootMargin: ${options.threshold}px 0%}`): Options to pass to the `IntersectionObserver` instance. Read [this MDN guide](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Intersection_observer_options) for a list of options. _**Note:** You are probably better off not modifying this, as doing so could drop the `rootMargin` value if you're not careful. Future developments will probably incorporate specific options to pass into the API to avoid detrimental effects to functionality._
137150

138151
## Limitations
139152

140-
Currently, yall.js doesn't provide an error handling mechanism. I'm currently trying to decide if this is worth implementing. In the meantime, you may want to make use of an inline `onerror` handler in your code.
141-
142-
Additionally, yall.js also doesn't care about placeholders, and it won't try to minimize layout shifting or perform any layout calculations for you. The recommended method is to use a placeholder method such as [LQIP](https://www.guypo.com/introducing-lqip-low-quality-image-placeholders/) or [SQIP](https://github.com/technopagan/sqip) to fill the image space prior to lazy loading in conjunction with appropriate `width` and `height` attributes on elements. For `<video>` elements, use the `poster` attribute set a placeholder image. Please check out `index.html` in the `test` folder to see how you might use placeholders in conjunction with yall.js. If you don't want to bother with placeholders, you can omit the `src` attribute entirely in your lazy loading markup and yall.js will still work. Alternatively, you could calculate placeholder size in CSS using the `padding-top` trick.
153+
yall.js doesn't care about placeholders. It won't try to minimize layout shifting or perform layout calculations for you. It's recommended to use a placeholder method such as [LQIP](https://www.guypo.com/introducing-lqip-low-quality-image-placeholders/) or [SQIP](https://github.com/technopagan/sqip) to fill the image space prior to lazy loading in conjunction with appropriate `width` and `height` attributes on elements. For `<video>` elements, use the `poster` attribute set a placeholder image. Please check out the `test` folder to see how you might use placeholders in conjunction with yall.js. If you don't want to bother with placeholders, you can omit the `src` attribute entirely in your lazy loading markup, and yall.js will still work.
143154

144155
## Contributing
145156

0 commit comments

Comments
 (0)