永遠にWIP

BlogのCLS対策をする

CLS
Frontend
React

はじめに

皆さん、CLS対策してますか?
CLSはCumulative Layout Shiftの略で、予期しないレイアウトのズレを表します。
よく、画像などがあとから読み込まれたせいで画面がガクッってなるあれです。
一応Google先生の説明的には以下のようになっています。

Cumulative Layout Shift は、ページがどのくらい安定しているように感じられるかを表します。視覚的な安定性を測定し、表示されるページ コンテンツにおける予期しないレイアウトのずれの量を定量化します
https://developers-jp.googleblog.com/2020/05/web-vitals.html

CLS対策をする

CLS対策で最初に思い浮かぶのは画像です。何も対策をしていないときは以下のような挙動をします。

次にCLS対策をしているものは次のような挙動になります。

私はEmotionを使ってこれを実装しているのですが、以下のようになります。

import styled from '@emotion/styled';
import React from 'react';

type ImageProps = React.DetailedHTMLProps<
  React.ImgHTMLAttributes<HTMLImageElement>,
  HTMLImageElement
>;

const StyledImage = styled.img`
  width: 100%;
  max-width: ${(props) => props.width}px;
  height: auto;
  aspect-ratio: ${(props) => props.width} / ${(props) => props.height};
`;

export const Image: React.VFC<ImageProps> = ({ ...props }) => {
  return <StyledImage loading={'lazy'} {...props} />;
};

CLS対策をするにはまず、画像のheightが事前に計算できないといけません。
今回は読み込む画像の大きさを予め指定し、aspect-ratioを使うことでレスポンシブ対応をしています。
画像の大きさ指定に関してはmarkdownのparserを自分で拡張することでいい感じにやっています。

https://github.com/DuGlaser/blog/blob/master/packages/parser/src/imageSize.ts

最後に

今回は結構端折った説明になりましたが、詳しく見たい方はweb.devの記事を見てください!

https://web.dev/optimize-cls/

© 2020 DuGlaser