Lesson 07: Image & Assets Optimization - strvcom/frontend-academy-2022 GitHub Wiki
Speaker: Dave Nguyen
- Pull Request
- Recording (Gdrive)
- Slides (Google Slides)
- Slides (PDF)
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
-
Squoosh
- Compress and convert to new image formats
-
ImageOptim
- Lossless compression
Code Snippets
-
<img />
withwidth
andheight
- 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" />
- 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 />
withsrcset
andsizes
- 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" />
- 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 />
withsrcset
by pixel density- Allows the browser to choose an appropriate resolution image based on display resolutions.
<img src="[email protected]" alt="Cute puppy" width="32" height="32" srcset="[email protected] 1x, [email protected] 2x" />
- Allows the browser to choose an appropriate resolution image based on display resolutions.
-
<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>
- The browser can choose which image format to display using the
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.
- The
- External Images
- You have to add
domains
to thenext.config.js
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} />
- You have to add
Resources
- Web Almanac 2021 report by HTTP Archive - Images
- Image Optimization by Addy Osmani
- Best Image Formats for Websites Compared―PNG, JPG, GIF, and WebP
- WEBP, AVIF, and JPEG XL, Better Image Formats For Websites
- Using Modern Image Formats: AVIF And WebP
- What is HEIC and HEIF
- What Is the Difference in Lossy vs Lossless Compression?
- MDN - Responsive Images
- MDN - Lazy Loading
- Next Image
- Next Image Optimization
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
Code Snippets
- Use
currentColor
to be able to style itimport 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> ) }
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; }