Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranî)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
1 1
One of the most important things 2
2
when building any website is performance. 3
3
And images have by far the biggest impact on page loading. 4
4
And so it's very important 5
5
that images are optimized on any page. 6
6
And for that, 7
7
we can use a strategy called Lazy Loading Images. 8
8
So, let me show you now 9
9
how to implement that strategy in JavaScript. 10
10
And the effect that I'm talking about is this one. 11
11
So what for what happens with the images 12
12
in this section here? 13
13
So you see, as we approach it, 14
14
it basically starts to load and then once it finished, 15
15
it will get displayed and that placeholder 16
16
which is there in the beginning gets replaced. 17
17
So you see that? 18
18
So let me quickly show you in the HTML how we implement that 19
19
and we're actually already here. 20
20
So, it's these features here 21
21
and so each of these features has an image. 22
22
So, the main ingredient to this lazy loading strategy 23
23
is that we have a very low resolution image, 24
24
which is really small and which is loaded, 25
25
right in the beginning. 26
26
So that's this image here, and you'll see 27
27
that the dimensions are only 200 times 120 in this case. 28
28
So let's actually take a look at that image here. 29
29
And so, you see it's really small 30
30
and it's only 16 kilobytes while the real one, 31
31
so this one called digital, is almost half a megabyte. 32
32
So that's a huge difference 33
33
and that image we then reference here 34
34
in this data-src attribute. 35
35
So that's a special attribute that we can use, 36
36
but any other would work as well. 37
37
So this is not a standard HTML attribute 38
38
but instead it's one of these special data attributes 39
39
that we can do ourselves. 40
40
And so basically the idea is to... 41
41
As we scroll to one of these low resolution images 42
42
we will then replace this low resolution image 43
43
with the one that is here specified 44
44
in the data-src attribute. 45
45
And we then also are gonna remove this class here 46
46
which has kind of this filter, 47
47
which makes this image blurred because without this filter, 48
48
let me show that to you, 49
49
without this, it would look really terrible. 50
50
So too small to change this now here. 51
51
Okay, but let's just remove it here for a second, 52
52
just so you can see what it looks like. 53
53
And so, maybe you can see, or maybe it's too small 54
54
but notice that it's like really pixelated and really ugly. 55
55
And so, I created this filter basically, 56
56
and so it makes it look like this. 57
57
So it hides the fact that it is actually way too small 58
58
for its size. 59
59
So let's put it back here. 60
60
And so this is what this class looks like. 61
61
It's simply a blur filter. 62
62
And so modern CSS allows us to do this really cool effect. 63
63
So, let's implement this and that's actually not too hard 64
64
using the Intersection Observer API, one more time. 65
65
So lazy loading images and so once again, 66
66
this one is really great for performance 67
67
while the other things we did so far are more visual things. 68
68
This one really impacts how your site works and especially 69
69
for your users who might have a slow internet connection 70
70
or a low data plan or a slow cell phone. 71
71
And we always have to think about these users as well. 72
72
Not everyone has a super high end computer 73
73
or the latest phone. 74
74
Anyway, let's start by selecting our images, 75
75
let's call them image targets. 76
76
And this selector is gonna be 77
77
a little bit different this time 78
78
because we don't want to select all the images. 79
79
So, we could simply do a selector of image 80
80
and that would then give us all the images. 81
81
But however not all of them are gonna be lazy loaded, 82
82
for example, this one here, 83
83
or we have some down here somewhere. 84
84
So these avatars here or even this logo, 85
85
so these are not lazy loaded. 86
86
And so, the ones that will be lazy loaded 87
87
are the ones that have this attribute here. 88
88
So, this data-src attribute 89
89
because that's where we specified 90
90
the real high resolution picture. 91
91
And so we can actually select four elements 92
92
which contain this property. 93
93
So if you're familiar with CSS, 94
94
maybe you know how to do that 95
95
but in case you're not, this is how it works. 96
96
So we select all the images which have 97
97
the property of data-src. 98
98
And that's it. 99
99
So, let's check that just to be sure 100
100
so that it's gonna work. 101
101
And so, indeed here we have these three images 102
102
and nothing else. 103
103
Then let's create our image observer 104
104
and so this is not always the same. 105
105
Here's our callback function, 106
106
which I'm gonna call load image in a second 107
107
and then all options. 108
108
And now, let's attach this image observer here basically 109
109
to all these targets. 110
110
So I'm gonna loop one more time over our targets 111
111
just like we did with this section previously. 112
112
And this time, let's actually use an arrow function 113
113
because all we want to do is to use the image observer 114
114
that we created previously to observe each image. 115
115
Now let's create that callback function 116
116
here also pretty fast. 117
117
So it gets the entries and also the observer. 118
118
Okay, that's always starting 119
119
with the options here and again, 120
120
the route set to the entire viewport 121
121
and let's start with the threshold at zero, 122
122
and then we can adjust it as we go. 123
123
But what matters really here is a disc callback function. 124
124
So as always, this is where our functionality is. 125
125
And so again, we have only one threshold, so only one entry. 126
126
So I'm getting that tier. 127
127
and now, let's check out actually this entry. 128
128
So here we already got three of them, 129
129
but all of them are not yet intersecting. 130
130
Well, actually it says that this one is, 131
131
well, but it isn't really because it's down here. 132
132
So, that's a bit weird. 133
133
Oh, but of course this still comes from the sections. 134
134
So this is still coming from up here somewhere. 135
135
Okay, let's delete it here from the sections. 136
136
And now, let's see if it's working 137
137
and now it is indeed an image. 138
138
Now, it appeared a little bit before 139
139
and that's because remember that our sections 140
140
are actually a little bit shifted 141
141
because of this hidden class that we added to them, 142
142
they are shifted 8rem down. 143
143
So remember that from here. 144
144
Let's see. 145
145
Yeah, so because of this translate here, 146
146
they have moved 8rem down. 147
147
And so, then therefore, 148
148
this event will fire a little bit early 149
149
but that's not a problem at all. 150
150
What matters is that the event fired correctly 151
151
and that it is indeed intersecting. 152
152
Let's just clear it here to wait for the next ones. 153
153
And so, here you get to the next one already. 154
154
And so, that is indeed this next lazy image here. 155
155
And then the next one here as well. 156
156
So this one, okay. 157
157
And then, as we're moving out of them, 158
158
then we get even more 159
159
because now they are no longer intersecting. 160
160
And so once again, 161
161
we need to only do something 162
162
if they are actually intersecting. 163
163
So we're gonna use the same guard clause as before. 164
164
So if they are not intersecting, 165
165
then we want an early return. 166
166
But otherwise we now want to replace the src attribute 167
167
with the data.src. 168
168
So as we reach the image, 169
169
it's finally time to replace the placeholder image, 170
170
which is at the src, 171
171
with the one we actually want, which is data-src. 172
172
So just like before, each of these images here 173
173
is at target or actually at entry.target 174
174
So that's the element that's currently being intersected 175
175
and then .src= entry.target.dataset. 176
176
Remember, that's where these special data properties 177
177
are stored and then .src from there. 178
178
So this is already the main functionality right here. 179
179
So let's try that, but you will not really see it happening 180
180
because there's still this blurry filter here on top. 181
181
But if we inspect it now, we should already see 182
182
that the src is now actually already the original image. 183
183
So you see it that it's the really big one 184
184
while the other ones are still the lazy ones. 185
185
Well, at least this one, the second one, 186
186
is already also the original one 187
187
because it's already in the viewport two. 188
188
So, that's great, that's working just fine. 189
189
Now, all we need to do is to then remove that class 190
190
that has this blurred filter. 191
191
So, that's the lazy image class. 192
192
Now, how do we do that? 193
193
Well, it's a little bit tricky 194
194
because this replacing of the src attribute 195
195
actually basically happens behind the scenes. 196
196
So JavaScript finds the new image 197
197
that it should load and display here. 198
198
And it does that behind the scenes. 199
199
And once it's finished loading that image 200
200
it will emit the load event. 201
201
And the load event is just like any other event. 202
202
And so we can just listen for it 203
203
and then do something so on that image. 204
204
So on that image, so that's entry.target, 205
205
we can do, addEventListener, and listen for the load event. 206
206
And actually, let me show you why it is important 207
207
that we do this. 208
208
So let's say that we removed 209
209
that lazy image class right away. 210
210
So entry.target.classList.remove lazy-img. 211
211
Let's scroll up here, reload. 212
212
And then, well, in this case, the loading happens so fast 213
213
that we don't even see a problem. 214
214
Maybe we can change that here in the network tab. 215
215
So this is a completely new tab 216
216
but what we can do here is to simulate or speed. 217
217
So this is a bit too big here, actually, I guess. 218
218
So I'm not used to the size, 219
219
Let me make it a little bit smaller. 220
220
So let's change the tier to fast or to slow 3G. 221
221
And maybe then, we can see what happens. 222
222
So it's not faking that these images 223
223
are loading really slow. 224
224
So did you see them here blurred now? 225
225
So it's really blurred, you see, 226
226
but we already removed the filter. 227
227
And so, here you can see how the image 228
228
is loading basically in the background. 229
229
And so it's doing that really slow now 230
230
because we said that we are on a slow network here 231
231
and now you see it's finished here 232
232
and now the original image is being displayed. 233
233
So, hopefully you could see that. 234
234
I'm not sure if the resolution 235
235
of the video is gonna be good enough to see it 236
236
but I did for sure see it. 237
237
And tear actually now the same as happening. 238
238
Let me increase the size of the window a bit, maybe. 239
239
So you see it's pretty blurred 240
240
but once it's gonna be finished you will then see the final 241
241
and beautiful version showing up here. 242
242
All right, so we're gonna come back 243
243
to this network tab later when we start loading data 244
244
from remote sources on the internet. 245
245
So this is a very important top in browser tools 246
246
but for now, it's also nice 247
247
to see the images loading over time behind the scenes. 248
248
Well, it's taking a lot of time 249
249
so let me just go back to the code here. 250
250
And so yeah, now it's finished actually. 251
251
And so by the time this loading finishes 252
252
it will emit this load event. 253
253
And so it is best to then only remove 254
254
that blurry filter once that's done. 255
255
So it's loading again very slow now 256
256
and you see that now it keeps being blurred 257
257
and it will only disappear 258
258
once the image is in fact loaded. 259
259
So I'm not gonna wait for that 260
260
because it seems like it's gonna take forever. 261
261
Oh, actually it's already done here. 262
262
And so, you'll see now the image is downloading 263
263
and at the same time the filter appeared 264
264
or actually disappeared. 265
265
Let's set it back to online. 266
266
And so now all of it happens basically at the same time 267
267
because we are working on our local development machine. 268
268
And so there of course the image 269
269
basically arrives instantaneously. 270
270
Now as a last step, we can just, as we did before 271
271
stop observing these images because it's no longer necessary 272
272
we already did our task of loading. 273
273
And so we no longer need this. 274
274
So entry.target and that's it. 275
275
So I hope that with this video, 276
276
I could convince you that it's really important 277
277
to implement this kind of functionality into your own sites. 278
278
So, all you really need to do 279
279
is to generate these placeholder images 280
280
and blurred them a little bit 281
281
and then implement this kind of logic, 282
282
which really shouldn't be too much work. 283
283
Let me just get rid of this console.log here. 284
284
That's a loaded again, because actually we want probably 285
285
to load the images a little bit 286
286
before we actually reached them. 287
287
So ideally we don't want our users to notice 288
288
that we are lazy loading these images 289
289
So all of this should basically happen 290
290
in the background without our user noticing that. 291
291
And so we should probably make these 292
292
images load a little bit earlier. 293
293
So to do that, we can again, 294
294
specify a negative root margin here. 295
295
So root margin of let's say minus 200 pixels. 296
296
And so this is just the same 297
297
as we did previously here with the navigation. 298
298
So to make the navigation load a little bit 299
299
before the threshold was actually reached 300
300
and here we are doing the same 301
301
so exactly 200 pixels before any of the images is loaded. 302
302
It should already start loading. 303
303
And by doing that we don't see any delay 304
304
in loading when we browse the page. 305
305
Well, actually that didn't quite work. 306
306
Maybe it should be plus 200. 307
307
So as you see, this is all a matter 308
308
of trying out and figuring out as we go here. 309
309
And so now indeed, as we approached the images, 310
310
they're already fully loaded. 311
311
So now that happens 200 pixels before we reach them. 312
312
And with that, our functionality here is complete 313
313
and we are now indeed almost finished with this project. 314
314
All that's left to implement is really this slider. 315
315
So this component here. 316
316
And so that is what we're gonna do in the next video.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.