Skip to content

Latest commit

 

History

History
197 lines (138 loc) · 8.88 KB

web-performance.md

File metadata and controls

197 lines (138 loc) · 8.88 KB

Web Performance

CSS

No JS technique for loading CSS asynchronously:

<link rel="stylesheet" href="/path/to/file.css" media="print" onload="this.media='all'">

Images

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>

Photographic images

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

Non-photographic images

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.

Animated

AVIF and WebP support animation.

APNG is another option (browser support), but usually yields a bigger file size than GIF.

Future

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.

Misc

If you want to use a next-gen image format as a background in CSS you can use:

Avoid JPEG 2000. It's only supported in Safari.

Avoid JPEG XR. It's only supported in IE 11 and older.

Web Fonts

Formats

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');
}

font-display

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.

Preloading

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).

Character ranges

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

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.

Misc

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).

Links