Implement lazy load

This commit is contained in:
Eduardo 2019-10-27 11:43:31 +01:00
parent f19382cd17
commit 8b557262c6
14 changed files with 67 additions and 126 deletions

View file

@ -54,9 +54,9 @@
{{> footer}} {{> footer}}
{{!-- Common scripts shared between pages --}} {{!-- Common scripts shared between pages --}}
<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver%2CPromise%2CArray.prototype.includes%2CString.prototype.endsWith%2CString.prototype.startsWith%2CObject.assign%2CNodeList.prototype.forEach"></script>
<script defer src="https://unpkg.com/@tryghost/content-api@1.2.7/umd/content-api.min.js"></script> <script defer src="https://unpkg.com/@tryghost/content-api@1.2.7/umd/content-api.min.js"></script>
<script defer src="{{asset "js/manifest.js"}}"></script> <script defer src="{{asset "js/manifest.js"}}"></script>
<script defer src="{{asset "js/polyfill.js"}}"></script>
<script defer src="{{asset "js/vendor.js"}}"></script> <script defer src="{{asset "js/vendor.js"}}"></script>
<script defer src="{{asset "js/app.js"}}"></script> <script defer src="{{asset "js/app.js"}}"></script>

View file

@ -40,7 +40,7 @@ into the {body} of the default.hbs template --}}
{{/if}} {{/if}}
<div class="m-featured-article__picture"> <div class="m-featured-article__picture">
{{#if feature_image}} {{#if feature_image}}
<div style="background-image: url({{feature_image}});"></div> <div class="lozad" data-background-image="{{feature_image}}"></div>
{{/if}} {{/if}}
</div> </div>
<div class="m-featured-article__meta"> <div class="m-featured-article__meta">

View file

@ -28,10 +28,9 @@ into the {body} of the default.hbs template --}}
{{#foreach authors}} {{#foreach authors}}
<article class="m-article-card as-author"> <article class="m-article-card as-author">
{{#if profile_image}} {{#if profile_image}}
<div class="m-article-card__picture" style="background-image: url({{profile_image}})"> <div class="m-article-card__picture lozad" data-background-image="{{profile_image}}">
{{else}} {{else}}
<div class="m-article-card__picture" <div class="m-article-card__picture lozad" data-background-image="{{asset "images/default-avatar-rectangle.jpg"}}">
style="background-image: url({{asset "images/default-avatar-rectangle.jpg"}})">
{{/if}} {{/if}}
<a href="{{url}}" class="m-article-card__picture-link" aria-label="Author"></a> <a href="{{url}}" class="m-article-card__picture-link" aria-label="Author"></a>
<h3 class="m-article-card__name">{{name}}</h3> <h3 class="m-article-card__name">{{name}}</h3>

View file

@ -6,7 +6,7 @@
{{/is}} {{/is}}
{{#if feature_image}} {{#if feature_image}}
<article class="m-article-card {{post_class}}"> <article class="m-article-card {{post_class}}">
<div class="m-article-card__picture" style="background-image: url({{feature_image}});"> <div class="m-article-card__picture lozad" data-background-image="{{feature_image}}">
{{else}} {{else}}
<article class="m-article-card no-picture {{post_class}}"> <article class="m-article-card no-picture {{post_class}}">
<div class="m-article-card__picture"> <div class="m-article-card__picture">

View file

@ -37,9 +37,9 @@ Also it includes the big submenu.
<a href="{{url}}" class="m-recent-article"> <a href="{{url}}" class="m-recent-article">
<div class="m-recent-article__picture"> <div class="m-recent-article__picture">
{{#if feature_image}} {{#if feature_image}}
<div style="background-image: url({{img_url feature_image size="m"}});"></div> <div class="lozad" data-background-image="{{img_url feature_image size="m"}}"></div>
{{else}} {{else}}
<div style="background-image: url({{asset "images/no-image.png"}});" class="no-image"></div> <div class="no-image lozad" data-background-image="{{asset "images/no-image.png"}}"></div>
{{/if}} {{/if}}
</div> </div>
<h3 class="m-recent-article__title">{{title}}</h3> <h3 class="m-recent-article__title">{{title}}</h3>

View file

@ -1,17 +1,20 @@
import cssVars from 'css-vars-ponyfill' import cssVars from 'css-vars-ponyfill'
import $ from 'jquery' import $ from 'jquery'
import lozad from 'lozad'
import Headroom from "headroom.js" import Headroom from "headroom.js"
import slick from 'slick-carousel' import slick from 'slick-carousel'
import tippy from 'tippy.js' import tippy from 'tippy.js'
import AOS from 'aos' import AOS from 'aos'
import Fuse from 'fuse.js' import Fuse from 'fuse.js'
import {
isRTL,
formatDate
} from './helpers'
cssVars({}) cssVars({})
$(document).ready(() => { $(document).ready(() => {
const isRTL = $('html').attr('lang') === 'ar' || $('html').attr('lang') === 'he' if (isRTL()) {
if (isRTL) {
$('html').attr('dir', 'rtl').addClass('rtl') $('html').attr('dir', 'rtl').addClass('rtl')
} }
@ -95,21 +98,6 @@ $(document).ready(() => {
}) })
} }
function formatDate(date) {
if (date) {
return new Date(date).toLocaleDateString(
document.documentElement.lang,
{
year: 'numeric',
month: 'long',
day: 'numeric'
}
)
}
return ''
}
$openMenu.click(() => { $openMenu.click(() => {
$menu.addClass('opened') $menu.addClass('opened')
toggleScrollVertical() toggleScrollVertical()
@ -217,6 +205,9 @@ $(document).ready(() => {
$('[data-aos]').addClass('no-aos-animation') $('[data-aos]').addClass('no-aos-animation')
} }
const observer = lozad()
observer.observe()
tippy('.js-tooltip') tippy('.js-tooltip')
trySearchFeature() trySearchFeature()

23
src/js/helpers.js Normal file
View file

@ -0,0 +1,23 @@
export const isRTL = () => {
const $html = document.querySelector('html')
return $html.getAttribute('lang') === 'ar' || $html.getAttribute('lang') === 'he'
}
export const isMobile = (width = '768px') => {
return window.matchMedia(`(max-width: ${width})`).matches
}
export const formatDate = (date) => {
if (date) {
return new Date(date).toLocaleDateString(
document.documentElement.lang,
{
year: 'numeric',
month: 'long',
day: 'numeric'
}
)
}
return ''
}

View file

@ -1,8 +1,8 @@
import $ from 'jquery' import $ from 'jquery'
import slick from 'slick-carousel' import slick from 'slick-carousel'
import { isRTL } from './helpers'
$(document).ready(() => { $(document).ready(() => {
const isRTL = $('html').attr('lang') === 'ar' || $('html').attr('lang') === 'he'
const $featuredArticles = $('.js-featured-articles') const $featuredArticles = $('.js-featured-articles')
if ($featuredArticles.length > 0) { if ($featuredArticles.length > 0) {
@ -12,7 +12,7 @@ $(document).ready(() => {
prevArrow: '<button class="m-icon-button in-featured-articles slick-prev" aria-label="Previous"><span class="icon-arrow-left"></span></button>', prevArrow: '<button class="m-icon-button in-featured-articles slick-prev" aria-label="Previous"><span class="icon-arrow-left"></span></button>',
nextArrow: '<button class="m-icon-button in-featured-articles slick-next" aria-label="Next"><span class="icon-arrow-right"></span></button>', nextArrow: '<button class="m-icon-button in-featured-articles slick-next" aria-label="Next"><span class="icon-arrow-right"></span></button>',
mobileFirst: true, mobileFirst: true,
rtl: isRTL rtl: isRTL()
}) })
setTimeout(() => { setTimeout(() => {

View file

@ -1,90 +0,0 @@
import 'promise-polyfill/src/polyfill';
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function (searchElement, fromIndex) {
if (this == null) {
throw new TypeError('"this" is null or is not defined');
}
var o = Object(this);
var len = o.length >>> 0;
if (len === 0) {
return false;
}
var n = fromIndex | 0;
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
while (k < len) {
if (sameValueZero(o[k], searchElement)) {
return true;
}
k++;
}
return false;
}
});
}
if (!String.prototype.endsWith) {
String.prototype.endsWith = function (search, this_len) {
if (this_len === undefined || this_len > this.length) {
this_len = this.length;
}
return this.substring(this_len - search.length, this_len) === search;
};
}
if (!String.prototype.startsWith) {
Object.defineProperty(String.prototype, 'startsWith', {
value: function (search, pos) {
pos = !pos || pos < 0 ? 0 : +pos;
return this.substring(pos, pos + search.length) === search;
}
});
}
if (typeof Object.assign != 'function') {
Object.defineProperty(Object, "assign", {
value: function assign(target, varArgs) {
'use strict';
if (target == null) {
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) {
for (var nextKey in nextSource) {
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true
});
}
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function (callback, thisArg) {
thisArg = thisArg || window;
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}

View file

@ -3,6 +3,10 @@ import slick from 'slick-carousel'
import stickybits from 'stickybits' import stickybits from 'stickybits'
import mediumZoom from 'medium-zoom' import mediumZoom from 'medium-zoom'
import fitvids from 'fitvids' import fitvids from 'fitvids'
import {
isRTL,
isMobile
} from './helpers'
let $aosWrapper = null let $aosWrapper = null
let $progressCircle = null let $progressCircle = null
@ -12,10 +16,6 @@ let lastDocumentHeight = 0
let circumference = 0 let circumference = 0
let isTicking = false let isTicking = false
function isMobile(width = '768px') {
return window.matchMedia(`(max-width: ${width})`).matches
}
function onScrolling() { function onScrolling() {
lastScrollingY = window.pageYOffset lastScrollingY = window.pageYOffset
requestTicking() requestTicking()
@ -102,8 +102,6 @@ function prepareProgressCircle() {
} }
$(document).ready(() => { $(document).ready(() => {
const isRTL = $('html').attr('lang') === 'ar' || $('html').attr('lang') === 'he'
$aosWrapper = $('.js-aos-wrapper') $aosWrapper = $('.js-aos-wrapper')
const $scrollButton = $('.js-scrolltop') const $scrollButton = $('.js-scrolltop')
const $loadComments = $('.js-load-comments') const $loadComments = $('.js-load-comments')
@ -153,7 +151,7 @@ $(document).ready(() => {
} }
} }
], ],
rtl: isRTL rtl: isRTL()
}) })
} }

5
src/package-lock.json generated
View file

@ -8357,6 +8357,11 @@
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
"dev": true "dev": true
}, },
"lozad": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/lozad/-/lozad-1.14.0.tgz",
"integrity": "sha512-uMGxpXBW15JDGVly3p121Y4jlb/OwmXpnMQR5vnb4GxMeK45NGcmlMrRr47fmLxtSdnGRFm0YdJaVXuudPKDaA=="
},
"lru-cache": { "lru-cache": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",

View file

@ -37,6 +37,7 @@
"fuse.js": "^3.4.2", "fuse.js": "^3.4.2",
"headroom.js": "^0.10.3", "headroom.js": "^0.10.3",
"jquery": "^3.3.1", "jquery": "^3.3.1",
"lozad": "^1.14.0",
"medium-zoom": "^1.0.3", "medium-zoom": "^1.0.3",
"promise-polyfill": "8.1.0", "promise-polyfill": "8.1.0",
"slick-carousel": "^1.8.1", "slick-carousel": "^1.8.1",

View file

@ -59,6 +59,20 @@ fieldset {
z-index: 5; z-index: 5;
} }
div[data-loaded="true"],
img[data-loaded="true"] {
opacity: 0;
@include animation('fadeIn 0.5s forwards');
@include keyframes(fadeIn) {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
}
::-webkit-input-placeholder { ::-webkit-input-placeholder {
color: $gray; color: $gray;
} }

View file

@ -16,7 +16,7 @@ mix.webpackConfig({
} }
}); });
mix.js('js/polyfill.js', 'js/') mix.js('js/helpers.js', 'js/')
.js('js/app.js', 'js/') .js('js/app.js', 'js/')
.js('js/home.js', 'js/') .js('js/home.js', 'js/')
.js('js/post.js', 'js/') .js('js/post.js', 'js/')