Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
The Art of Lazy Loading
Search
Houssein Djirdeh
October 03, 2018
Technology
580
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
The Art of Lazy Loading
The magic of lazy loading images and splitting bundles ✨
Houssein Djirdeh
October 03, 2018
More Decks by Houssein Djirdeh
See All by Houssein Djirdeh
Performance Empathy
housseindjirdeh
0
220
GitPoint - Lunch and Learn
housseindjirdeh
0
130
Progressive Web Apps - fullStackTO/FITC Web Unleashed
housseindjirdeh
0
230
Once you go PRPL - FullStackFest
housseindjirdeh
0
46
Once you go PRPL: SeattleJS
housseindjirdeh
0
200
Other Decks in Technology
See All in Technology
AIエージェントに財布を渡す日 ― 承認付き"買い物エージェント"を作って実演
yama3133
1
110
toio・myCobotでフィジカルAIっぽいことを行うための検討(とりあえず調査) / フィジカルAI LT(IoTLTによる開催)
you
PRO
0
230
個人OSSが、机の上から世界に広がるまでの話
shinyasaita
1
200
信頼できるテスティングAIをどう育てるか?
odan611
0
180
AI ネイティブな組織に Gemini Enterprise Agent Platform がなぜ必要なのか
asei
1
140
BigQuery を検索ソースとした AI Agent の作り方って 〇〇 通りあんねん
satohjohn
0
150
plamo-3-translateの開発
pfn
PRO
0
240
Data Hubグループ 紹介資料
sansan33
PRO
0
3.1k
SnowflakeCoCoでデータエンジニアリング!
foursue
0
110
セキュリティ研修【MIXI 26新卒技術研修】
mixi_engineers
PRO
32
27k
クラウドセキュリティ入門 ~安全なクラウド利用のための基礎知識~
lhazy
7
5.9k
AIQAのナレッジ構築について
qatonchan
1
140
Featured
See All Featured
Java REST API Framework Comparison - PWX 2021
mraible
34
9.6k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.1k
HDC tutorial
michielstock
2
760
How STYLIGHT went responsive
nonsquared
100
6.2k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
Product Roadmaps are Hard
iamctodd
55
12k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
480
Abbi's Birthday
coloredviolet
3
8.9k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
560
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
Transcript
the art of lazy loading lazy loading @hdjirdeh
lazy defer until the user needs it
loading fetch + render
what?
images!
None
highest high medium low low high highest medium low
highest high medium low low high highest medium low
low highest high medium low low high highest medium
highest high medium low low high highest medium medium low
> 40% of data fetched = images
scroll event listeners
<img class="lazy" data-src="kittens.png"> class="lazy" data-src="kittens.png"
let image = document.querySelector("img.lazy"); const lazyLoad = () "=> {
setTimeout(() "=> { if ( image.getBoundingClientRect().top "<= window.innerHeight "&& image.getBoundingClientRect().bottom ">= 0 ) { image.src = image.dataset.src; } }, 200); }; document.addEventListener("scroll", lazyLoad); let image = document.querySelector("img.lazy"); const lazyLoad = () "=> { setTimeout(() "=> { if ( image.getBoundingClientRect().top "<= window.innerHeight "&& image.getBoundingClientRect().bottom ">= 0 ) { image.src = image.dataset.src; } }, 200); } document.addEventListener("scroll", lazyLoad); };
intersection observer
let image = document.querySelector("img.lazy"); let lazyObserver = new IntersectionObserver(entry "=>
{ if (entry.isIntersecting) { const image = entry.target; image.src = lazyImage.dataset.src; lazyObserver.unobserve(image); } }); lazyObserver.observe(image); let image = document.querySelector("img.lazy"); let lazyObserver = new IntersectionObserver(entry "=> { if (entry.isIntersecting) { const image = entry.target; image.src = lazyImage.dataset.src; lazyObserver.unobserve(image); } }); lazyObserver.observe(image);
bit.ly/inter-obs
native browser feature?
<img lazyload=“on”> lazyload=“on”
None
what else?
code!
None
1 KB of Image 1 KB of JavaScript ≠
split, split, split ✂
import('lodash.sortby') .then(module "=> module.default) .then(doSomethingCool) import('lodash.sortby') .then(module "=> module.default) .then(doSomethingCool)
dynamic import
what should I do?
audit
None
None
None
audit fix ✂
None
Use a library lozad.js lazysizes yall.js
Use IO + polyfill Use a library Use placeholders/ load
early
Use placeholders/ load early pinterest pinterest.com
Use placeholders/ load early lqip-loader github.com/zouhir/lqip-loader
Use placeholders/ load early Primitive primitive.lol
Use placeholders/ load early sqip github.com/technopagan/sqip SQIP LQIP Image
None
export const routes: Routes = [ { path: 'main', component:
'MainComponent', }, { path: 'details', loadChildren: 'details/details.module#DetailsModule' } ]; angular router
const DetailsComponent = () "=> import(‘./details.vue'); export const router =
new VueRouter({ routes: [ { path: '/details', component: DetailsComponent }, ] }) const DetailsComponent = () "=> import(‘./details.vue'); export const router = new VueRouter({ routes: [ { path: '/details', component: DetailsComponent }, ] }) const DetailsComponent = () "=> import(‘./details.vue'); export const router = new VueRouter({ routes: [ { path: '/details', component: DetailsComponent }, ] }) export const router = new VueRouter({ routes: [ { path: '/details', component: DetailsComponent }, ] }) vue router
import { Router } from 'preact-router'; import Home from '"../routes/home';
import Details from 'async!./details'; export const App = () "=> ( <Router> <Home path="/" "/> <Details path="/details/" "/> "</Router> ); import { Router } from 'preact-router'; import Home from '"../routes/home'; import Details from 'async!./details'; export const App = () "=> ( <Router> <Home path="/" "/> <Details path="/details/" "/> "</Router> ); preact cli import { Router } from 'preact-router'; import Home from '"../routes/home'; import Details from 'async!./details'; export const App = () "=> ( <Router> <Home path="/" "/> <Details path="/details/" "/> "</Router> );
const loadPage = (page) "=> (dispatch) "=> { switch(page) {
case 'view1': import('"../my-view1.js').then((module) "=> { "// ""... }); break; "//""... } dispatch(updatePage(page)); }; const loadPage = (page) "=> (dispatch) "=> { switch(page) { case 'view1': import('"../my-view1.js').then((module) "=> { "// ""... }); break; "//""... } dispatch(updatePage(page)); }; const loadPage = (page) "=> (dispatch) "=> { switch(page) { case 'view1': import('"../my-view1.js').then((module) "=> { "// ""... }); break; "//""... } dispatch(updatePage(page)); }; polymer pwa-starter-kit
import Loadable from 'react-loadable'; const DetailsComponent = Loadable({ loader: ()
"=> import('./details.component'), loading: () "=> <div>Loading""..."</div>, }); import Loadable from 'react-loadable'; const DetailsComponent = Loadable({ loader: () "=> import('./details.component'), loading: () "=> <div>Loading""..."</div>, }); import Loadable from 'react-loadable'; const DetailsComponent = Loadable({ loader: () "=> import('./details.component'), loading: () "=> <div>Loading""..."</div>, }); jamiebuilds / react-loadable
import loadable from 'loadable-components'; const DetailsComponent = loadable(() "=> import('./details.component'),
{ LoadingComponent: () "=> <div>Loading""..."</div> }); import loadable from 'loadable-components'; const DetailsComponent = loadable(() "=> import('./details.component'), { LoadingComponent: () "=> <div>Loading""..."</div> }); import loadable from 'loadable-components'; const DetailsComponent = loadable(() "=> import('./details.component'), { LoadingComponent: () "=> <div>Loading""..."</div> }); smooth-code / loadable-components
import LoadableVisibility from ‘react-loadable-visibility/react-loadable' const DetailsComponent = LoadableVisibility({ loader: ()
"=> import('./details.component'), loading: () "=> <div>Loading""..."</div>, }) import LoadableVisibility from ‘react-loadable-visibility/react-loadable' const DetailsComponent = LoadableVisibility({ loader: () "=> import('./details.component'), loading: () "=> <div>Loading""..."</div>, }) import LoadableVisibility from ‘react-loadable-visibility/react-loadable' const DetailsComponent = LoadableVisibility({ loader: () "=> import('./details.component'), loading: () "=> <div>Loading""..."</div>, }) stratiformltd / react-loadable-visibility
None
const DetailsComponent = Loadable({ loader: () "=> import('./details.component'), loading: ()
"=> <div>Loading""..."</div>, delay: 300, }); jamiebuilds / react-loadable const DetailsComponent = Loadable({ loader: () "=> import('./details.component'), loading: () "=> <div>Loading""..."</div>, delay: 300, });
suspense
bit.ly/lazy-metro metro (react native)
None
audit fix ✂ observe
webpack-bundle-analyzer
size-plugin
progressivetooling.com
responsive images with srcset preload critical chunks convert gifs to
.mp4 pre-cache assets using a service worker compress assets remove unused packages module / nomodule
/ Dx Ux
@hdjirdeh