nobe4 / Lazy Lazy Loading

In this blog post, I showcase how I maintain my cat website.

Past

I used to maintain a piece of code that roughly did the following:

content = "<body>"

for picture in ls("./pictures"):
    content += picture

content += "</body>"

Which generated an HTML file I could then deploy:

<body>
    <img src="pictures/0.jpeg"/>
    <img src="pictures/1.jpeg"/>
    <img src="pictures/2.jpeg"/>
    ...
</body>

That meant that for any new picture, the build script would have to run again. I removed the build step by doing something much worse.

Present

Given that all the pictures are numerically sorted, it’s possible to iterate through each one.

When would it stop? When the picture doesn’t exist, meaning that it reached the last picture.

In JavaScript, we can use fetch like so:

for (let i = 0; ; i++) {
    const image = fetch(`path/to/picture_${i}.jpeg`)
    if (!image) {
        break;
    }
    body.append(image)
}

Except that fetch is an async function, which needs either await or wrapping everything in an async function(){}.

Bah, both sounds too complex, let’s do something simpler.

Let’s use <img> events to loop through the pictures:

onerror needs to also remove the current image from the page, since it didn’t load.

Here’s the result:

<body>
    <main id="cats"></main>
    <script>
        function load_next(i) {
            if (event) {
                event.target.onload = ''
                event.target.onerror = ''
            }

            cats.insertAdjacentHTML(
                "beforeend",
                `<img src="pictures/${i}.jpeg" onload="load_next(${i + 1})" onerror="done()"/>`
            )
        }
        load_next(0)

        function done() {
            cats.removeChild(cats.lastChild)
        }
    </script>
</body>

screencast

Notice how the loading stops after the last picture gets a 404.

Future

Have another look at the website, some other things are there, all terrible. At least there’s some cute cats!