From 5eb01a6510efa906a1733b2f05098e00b9432d8e Mon Sep 17 00:00:00 2001 From: Cristiano Crolla Date: Thu, 22 Dec 2022 17:13:10 +0000 Subject: [PATCH 1/6] WIP: Add lazy loading files --- entry/entry-complete.js | 4 ++- package-lock.json | 5 +-- src/assets/sass/glide.core.scss | 20 +++++++++++ src/components/lazy.js | 63 +++++++++++++++++++++++++++++++++ src/defaults.js | 7 ++++ 5 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 src/components/lazy.js diff --git a/entry/entry-complete.js b/entry/entry-complete.js index 5ff8ef3a..6fbca4d5 100644 --- a/entry/entry-complete.js +++ b/entry/entry-complete.js @@ -17,6 +17,7 @@ import Transition from '../src/components/transition' // Optional components import Swipe from '../src/components/swipe' import Images from '../src/components/images' +import Lazy from '../src/components/lazy' import Anchors from '../src/components/anchors' import Controls from '../src/components/controls' import Keyboard from '../src/components/keyboard' @@ -45,7 +46,8 @@ const COMPONENTS = { Controls, Keyboard, Autoplay, - Breakpoints + Breakpoints, + Lazy } export default class Glide extends Core { diff --git a/package-lock.json b/package-lock.json index d88ade6d..72a5c933 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,12 @@ { "name": "@glidejs/glide", - "version": "3.5.0", + "version": "3.6.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "3.5.0", + "name": "@glidejs/glide", + "version": "3.6.0", "license": "MIT", "devDependencies": { "@babel/core": "^7.16.0", diff --git a/src/assets/sass/glide.core.scss b/src/assets/sass/glide.core.scss index 87f99d7f..389a66b6 100644 --- a/src/assets/sass/glide.core.scss +++ b/src/assets/sass/glide.core.scss @@ -68,4 +68,24 @@ &#{$sm}rtl { direction: rtl; } + + &__lazy__loaded { + -webkit-animation: fadeInFromNone 0.5s ease-in 0s forwards; + animation: fadeInFromNone 0.5s ease-in 0s forwards; + } } + +@keyframes fadeInFromNone { + 0% { + visibility: hidden; + opacity: 0; + } + 1% { + visibility: visible; + opacity: 0; + } + 100% { + visibility: visible; + opacity: 1; + } +} \ No newline at end of file diff --git a/src/components/lazy.js b/src/components/lazy.js new file mode 100644 index 00000000..430bfb7b --- /dev/null +++ b/src/components/lazy.js @@ -0,0 +1,63 @@ +import { throttle } from '../utils/wait' + +export default function (Glide, Components, Events) { + /** + * Holds reference to settings. + * + * @type {Object} + */ + let settings = Glide.settings + + const Lazy = { + mount () { + /** + * Collection of image element to be lazy loaded. + * + * @private + * @type {HTMLCollection} + */ + if (settings.lazy) { + this._slideElements = Components.Html.root.querySelectorAll('.glide__slide') + } + }, + + lazyLoad () { + let length + if (Glide.index + 1 < this._slideElements.length) { + length = Glide.index + 1 + } else { + length = Glide.index + } + for (let i = Glide.index; i <= length; i++) { + const img = this._slideElements[i].getElementsByTagName('img')[0] + if (img && img.classList.contains('glide__lazy')) { + if (!this._slideElements[i].classList.contains('glide__lazy__loaded')) { + this.loadImage(img) + } + } + } + }, + + loadImage (image) { + if (image.dataset.src) { + image.src = image.dataset.src + image.classList.add('glide__lazy__loaded') + image.classList.remove('glide__lazy') + } + } + } + + Events.on(['mount.after'], () => { + if (settings.lazy) { + Lazy.lazyLoad() + } + }) + + Events.on(['move.after'], throttle(() => { + if (settings.lazy) { + Lazy.lazyLoad() + } + }, 100)) + + return Lazy +} diff --git a/src/defaults.js b/src/defaults.js index 88063601..a13e4818 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -197,6 +197,13 @@ export default { */ breakpoints: {}, + /** + * Enable lazy loading. + * + * @type {Boolean} + */ + lazy: false, + /** * Collection of internally used HTML classes. * From 143fe8b87ba0428f32be342855466dc61c31aba4 Mon Sep 17 00:00:00 2001 From: Cristiano Crolla Date: Fri, 30 Dec 2022 20:29:26 +0000 Subject: [PATCH 2/6] Add new withinView function checking if slide is within user window --- src/components/lazy.js | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/components/lazy.js b/src/components/lazy.js index 430bfb7b..2469cb2a 100644 --- a/src/components/lazy.js +++ b/src/components/lazy.js @@ -7,6 +7,7 @@ export default function (Glide, Components, Events) { * @type {Object} */ let settings = Glide.settings + let inView = false const Lazy = { mount () { @@ -17,12 +18,27 @@ export default function (Glide, Components, Events) { * @type {HTMLCollection} */ if (settings.lazy) { - this._slideElements = Components.Html.root.querySelectorAll('.glide__slide') + this._wrapper = Components.Html.root + this._slideElements = this._wrapper.querySelectorAll('.glide__slide') + } + }, + + withinView () { + let rect = this._wrapper.getBoundingClientRect() + + if ( + rect.bottom > 0 && + rect.right > 0 && + rect.top <= (window.innerHeight * settings.lazyScrollThreshold || document.documentElement.clientHeight) * settings.lazyScrollThreshold && + rect.left <= (window.innerWidth * settings.lazyScrollThreshold || document.documentElement.clientWidth * settings.lazyScrollThreshold) + ) { + this.lazyLoad() } }, lazyLoad () { let length + inView = true if (Glide.index + 1 < this._slideElements.length) { length = Glide.index + 1 } else { @@ -43,19 +59,29 @@ export default function (Glide, Components, Events) { image.src = image.dataset.src image.classList.add('glide__lazy__loaded') image.classList.remove('glide__lazy') + image.removeAttribute('data-src') } } } Events.on(['mount.after'], () => { if (settings.lazy) { - Lazy.lazyLoad() + Lazy.withinView() } }) Events.on(['move.after'], throttle(() => { - if (settings.lazy) { + if (settings.lazy && inView) { Lazy.lazyLoad() + } else if (settings.lazy) { + Lazy.withinView() + } + }, 100)) + + document.addEventListener('scroll', throttle(() => { + if (settings.lazy && !inView) { + console.log('Scroll') + Lazy.withinView() } }, 100)) From e5eefe4f9c79193dbfc9b9d3ec092b365534bc7e Mon Sep 17 00:00:00 2001 From: Cristiano Crolla Date: Fri, 30 Dec 2022 20:29:39 +0000 Subject: [PATCH 3/6] Add lazy load defaults --- src/defaults.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/defaults.js b/src/defaults.js index a13e4818..9b72d837 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -204,6 +204,22 @@ export default { */ lazy: false, + /** + * Defines the threshold in which lazy loading will begin. + * For example: a threshold of 1.2 will load the images if the carousel/slider + * is within 120% of the screen width and height + * + * @type {Number} + */ + lazyScrollThreshold: 1.2, + + /** + * Defines the inital amount of slides to be loaded + * + * @type {Number} + */ + lazyInitialSlidesLoaded: 2, + /** * Collection of internally used HTML classes. * From 53d88d448583a1467517945dea24e5b77c1f659f Mon Sep 17 00:00:00 2001 From: Cristiano Crolla Date: Fri, 30 Dec 2022 23:48:59 +0000 Subject: [PATCH 4/6] Add lazyInitalSlidesLoaded default to lazy.js --- src/components/lazy.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/lazy.js b/src/components/lazy.js index 2469cb2a..f89f3a10 100644 --- a/src/components/lazy.js +++ b/src/components/lazy.js @@ -6,7 +6,7 @@ export default function (Glide, Components, Events) { * * @type {Object} */ - let settings = Glide.settings + const settings = Glide.settings let inView = false const Lazy = { @@ -39,8 +39,8 @@ export default function (Glide, Components, Events) { lazyLoad () { let length inView = true - if (Glide.index + 1 < this._slideElements.length) { - length = Glide.index + 1 + if (Glide.index + (settings.lazyInitialSlidesLoaded - 1) < this._slideElements.length) { + length = Glide.index + (settings.lazyInitialSlidesLoaded - 1) } else { length = Glide.index } @@ -80,7 +80,6 @@ export default function (Glide, Components, Events) { document.addEventListener('scroll', throttle(() => { if (settings.lazy && !inView) { - console.log('Scroll') Lazy.withinView() } }, 100)) From 9862c8392b721ef493991512586c7348c6f61da3 Mon Sep 17 00:00:00 2001 From: Cristiano Crolla Date: Sat, 31 Dec 2022 22:36:35 +0000 Subject: [PATCH 5/6] Update for loop i value --- src/components/lazy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/lazy.js b/src/components/lazy.js index f89f3a10..56753101 100644 --- a/src/components/lazy.js +++ b/src/components/lazy.js @@ -44,7 +44,7 @@ export default function (Glide, Components, Events) { } else { length = Glide.index } - for (let i = Glide.index; i <= length; i++) { + for (let i = 0; i <= length; i++) { const img = this._slideElements[i].getElementsByTagName('img')[0] if (img && img.classList.contains('glide__lazy')) { if (!this._slideElements[i].classList.contains('glide__lazy__loaded')) { From 717bdf7d7ec82fc0554162ddbd18a0dfdc266849 Mon Sep 17 00:00:00 2001 From: Cristiano Crolla Date: Tue, 3 Jan 2023 22:30:39 +0000 Subject: [PATCH 6/6] tidyup additional slide calls --- src/components/lazy.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/lazy.js b/src/components/lazy.js index 56753101..0830dc60 100644 --- a/src/components/lazy.js +++ b/src/components/lazy.js @@ -12,7 +12,7 @@ export default function (Glide, Components, Events) { const Lazy = { mount () { /** - * Collection of image element to be lazy loaded. + * Collection of slide elements * * @private * @type {HTMLCollection} @@ -38,9 +38,10 @@ export default function (Glide, Components, Events) { lazyLoad () { let length + const additionSlides = settings.lazyInitialSlidesLoaded - 1 inView = true - if (Glide.index + (settings.lazyInitialSlidesLoaded - 1) < this._slideElements.length) { - length = Glide.index + (settings.lazyInitialSlidesLoaded - 1) + if (Glide.index + additionSlides < this._slideElements.length) { + length = Glide.index + additionSlides } else { length = Glide.index }