Chris Padilla/Blog

You can follow by RSS! (What's RSS?) Full posts list here.

    Floating Improv

    Listen on Youtube

    ā˜ļø

    The backing is prerecorded, but Miranda from the other room thought that I just got WAY better all of a sudden šŸ˜‚

    Lizalfos

    šŸŖ°

    Miranda's least favorite enemy to fight, but my favorite to draw!

    Mitigating Content Layout Shift with Next Image Component

    One aspect of developing my art grid was moving away from the Next image component and choosing a more flexible option with special css.

    There are still plenty of spots on the site I wanted to keep using it, though! This week, I wanted to jot down why.

    CLS

    Content Layout Shift is something I've written about a few times. Surprisingly, this is my first touch on images, the largest culprits of creating CLS!

    A page is typically peppered with images throughout. An image can be wholly optimized to be very lightweight, but can still contribute to a negative user experience if the dimensions are not accounted for.

    Say you're reading this blog. And a put an image right above this paragraph. If an image FINALLY loads as you're reading this, all of a sudden this paragraph is pushed down and now you have to scroll to find your place. Ugh.

    The Solution

    The way to mitigate this is pretty simple: Set dimensions on your images.

    Easy if you already know what they are: Use css to set explicit widths and heights. You can even use media queries to set them depending on the screen size.

    It gets a little trickier if you're doing this dynamically, not knowing what dimensions your image will be. The best bet, then, is to set a container for the image to reside in , and have the image fill the container. Thinking of a div with an img child.

    Next Image Component

    It's not too involved to code this yourself, but Next.js comes out of the box with a component to handle this along with many other goodies. The Image Component in Next offers Size optimization for local images and lazy loading.

    Here I'm using the component for my albums page

    import React from 'react';
    import Image from 'next/image';
    import Link from 'next/link';
    
    const MusicGrid = ({ albums }) => {
      return (
        <>
          <section className="music_display">
            {albums.map((album) => (
              <article key={album.title}>
                {/* <Link href={album.link}> */}
                <Link href={`/${album.slug}`}>
                  <a data-test="musicGridLink">
                    <Image src={album.coverURL} width="245" height="245" />
                    <span>{album.title}</span>
                  </a>
                </Link>
              </article>
            ))}
          </section>
        </>
      );
    };
    
    export default MusicGrid;

    And here is what's generated to the DOM. It's a huge sample, but you can find a few interesting points in there:

    The key pieces being the srcset used for different sized images generated for free. These are made with externally sourced images, interestingly enough, but they're generated by the component to handle rendering specifically to the page!

    <article>
      <a data-test="musicGridLink" href="/forest"
        ><span
          style="
            box-sizing: border-box;
            display: inline-block;
            overflow: hidden;
            width: initial;
            height: initial;
            background: none;
            opacity: 1;
            border: 0;
            margin: 0;
            padding: 0;
            position: relative;
            max-width: 100%;
          "
          ><span
            style="
              box-sizing: border-box;
              display: block;
              width: initial;
              height: initial;
              background: none;
              opacity: 1;
              border: 0;
              margin: 0;
              padding: 0;
              max-width: 100%;
            "
            ><img
              style="
                display: block;
                max-width: 100%;
                width: initial;
                height: initial;
                background: none;
                opacity: 1;
                border: 0;
                margin: 0;
                padding: 0;
              "
              alt=""
              aria-hidden="true"
              src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%27245%27%20height=%27245%27/%3e" /></span
          ><img
            src="/_next/image?url=https%3A%2F%2Fres.cloudinary.com%2Fcpadilla%2Fimage%2Fupload%2Ft_optimize%2Fchrisdpadilla%2Falbums%2Fforest.jpg&amp;w=640&amp;q=75"
            decoding="async"
            data-nimg="intrinsic"
            style="
              position: absolute;
              top: 0;
              left: 0;
              bottom: 0;
              right: 0;
              box-sizing: border-box;
              padding: 0;
              border: none;
              margin: auto;
              display: block;
              width: 0;
              height: 0;
              min-width: 100%;
              max-width: 100%;
              min-height: 100%;
              max-height: 100%;
            "
            srcset="
              /_next/image?url=https%3A%2F%2Fres.cloudinary.com%2Fcpadilla%2Fimage%2Fupload%2Ft_optimize%2Fchrisdpadilla%2Falbums%2Fforest.jpg&amp;w=256&amp;q=75 1x,
              /_next/image?url=https%3A%2F%2Fres.cloudinary.com%2Fcpadilla%2Fimage%2Fupload%2Ft_optimize%2Fchrisdpadilla%2Falbums%2Fforest.jpg&amp;w=640&amp;q=75 2x
            " /><noscript
            ><img
              srcset="
                /_next/image?url=https%3A%2F%2Fres.cloudinary.com%2Fcpadilla%2Fimage%2Fupload%2Ft_optimize%2Fchrisdpadilla%2Falbums%2Fforest.jpg&amp;w=256&amp;q=75 1x,
                /_next/image?url=https%3A%2F%2Fres.cloudinary.com%2Fcpadilla%2Fimage%2Fupload%2Ft_optimize%2Fchrisdpadilla%2Falbums%2Fforest.jpg&amp;w=640&amp;q=75 2x
              "
              src="/_next/image?url=https%3A%2F%2Fres.cloudinary.com%2Fcpadilla%2Fimage%2Fupload%2Ft_optimize%2Fchrisdpadilla%2Falbums%2Fforest.jpg&amp;w=640&amp;q=75"
              decoding="async"
              data-nimg="intrinsic"
              style="
                position: absolute;
                top: 0;
                left: 0;
                bottom: 0;
                right: 0;
                box-sizing: border-box;
                padding: 0;
                border: none;
                margin: auto;
                display: block;
                width: 0;
                height: 0;
                min-width: 100%;
                max-width: 100%;
                min-height: 100%;
                max-height: 100%;
              "
              loading="lazy" /></noscript></span
        ><span>Forest</span></a
      >
    </article>

    Swing Low

    Listen on Youtube

    Sangin'! With Lucy!

    Sleepy Seals

    Ssssh

    šŸ¤«šŸ¦­šŸ˜“