No JS technique for loading CSS asynchronously:
<link rel="stylesheet" href="/path/to/file.css" media="print" onload="this.media='all'">
Including dimension attributes (i.e. width
and height
) to <img>
can help prevent layout shifts. Dimensions can of course, be overwritten with CSS.
Use the available horizontal space up until its maximum size while retaining the aspect ratio:
img {
max-width: 100%;
height: auto;
}
Consider setting the image decoding be non-blocking with decoding=”async”
(browser support) to help speed up the initial rendering.
Non-critical <img>
should be lazy loaded natively by the browser with loading="lazy"
(browser support) to help speed up the initial rendering.
Favor using the <picture>
tag for displaying responsive images in different next-gen formats depending on what the browser supports.
The order of the <source>
tags in <picture>
should depend on the output size of the different image formats, as the browser will grab the first supported format from top to bottom, i.e. the smallest should be at the top.
<picture>
<source
media="(min-width: 768px)"
type="image/avif"
srcset="my-larger-image.avif"
>
<source
media="(min-width: 768px)"
type="image/webp"
srcset="my-larger-image.webp"
>
<source
media="(min-width: 768px)"
srcset="my-larger-image.jpg"
>
<source
type="image/avif"
srcset="my-base-image.avif"
>
<source
type="image/webp"
srcset="my-base-image.webp"
>
<img
src="my-base-image.jpg"
alt="Alternative text for accessibility"
loading="lazy"
decoding="async"
>
</picture>
Format | Lossless | Alpha | Animation | Notes |
---|---|---|---|---|
AVIF | ✓ | ✓ | ✓ | No progressive mode. Browser support |
WebP | ✓ | ✓ | ✓ | No progressive mode. Browser support |
JPEG | x | x | x | Progressive mode. All browsers support it |
Refers to synthetic/vector/sharp edges/text images.
Depending on your usage, your best option may be embedded SVG when critical, and in <img>
when non-critical. It is technically lossless. And since SVG is just text, it can be optimized, and compressed (e.g. with brotli, or gzip on a CDN).
If you don't need to re-scale your (non-photographic) image consider compressing it as AVIF, WebP (since they both support transparency) and PNG. These may yield a smaller file size than SVG.
AVIF and WebP support animation.
APNG is another option (browser support), but usually yields a bigger file size than GIF.
In the not-so-distant future, the format to rule them all may be JPEG XL (browser support).
It supports alpha and other channels, has high bit depth, supports lossless, animation, progressive mode, it's responsive by design, high quality, and legacy-friendly.
With all of that it can replace JPEG, PNG, GIF, and others.
If you want to use a next-gen image format as a background in CSS you can use:
- avif-in-css (PostCSS plugin): Te detect AVIF support
- webp-in-css (PostCSS plugin): Te detect WebP support
- Modernizr: To detect WebP support
Avoid JPEG 2000. It's only supported in Safari.
Avoid JPEG XR. It's only supported in IE 11 and older.
Use WOFF. It has the widest browser support and yields the smallest file size over other formats.
If you don't need to support IE 11, use WOFF 2.0:
/* assumes a regular (i.e. 400) normal (i.e. non-italic) font */
@font-face {
font-family: 'Font Name';
font-style: normal;
font-weight: 400;
src: url('/path/to/file.woff2') format('woff2');
}
If you need to support IE 11, add WOFF 1 as fallback:
/* assumes a regular (i.e. 400) normal (i.e. non-italic) font */
@font-face {
font-family: 'Font Name';
font-style: normal;
font-weight: 400;
src: url('/path/to/file.woff2') format('woff2'),
url('/path/to/file.woff') format('woff');
}
The font-display
descriptor lets you control what happens while the font is still loading or otherwise unavailable.
Use the swap
value to ensure text remains visible during font loading and avoid a flash of invisible text (FOIT).
Use the optional
value when the font is non-essential to the design. It will optionally load the font on fast enough connections.
Preload fonts to increase the likelihood of them being loaded when your document is first rendered, thus avoiding a layout shift:
<head>
<link rel="preload" href="/path/to/file.woff2" as="font" type="font/woff2" crossorigin>
</head>
Note: crossorigin
and crossorigin=""
are the same as crossorigin="anonymous"
(the default).
Use the unicode-range
descriptor to define one, or more, specific ranges of characters to be used from a font defined by @font-face
. If the page doesn't use any character in the range, the font is not downloaded; if it uses at least one, the whole font is downloaded.
Google Fonts outputs different ranges using unicode-range
: Example
Subsetting allows you to include only the characters/glyphs you want instead of a full font file.
For example, subsetting to basic latin characters for an English only site.
See Links section for tools on this.
Use long HTTP caching for fonts, since they are static resources that don't see frequent updates.
Avoid using the Google Fonts service and self-host the fonts instead.
Avoid using the local()
function, in @font-face
, to prevent showing potentially unexpected locally installed fonts.
Consider using variable fonts (browser support).
- Ezgif (Online) – Animated GIF editor and GIF maker | convert, edit
- fontTools (CLI) – a library for manipulating fonts
- Font Squirrel (Online) – Create Your Own @font-face Kits | convert, subset
- glyphhanger (CLI) – Your web font utility belt
- google-webfonts-helper (Online) – Get (Google Fonts) eot, ttf, svg, woff and woff2 files + CSS snippets
- ImageMagick (CLI) – Create, edit, compose, or convert digital images
- lazysizes – lazyloader for images, iframes, scripts/widgets and much more
- Photopea (Online) – Online Photo Editor | convert, resize, crop, etc.
- Squoosh (Online) – Compress and compare images with different codecs, right in your browser | compress, convert, resize
- SVGO – Node.js tool for optimizing SVG files
- SVGOMG (Online) – SVGO's Missing GUI
- The Simplest Way to Load CSS Asynchronously – Article
- Transfonter (Online) – Modern and simple css @font-face generator | convert, subset
- woff2 (CLI) – Produce
.woff2
files