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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Houssein Djirdeh
October 03, 2018
Technology
0
560
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
210
GitPoint - Lunch and Learn
housseindjirdeh
0
120
Progressive Web Apps - fullStackTO/FITC Web Unleashed
housseindjirdeh
0
220
Once you go PRPL - FullStackFest
housseindjirdeh
0
42
Once you go PRPL: SeattleJS
housseindjirdeh
0
190
Other Decks in Technology
See All in Technology
2人で作ったAIダッシュボードが、開発組織の次の一手を照らした話― Cursor × SpecKit × 可視化の実践 ― Qiita AI Summit
noalisaai
1
370
Mosaic AI Gatewayでコーディングエージェントを配るための運用Tips / JEDAI 2026 新春 Meetup! AIコーディング特集
genda
0
150
MySQLのJSON機能の活用術
ikomachi226
0
140
SREが向き合う大規模リアーキテクチャ 〜信頼性とアジリティの両立〜
zepprix
0
380
Bill One 開発エンジニア 紹介資料
sansan33
PRO
4
17k
コスト削減から「セキュリティと利便性」を担うプラットフォームへ
sansantech
PRO
3
1.1k
日本の85%が使う公共SaaSは、どう育ったのか
taketakekaho
1
120
今日から始めるAmazon Bedrock AgentCore
har1101
4
380
変化するコーディングエージェントとの現実的な付き合い方 〜Cursor安定択説と、ツールに依存しない「資産」〜
empitsu
4
1.3k
Webhook best practices for rock solid and resilient deployments
glaforge
1
240
15 years with Rails and DDD (AI Edition)
andrzejkrzywda
0
160
GCASアップデート(202510-202601)
techniczna
0
250
Featured
See All Featured
Building an army of robots
kneath
306
46k
Claude Code のすすめ
schroneko
67
210k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.4k
We Are The Robots
honzajavorek
0
160
Rebuilding a faster, lazier Slack
samanthasiow
85
9.4k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
0
430
HDC tutorial
michielstock
1
350
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
910
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
920
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
160
Context Engineering - Making Every Token Count
addyosmani
9
640
Imperfection Machines: The Place of Print at Facebook
scottboms
269
14k
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