From bf3a34d0544b49fcf40f57080c4d6b4ff44750c4 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Wed, 27 Sep 2023 04:44:32 +0800 Subject: [PATCH] perf(core): replace `lazysizes` with browser-level lazy loading (#1267) --- _data/origin/basic.yml | 5 +- _data/origin/cors.yml | 5 +- _includes/embed/twitch.html | 9 +- _includes/embed/youtube.html | 7 +- _includes/head.html | 4 + _includes/js-selector.html | 2 +- _includes/refactor-content.html | 65 +++++--------- _javascript/home.js | 4 +- .../modules/components/img-lazyload.js | 27 ------ _javascript/modules/components/img-loading.js | 31 +++++++ _javascript/modules/plugins.js | 2 +- _javascript/page.js | 4 +- _javascript/post.js | 4 +- _layouts/default.html | 1 - _layouts/home.html | 88 ++++++++++--------- _sass/addon/commons.scss | 79 +++++++---------- _sass/layout/home.scss | 29 ++---- _sass/layout/post.scss | 29 ------ assets/lib | 2 +- 19 files changed, 171 insertions(+), 226 deletions(-) delete mode 100644 _javascript/modules/components/img-lazyload.js create mode 100644 _javascript/modules/components/img-loading.js diff --git a/_data/origin/basic.yml b/_data/origin/basic.yml index 14d865a..9ffc76c 100644 --- a/_data/origin/basic.yml +++ b/_data/origin/basic.yml @@ -35,8 +35,9 @@ magnific-popup: css: /assets/lib/magnific-popup/magnific-popup.css js: /assets/lib/magnific-popup/jquery.magnific-popup.min.js -lazysizes: - js: /assets/lib/lazysizes/lazysizes.min.js +lazy-polyfill: + css: /assets/lib/loading-attribute-polyfill/loading-attribute-polyfill.min.css + js: /assets/lib/loading-attribute-polyfill/loading-attribute-polyfill.umd.min.js clipboard: js: /assets/lib/clipboard/clipboard.min.js diff --git a/_data/origin/cors.yml b/_data/origin/cors.yml index 6d6f496..7322695 100644 --- a/_data/origin/cors.yml +++ b/_data/origin/cors.yml @@ -46,8 +46,9 @@ magnific-popup: css: https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/magnific-popup.min.css js: https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/jquery.magnific-popup.min.js -lazysizes: - js: https://cdn.jsdelivr.net/npm/lazysizes@5.3.2/lazysizes.min.js +lazy-polyfill: + css: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.min.css + js: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.umd.min.js clipboard: js: https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js diff --git a/_includes/embed/twitch.html b/_includes/embed/twitch.html index ab0419a..043d532 100644 --- a/_includes/embed/twitch.html +++ b/_includes/embed/twitch.html @@ -1,4 +1,7 @@ - + frameborder="0" + allowfullscreen="true" + scrolling="no" +> diff --git a/_includes/embed/youtube.html b/_includes/embed/youtube.html index 715063c..640011f 100644 --- a/_includes/embed/youtube.html +++ b/_includes/embed/youtube.html @@ -1,6 +1,9 @@ - + allowfullscreen +> diff --git a/_includes/head.html b/_includes/head.html index 408358f..fb12d99 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -80,6 +80,10 @@ {% endif %} + {% if page.layout == 'post' or page.layout == 'page' or page.layout == 'home' %} + + {% endif %} + {% if page.layout == 'page' or page.layout == 'post' %} diff --git a/_includes/js-selector.html b/_includes/js-selector.html index f6c8e9d..b332f10 100644 --- a/_includes/js-selector.html +++ b/_includes/js-selector.html @@ -12,7 +12,7 @@ {% if page.layout == 'post' or page.layout == 'page' or page.layout == 'home' %} - {% assign urls = urls | append: ',' | append: site.data.origin[type].lazysizes.js %} + {% assign urls = urls | append: ',' | append: site.data.origin[type]['lazy-polyfill'].js %} {% unless page.layout == 'home' %} diff --git a/_includes/refactor-content.html b/_includes/refactor-content.html index cd34d81..b035ef7 100644 --- a/_includes/refactor-content.html +++ b/_includes/refactor-content.html @@ -30,6 +30,7 @@ {% endif %} + {% if _content contains '', @@ -39,7 +40,8 @@ %} {% endif %} - + + {% assign IMG_TAG = ' --> - {% assign _left = _left | replace: 'src=', 'data-src=' %} - {% if _left contains 'class=' %} - {% assign _left = _left | replace: 'class="', 'class="lazyload ' %} - {% else %} - {% assign _left = _left | append: ' class="lazyload"' %} - {% endif %} - - - {% if _lqip %} - {% assign _left = _left | replace: ' lqip=', ' data-lqip="true" src=' %} - {% else %} - {% if _width and _height %} - - {%- capture _svg -%} - src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{ _width }} {{ _height }}'%3E%3C/svg%3E" - {%- endcapture -%} - {% assign _left = _svg | append: ' ' | append: _left %} - {% assign _class = _class | append: ' shimmer' %} + {% if _lqip contains ':' %} + {% assign _lazyload = false %} + {% else %} + {% assign _lqip_alt = 'lqip="' | append: _path_prefix %} + {% assign _left = _left | replace: 'lqip="', _lqip_alt %} {% endif %} + + + {% assign _left = _left | replace: 'src=', 'data-src=' | replace: ' lqip=', ' data-lqip="true" src=' %} + + {% else %} + {% assign _class = _class | append: ' shimmer' %} {% endif %} - - {% assign _left = _left | append: ' data-proofer-ignore' %} + + {% if _lazyload %} + {% assign _left = _left | append: ' loading="lazy"' %} + {% endif %} {% if page.layout == 'home' %} @@ -174,6 +156,7 @@ class="img-link{% unless _lqip %} shimmer{% endunless %}" {% endcapture %} {% assign _img_content = _img_content | slice: 0, _size | append: _class | append: '>' %} + {% else %} {% assign _wrapper_start = _final_src @@ -185,12 +168,12 @@ %} {% assign _img_content = _img_content | append: _wrapper_start %} - {% assign _right = _right | prepend: '> - {% assign _img_content = _img_content | append: debug | append: IMG_TAG | append: _left | append: _right %} + {% assign _img_content = _img_content | append: IMG_TAG | append: _left | append: _right %} {% endfor %} {% if _img_content %} diff --git a/_javascript/home.js b/_javascript/home.js index 70af328..02948c9 100644 --- a/_javascript/home.js +++ b/_javascript/home.js @@ -1,8 +1,8 @@ import { basic, initSidebar, initTopbar } from './modules/layouts'; -import { initLocaleDatetime, imgLazy } from './modules/plugins'; +import { initLocaleDatetime, loadImg } from './modules/plugins'; basic(); initSidebar(); initTopbar(); initLocaleDatetime(); -imgLazy(); +loadImg(); diff --git a/_javascript/modules/components/img-lazyload.js b/_javascript/modules/components/img-lazyload.js deleted file mode 100644 index 6a6c99a..0000000 --- a/_javascript/modules/components/img-lazyload.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Set up image lazy-load - */ - -function stopShimmer($node) { - $node.parent().removeClass('shimmer'); -} - -export function imgLazy() { - const $images = $('main img[data-src]'); - - if ($images.length <= 0) { - return; - } - - /* Stop shimmer when image loaded */ - document.addEventListener('lazyloaded', function (e) { - stopShimmer($(e.target)); - }); - - /* Stop shimmer from cached images */ - $images.each(function () { - if ($(this).hasClass('ls-is-cached')) { - stopShimmer($(this)); - } - }); -} diff --git a/_javascript/modules/components/img-loading.js b/_javascript/modules/components/img-loading.js new file mode 100644 index 0000000..18ed3ac --- /dev/null +++ b/_javascript/modules/components/img-loading.js @@ -0,0 +1,31 @@ +/** + * Setting up image lazy loading and LQIP switching + */ + +export function loadImg() { + const $images = $('main img[loading="lazy"]'); + const $lqip = $('main img[data-lqip="true"]'); + + if ($images.length > 0) { + $images.on('load', function () { + /* Stop shimmer when image loaded */ + $(this).parent().removeClass('shimmer'); + }); + + $images.each(function () { + /* Images loaded from the browser cache do not trigger the 'load' event */ + if ($(this).prop('complete')) { + $(this).parent().removeClass('shimmer'); + } + }); + } + + if ($lqip.length > 0) { + $lqip.each(function () { + /* Switch LQIP with real image url */ + const dataSrc = $(this).attr('data-src'); + $(this).attr('src', encodeURI(dataSrc)); + $(this).removeAttr('data-src data-lqip'); + }); + } +} diff --git a/_javascript/modules/plugins.js b/_javascript/modules/plugins.js index fa7a7dd..fb892e2 100644 --- a/_javascript/modules/plugins.js +++ b/_javascript/modules/plugins.js @@ -1,6 +1,6 @@ export { categoryCollapse } from './components/category-collapse'; export { initClipboard } from './components/clipboard'; -export { imgLazy } from './components/img-lazyload'; +export { loadImg } from './components/img-loading'; export { imgPopup } from './components/img-popup'; export { initLocaleDatetime } from './components/locale-datetime'; export { toc } from './components/toc'; diff --git a/_javascript/page.js b/_javascript/page.js index 7b31813..f13bd2f 100644 --- a/_javascript/page.js +++ b/_javascript/page.js @@ -1,9 +1,9 @@ import { basic, initSidebar, initTopbar } from './modules/layouts'; -import { imgLazy, imgPopup, initClipboard } from './modules/plugins'; +import { loadImg, imgPopup, initClipboard } from './modules/plugins'; basic(); initSidebar(); initTopbar(); -imgLazy(); +loadImg(); imgPopup(); initClipboard(); diff --git a/_javascript/post.js b/_javascript/post.js index 9a5a61b..dc6e28c 100644 --- a/_javascript/post.js +++ b/_javascript/post.js @@ -1,6 +1,6 @@ import { basic, initSidebar, initTopbar } from './modules/layouts'; import { - imgLazy, + loadImg, imgPopup, initLocaleDatetime, initClipboard, @@ -10,7 +10,7 @@ import { basic(); initSidebar(); initTopbar(); -imgLazy(); +loadImg(); imgPopup(); initLocaleDatetime(); initClipboard(); diff --git a/_layouts/default.html b/_layouts/default.html index e2d3894..844ca23 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -1,6 +1,5 @@ --- layout: compress -# Default layout --- diff --git a/_layouts/home.html b/_layouts/home.html index a713383..720f114 100644 --- a/_layouts/home.html +++ b/_layouts/home.html @@ -39,10 +39,13 @@ layout: default {% endfor %} {% endif %} -{% capture content %} +{% capture _content %} +
{% for post in posts %} -
- +
+ + {% assign card_body_col = '12' %} + {% if post.image %} {% if post.image.lqip %} {% capture lqip %}lqip="{{ post.image.lqip }}"{% endcapture %} @@ -55,56 +58,61 @@ layout: default {% assign alt = post.image.alt | xml_escape | default: 'Preview Image' %} - {{ alt }} +
+ {{ alt }} +
+ + {% assign card_body_col = '7' %} {% endif %} -
{% endfor %} -{% endcapture %} - -
- {% include refactor-content.html content=content lang=lang %}
+{% endcapture %} + +{% include refactor-content.html content=_content lang=lang %} {% if paginator.total_pages > 1 %} {% include post-paginator.html %} diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss index 7439330..0fa515f 100644 --- a/_sass/addon/commons.scss +++ b/_sass/addon/commons.scss @@ -71,54 +71,13 @@ a { img { max-width: 100%; height: auto; - transition: all 0.35s ease-in-out; + transition: all 0.7s ease-in-out; - &[data-src] { - &[data-lqip='true'] { - &.lazyload, - &.lazyloading { - -webkit-filter: blur(20px); - filter: blur(20px); - } - } + &[data-lqip='true'] { + $blur: 20px; - &:not([data-lqip='true']) { - &.lazyload, - &.lazyloading { - background: var(--img-bg); - } - - &.lazyloaded { - -webkit-animation: fade-in 0.35s ease-in; - animation: fade-in 0.35s ease-in; - } - } - - &.shadow { - -webkit-filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.08)); - filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.08)); - box-shadow: none !important; /* cover the Bootstrap 4.6.1 styles */ - } - - @extend %img-caption; - } - - @-webkit-keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } - } - - @keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } + -webkit-filter: blur($blur); + filter: blur($blur); } } @@ -349,6 +308,29 @@ sup { /* --- post --- */ +.preview-img { + aspect-ratio: 40 / 21; + width: 100%; + height: 100%; + overflow: hidden; + + @extend %rounded; + + &:not(.no-bg) { + img { + background: var(--img-bg); + } + } + + img { + height: 100%; + -o-object-fit: cover; + object-fit: cover; + + @extend %rounded; + } +} + .post-preview { @extend %rounded; @@ -384,7 +366,6 @@ main { } p { - > img[data-src], > a.popup { &:not(.normal):not(.left):not(.right) { @include align-center; @@ -538,8 +519,8 @@ main { background: var(--shimmer-bg); height: 100%; width: 100%; - -webkit-animation: shimmer 1s infinite; - animation: shimmer 1s infinite; + -webkit-animation: shimmer 1.3s infinite; + animation: shimmer 1.3s infinite; } @-webkit-keyframes shimmer { diff --git a/_sass/layout/home.scss b/_sass/layout/home.scss index 5b43261..7f9fd2e 100644 --- a/_sass/layout/home.scss +++ b/_sass/layout/home.scss @@ -6,8 +6,6 @@ margin-top: 2rem; .card-wrapper { - display: block; - &:hover { text-decoration: none; } @@ -18,27 +16,23 @@ } .card { + border: 0; + background: none; + %img-radius { border-radius: $base-radius $base-radius 0 0; } .preview-img { - height: 10rem; - @extend %img-radius; img { - width: 100%; - height: 100%; - -o-object-fit: cover; - object-fit: cover; - @extend %img-radius; } } .card-body { - min-height: 10.5rem; + height: 100%; padding: 1rem; .card-title { @@ -136,20 +130,13 @@ /* Tablet */ @media all and (min-width: 768px) { + %img-radius { + border-radius: 0 $base-radius $base-radius 0; + } + #post-list { - %img-radius { - border-radius: 0 $base-radius $base-radius 0; - } - .card { - .preview-img { - width: 20rem; - height: 11.55rem; // can hold 2 lines each for title and content - } - .card-body { - min-height: 10.75rem; - width: 60%; padding: 1.75rem 1.75rem 1.25rem 1.75rem; .card-text { diff --git a/_sass/layout/post.scss b/_sass/layout/post.scss index ebc2582..955c958 100644 --- a/_sass/layout/post.scss +++ b/_sass/layout/post.scss @@ -26,26 +26,6 @@ color: var(--text-color); } -.preview-img { - overflow: hidden; - aspect-ratio: 40 / 21; - - @extend %rounded; - - &:not(.no-bg) { - img.lazyloaded { - background: var(--img-bg); - } - } - - img { - -o-object-fit: cover; - object-fit: cover; - - @extend %rounded; - } -} - h1 + .post-meta { > span + span::before { @include dot; @@ -368,10 +348,6 @@ h1 + .post-meta { } @media all and (max-width: 576px) { - .preview-img[data-src] { - margin-top: 2.2rem; - } - .post-tail-bottom { flex-wrap: wrap-reverse !important; @@ -396,9 +372,4 @@ h1 + .post-meta { margin-left: -0.5rem; margin-right: -0.5rem; } - - .preview-img[data-src] { - max-width: 100vw; - border-radius: 0; - } } diff --git a/assets/lib b/assets/lib index 6737eab..f80ba2f 160000 --- a/assets/lib +++ b/assets/lib @@ -1 +1 @@ -Subproject commit 6737eab720e4cdd8330d32053053356f200d8819 +Subproject commit f80ba2f1616496cba34f3fd3eef1564d8fa843cd