 So, I think in the last developer diary, I probably got to the point where I had styled things up. Yes, that's where I'd got to. And since then, it's been a lot of plumbing work, if you like, just to do things like offline. But I will come back to that in probably the next entry. In this entry, what I want to talk about is a relatively straightforward thing, which is lazy loading of images. So I say straightforward. I mean straightforward in the sense that it's not an out there concept. I think many of us kind of realize that we probably want to defer loading of some stuff. And many of us would probably do it on something like a scroll basis and possibly even have a scroll handler to do that kind of stuff. Well, well, I've done it. But I've done it without scroll handling. I've used an intersection observer. So I thought I'd show you that little bit of code today. And you could just have a look. I mean, I said that. I said you could have a look. And then I just said it twice. What an idiot. Anyway, let's have a look at what it is. If you look at what's on my screen, you'll see that I've got the site up and I've got the network tab open and it's recording. So that's the network you bit there and it's recording. And when I scroll down here, ready, steady, these two poster images here for these two episodes, the lazy load on the fly based on the scroll position where I say the scroll position based on intersecting with the viewport. So let's have a quick look at what the code looks like for that. I have myself a lazy load images class. And I do a quick check to see where the intersection observer is supported because you'll see what happens here is I basically early on I look for anything which has this JS lazy image class on it. And if it does, then I set things up to go. But if we don't have support for an intersection observer, I just kind of fall back to what I think most of us would do today, which is just go, well, look, I can't do an intersection observer. I'm just going to load everything. And that's okay. I mean, this is a progressive enhancement move. This is something we can use to improve our experiences. And you might say I'm not going to load images immediately. What I'm actually going to do is I'm going to fall back to a scroll handler based one. You might choose to do that. I would suggest typically you want to avoid anything that's coupled to the scroll handling just because it's typically the case that a scroll is an animation and it's very frame rate sensitive. And so you probably want to be careful about doing something that has to fire on a scroll handle a scroll handling. Anyway, done with standing. I've decided that if we don't have an intersection observer, we're not doing anything. But what do we do when we've got an intersection observer available to us? Well, we create one of these and we have it observe all of the images which have the JS lazy image class on it. So if they don't have that class on, we're not bothered. If we do, then we observe them. And what do we observe? Well, we have a threshold, which is how much they have to intersect. By default, it's going to how much does it intersect with the viewport? And I have a 50 pixel margin. So when you imagine the viewport and then add 50 pixels either side, that's the that's the that's the area of interest if you like. And I'm asking, when does an image intersect? Let me know if an image intersects that that viewport plus 50 pixels on either side. And there's a threshold that I need to know. So they what it does is, if you imagine the image being completely inside the viewport, that would have a value of one. If it's completely outside, it's zero. And then as it passes, it's going to go between zero and one. And so there's a threshold. As soon as you pass that threshold, I need to know about the intersection. And that's that's a hard way to hard coded value, which is not point not one. So it's it's one percent, I guess, of overlap between those two areas. So what happens when we do actually see that? Well, you can see I have this dot on intersection, as you can see here, which is called. And we get because it's an observer, we get an array of entries because it's possible that with an observer, you're going to get a backlog of entries because things could go in and out. And by the time you actually get to them, you need to, you know, you need to maybe sort them by date. Actually, I don't know if they already sorted. I should figure that out. In any case, with something like this, it's it's not too bad. I just need to know whether or not they've actually intersected with the viewport. And if they have, I'm fine with just going ahead, you might need to do something a bit more nuanced than your intersection observer callback, where you say, Well, actually, you know, is it, you know, is it the most recent record and all these kind of things? But you can you can see, hopefully that you could do some further work on those records. Right. If I decide or if I find that in my entry that the intersection ratio is less than zero, as in it's it's no longer intersecting or whatever. Don't worry about it. Forget about it. Don't need to know about it. If I have already tagged the image that is now intersecting, if I've tagged it with my handled class, so that's what I do. I tag something. So if something goes in out and then back in again, I don't need to know about it the second time. So the first time it comes in and the first time I see an image intersecting with my viewport, I tag it with this class and say, Right, you're done. And if I see that that handled class is on, then I return. And then the last thing I actually do is preload the image. So how can I put this? We what I do is I actually set a background image and I fade it in. That's just the way I'm choosing to do this particular content. It means that I can have like a placeholder with a little icon. So if it takes a long while to load the image, then we sort of we can just put something up on screen and then fade it in. So I preload the image here, which I have a thing that goes off, makes a new image, sets the source and then does an onload and then resolves the promise. Which you can find inside the utils. In fact, let me show you it since we're here preload images. Then we are making a new image, set the source and then I just use resolve and reject as the handlers for onload and on error. So when the image is actually being preloaded, we apply it. So we find the element that we were talking about, which is, you know, image and find the actual sub element, a child of that, which is as the class of just lazy image content. So you can see I have just lazy image and just lazy image content as my two classes. If I can't find it, don't worry about it. If I can, I set the background image and then I add this fade in, which is an animation that fades the opacity from zero to one. So the idea of preloading the image is to make sure that because it's a background image, here's the thing. Because it's a background image, there's no guarantee that if I just set the background image and then started fading in that the image wouldn't be sort of part loaded during the fading. You kind of get that bizarre, it's fading, but it's also loading at the same time feel. So I preload it, which is make sure it's definitely in the cache. And we talked previously about my caching headers. So the image should come with good caching headers. Preload it, get it, make sure it's there. And then we can set background image. So when we set the background image, it goes, oh, I better go and get that image. And he goes, oh, it's already there in the cache. Let me just use that pop. And it means that we don't get that partly downloaded. Kind of feel with that images. And that's it. So using intersection observer is a nice progressive enhancement move. I'm enjoying it. It does the job perfectly. If we don't, if we have a long page with a lot of content in and somebody doesn't scroll down, why bother loading those images? No need. So it's not a lot of code, is it? 115 or so lines of code just to handle that? Winning. So there you go. Next time, I'm going to have a chat with you about what I've been doing in the world of offline and prefetching video. And oh my goodness, has that been a journey? Anyway, don't forget you can subscribe. Don't forget you can drop your comments and your questions in below and I will catch you next time. Hello. Thanks for watching. If you enjoyed this video, well, you may enjoy other videos that we make too. So don't forget you can subscribe and you'll get notified when we push out a new video. And there's more videos over there or down there depending on how you're watching the YouTube right now. Definitely click on those.