Lesson 07: Image & Assets Optimization - strvcom/frontend-academy-2022 GitHub Wiki

Speaker: Dave Nguyen

Resources


1. Images

Current Image Formats
  • JPEG
    • Ideal for photographic content
    • Significantly smaller than PNGs
  • PNG
    • Ideal for graphics that have sharp contrast
    • Supports transparency
  • GIF
    • Predecessor to PNG
    • Known for animation
  • WEBP
    • ~30% smaller than JPEG
    • 26% smaller than PNG
    • Supports transparency
    • Partially supported on all major browsers
    • Preferred option to use in 2022 with JPEG/PNG fallback
  • SVG
    • Vector based format
    • Best for icons
New Image Formats
  • AVIF
    • Open-source image format
    • High quality compressed (50% size of JPEG and 20% size of WEBP)
    • Supported on Chrome, Firefox and Opera
    • High quality compressed (50% size of JPEG and 20% size of WEBP)
    • Preferred option to use in 2022 with WEBP/JPEG/PNG fallback
  • JPEG XL
    • Designed to outperform existing raster formats and become their replacement
    • Supported only on Safari
  • HEIF and HEIC
    • HEIF = can store individual images and image sequences
    • HEIC = can store both image and video files (Live Photos)
Image Optimization

Process of delivering high-quality images in the right format, dimension, size, and resolution while keeping the smallest possible size.

  • Improves page load speed (which is directly related to SEO ranking)
  • Boosts websites’ SEO ranking (thanks to page load speed)
  • Improves UX
Lossy vs Lossless Compression
  • Lossy Compression
    • Reduces file sizes by removing as much data as possible
    • Reduces image quality
    • JPEG
  • Lossless compression
    • Strips metadata and non-essential information that doesn’t impact the picture’s appearance or quality
    • PNG, GIF
  • What about WEBP and AVIF?
    • They support both lossy and lossless compression
Tools For Image Optimization
Code Snippets
  • <img /> with width and height
    • Use both width and height to set the intrinsic size of the image, allowing it to take up space before it loads, to mitigate content layout shifts.
        <img src="puppy.jpg" alt="Cute puppy" width="700" height="400" />
  • <img /> with srcset and sizes
    • Using responsive images is the practice of serving multiple versions of the same image so the browser can choose the version that works best for the user’s device.
       <img
         src="puppy-800w.jpeg"
         alt="Cute puppy"
         srcset="puppy-400w.jpeg 400w, puppy-800w.jpeg 800w"
         sizes="(max-width: 900px) 400px,
                800px"
       />
  • <img /> with srcset by pixel density
  • <img /> with native lazy loading * Tell browser to defer loading of images that are off-screen until the user scrolls near them.
     <img
       src="[email protected]"
       alt="Cute puppy"
       width="32"
       height="32"
       srcset="[email protected] 1x, 
               [email protected] 2x"
       loading="lazy"
     />
  • <picture /> for multiple sources
    • The browser can choose which image format to display using the <picture> element. The <picture> element supports multiple <source> elements, which can reference sources for formats like webp.
      <picture>
         <source srcset="puppy.webp" type="image/webp">
         <source srcset="puppy.jpg" type="image/jpeg">
         <!-- fallback -->
         <img src="puppy.jpg" alt="Cute puppy">
      </picture>
Next Image
Next.JS comes up with the out of box solution which will do all the magic for you.

  • Local Images
    • The import must be static so it can be analyzed at build time.
  • External Images
      import Image from 'next/image'
    
      import puppyImage from './assets/puppy.jpeg'
    
      export const Component = () => (
          <Image
            src={puppyImage}
            alt="A cute puppy"
            width={400}
            height={800}
         />
Resources

2. SVGs

Best Practices
  • Icons as SVGs
  • Icons as standalone React components
    • Reusable
    • Passing props
  • Icons are placed along its using component. It's a good practice and it helps maintenance of the project
SVG Optimization
  • Stripping out anything that is unnecessary
  • SVGOMG
    • Best tool for SVG Optimization
Code Snippets
  • Use currentColor to be able to style it
       import type { FC } from 'react'
    
       export const LogoIcon: FC = (props) => {
         return (
           <svg
             width="29"
             height="28"
             fill="none"
             xmlns="http://www.w3.org/2000/svg"
             {...props}
           >
             <path
               fillRule="evenodd"
               clipRule="evenodd"
               d="M.078 27V.058H16.95v4.94H5.322v6.156h10.526v4.674H5.322v6.232H16.95V27H.078Zm21.47-3.192c0-.963.336-1.78 1.007- 
                  2.451.671-.671 1.488-1.007 2.451-1.007.481 0 .937.089 1.368.266a3.393 3.393 0 0 1 1.862 1.843c.177.418.266.868.266 
                  1.349A3.419 3.419 0 0 1 26.374 27c-.43.177-.887.266-1.368.266-.963 0-1.78-.336-2.451-1.007-.671-.671-1.007-1.488-1.007- 
                  2.451Z"
               fill="currentColor"
             />
           </svg>
         )
        }  

3. Fonts

Fonts Formats
  • TTF (TrueType Font)
  • OTF (OpenType)
  • EOT (Embedded Open Type)
  • WOFF/WOFF2 (Web Open Font Format)
    • OTF or TTF with metadata and compression
    • Supported by all major browsers
    • Recommended
Fonts Optimization
  • Font Rendering

    • font-display informs the browser how it should proceed with text rendering when the web font has not loaded.
    • If performance is a top priority: Use font-display: optional. This is the most "performant" approach: text render is delayed for no longer than 100ms and there is assurance that there will be no font-swap related layout shifts.
    • If displaying text in a web font is a top priority: Use font-display: swap but make sure to deliver the font early enough that it does not cause a layout shift.
  • Font Usage

    • Use WOFF/WOFF2 format
    • Use system fonts instead
  • Next.JS

    • Since version 10.2, Next.js has built-in web font optimization
    • Currently supports only Google Fonts and Typekit
  • Should I use self-hosted fonts?

    • On paper, using a self-hosted font should deliver better performance as it eliminates a third-party connection setup
    • If you are considering using self-hosted fonts, confirm that your site is using a Content Delivery Network (CDN) and HTTP/2 protocols. Without use of these technologies, it is much less likely that self-hosted fonts will deliver better performance.
Code Snippets
  • Custom fonts with font-face
      @font-face {
        font-family: "Open Sans";
        src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2"),
             url("/fonts/OpenSans-Regular-webfont.woff") format("woff");
        font-display: swap;
        font-style: normal;
        font-weight: 400;
      }
  • Google Fonts with <link>
       <head>
         <link rel="preconnect" href="https://fonts.googleapis.com" />
         <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
         <link
           href="https://fonts.googleapis.com/css2?family=Hind:wght@400;500&family=Playfair+Display&display=swap"
           rel="stylesheet"
         />
      </head>
  • font-smoothing
    • Smooth the font on the level of the pixel, as opposed to the subpixel. Switching from subpixel rendering to antialiasing for light text on dark backgrounds makes it look lighter.
    • Works only on macOS
      body, html {
         font-family: 'Open Sans', sans-serif;
         -moz-osx-font-smoothing: grayscale;
         -webkit-font-smoothing: antialiased;
      }
Resources
⚠️ **GitHub.com Fallback** ⚠️