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
0
540
The Art of Lazy Loading
The magic of lazy loading images and splitting bundles ✨
Houssein Djirdeh
October 03, 2018
Tweet
Share
More Decks by Houssein Djirdeh
See All by Houssein Djirdeh
Performance Empathy
housseindjirdeh
0
200
GitPoint - Lunch and Learn
housseindjirdeh
0
120
Progressive Web Apps - fullStackTO/FITC Web Unleashed
housseindjirdeh
0
210
Once you go PRPL - FullStackFest
housseindjirdeh
0
36
Once you go PRPL: SeattleJS
housseindjirdeh
0
190
Other Decks in Technology
See All in Technology
九州の人に知ってもらいたいGISスポット / gis spot in kyushu 2025
sakaik
0
140
GMOペパボのデータ基盤とデータ活用の現在地 / Current State of GMO Pepabo's Data Infrastructure and Data Utilization
zaimy
3
210
✨敗北解法コレクション✨〜Expertだった頃に足りなかった知識と技術〜
nanachi
1
690
Amazon Q と『音楽』-ゲーム音楽もAmazonQで作成してみた感想-
senseofunity129
0
140
dipにおけるSRE変革の軌跡
dip_tech
PRO
1
260
ロールが細分化された組織でSREと協働するインフラエンジニアは何をするか? / SRE Lounge #18
kossykinto
0
210
Amazon GuardDuty での脅威検出:脅威検出の実例から学ぶ
kintotechdev
0
100
Agent Development Kitで始める生成 AI エージェント実践開発
danishi
0
140
Google Cloud で学ぶデータエンジニアリング入門 2025年版 #GoogleCloudNext / 20250805
kazaneya
PRO
20
4.9k
Claude CodeでKiroの仕様駆動開発を実現させるには...
gotalab555
3
1k
Kiroでインフラ要件定義~テスト を実施してみた
nagisa53
3
340
オブザーバビリティプラットフォーム開発におけるオブザーバビリティとの向き合い / Hatena Engineer Seminar #34 オブザーバビリティの実現と運用編
arthur1
0
380
Featured
See All Featured
StorybookのUI Testing Handbookを読んだ
zakiyama
30
6k
Adopting Sorbet at Scale
ufuk
77
9.5k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
Speed Design
sergeychernyshev
32
1.1k
A designer walks into a library…
pauljervisheath
207
24k
Navigating Team Friction
lara
188
15k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Producing Creativity
orderedlist
PRO
347
40k
We Have a Design System, Now What?
morganepeng
53
7.7k
Balancing Empowerment & Direction
lara
1
540
It's Worth the Effort
3n
185
28k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
750
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