この記事の要約

webパフォーマンス高速化を定量的かつ比較しやすい指標である「コアウェブバイタル」の視点でパフォーマンスを改善する7種類の考え方と手法をざっくり紹介しています。

本文

さまざまなwebパフォーマンス改善の手法

こんにちは。アイレットデザイン事業部のマークアップ/フロントエンドエンジニアの工藤です。アイレットデザイン事業部ではINSIDE UI/UXと題して、所属デザイナーとエンジニアがデザイン・SEO・アクセシビリティ・UI/UXなどそれぞれスペシャリティのある領域に対する知見を幅広く発信しています。前回記事で画像の実装に焦点を当てましたので、今回はモダンブラウザでハイパフォーマンスなウェブページを実現するための画像以外の実装についてざっくりと書こうと思います。

イメージ画像

パフォーマンス改善の方法は多岐に渡りますが、これを手法ごとに分類すると
1. リソースを先行取得する
2. リソース取得や実行を遅延する/非同期に実行する
3. リソースを削減する
4. リソースを圧縮する
5. キャッシュする
6. 記法を工夫する(CSSセレクタの単純化やリペイントを減らすなど)
7. 別の手法がないか検討する

こんなところでしょうか。こうしてみるとリソースの取得に関係するものが多いですね。スマートフォンなどでも高性能なCPUを搭載したモデルが増えたことでレンダリング時およびペインティング時の描画の問題が起きることが減った一方で、端末の性能で補えない通信や回線に依存する部分があるからかなと思います(もちろんHTTP2、5Gなどその分野でも革新は著しいのですが)。
実務においては上記の手法ごとの分類をざっくりと頭の中に入れておいて、場面ごとに必要なものをサッと取り出せる柔軟性が大事だと思います。

1. リソースを先行取得する

リソースを効率的に取得する方法としては以下が考えられます。

  • リソースヒント(Resource Hints)とプリロード(preload)を利用したリソースの先行取得
    • dns-prefetch
    • preconnect
    • prefetch
    • prerender
  • preload
    • 似ているがリソースヒントとは言わない

2. リソース取得や実行を遅延する/非同期に実行する

  • defer属性による非同期化
    • defer属性をつけたスクリプトの読み込み位置はどこが良いか
    • 読み込み順の検討
  • vue.jsやReactの利用
    • 仮想DOM
  • プログレッシブウェブアプリ (Progressive web apps, PWA)
  • AMP(Accelerated Mobile Pages)
    • Googleは2021年6月検索結果への優遇を廃止

3. リソースを削減する

  • CDNの利用
    • オリジンサーバーの配信作業が減り、結果的に負荷が減る
  • 不要なCSSの探索と削除
    • purgecss
  • クリティカルCSSの書き出し
  • ページごとのスクリプトの分割
    • ES Modules
    • IE対応(を考えるとできないもの多いので注意)
    • polyfill
    • フォールバックスクリプト、nomodule属性
  • CSS Module

4. リソースを圧縮する

  • cleanCSSによる圧縮・最適化
  • imageminによる画像の圧縮
  • gzipによる配信リソースの圧縮
  • JSの圧縮: uglify+concat+babel

5. キャッシュする

  • 静的リソースをキャッシュ
    • 逆にキャッシュ破棄したい時: リソースへのハッシュ値付加によるキャッシュ無効化
  • サーバーサイドの知見〜それぞれのキャッシュ破棄を知る
    • Apache
    • NGINX
    • CloudFront
  • レスポンスヘッダの知見

6. 記法を工夫する

CSS記法について

  • web font対応
  • dart-sassの利用とBreaking Changes対応
    • @import => @use / @forward
    • slash div
    • sass-migrator
  • 効率的なCSS記法
    • クラスの単純化
    • BEMを利用しネストを少なくする
    • 色数を限定する
      • 変数の利用
      • a11yとの両立を目指す
    • 高コストなCSSプロパティの描画(とくにアニメーション)を見直す
    • リペイントの発生を減らす
    • stylelintによるエラーの洗い出し
      • no-descending-specificityルール
    • 不要なCSSの削減
      • csscssによるスタイル重複プロパティの探索
    • background-imageのレスポンシブ対応
  • IE対応
    • Autoprefixer
    • IEを想定するとdisplay: gridは使いにくい…
  • Safari対応

7. 別の手法がないか検討する

  • 動画を埋め込みたい!
    • 画像で充分かも?
  • スライドショーを使いたい!
    • アクセスするたびに一枚の静止画が切り替わる…でも十分かも?
  • 日本語のwebフォントを使いすぎない
    • 英数字なら大文字・小文字を区別しない場合は36文字、区別する場合は62文字
    • 日本語は漢字を含めると桁が違う…
  • iframeを使わない
    • 地図とか。
  • 画像のCSS Sprite化をする/しない
    • HTTP2では一度にダウンロードできるリソース数が増えたため画像のCSS Sprite化をしない
    • HTTP1なら画像のCSS Sprite化をする
      • つまりサーバーサイドの実装もチェックしておく
  • CSSでできるインタラクティブ表現
    • インタラクティブ要素のPure CSS化
      • カルーセル
      • スライドショー
      • アニメーション
        • などなど。CodePenなどで新しいCSS芸をチェック
  • You Might Not Need jQuery
    • jQueryのpros/consを知っておく
    • jQueryに依存しないプラグインの利用
    • Vannila JSの利用
      • jQueryでは直せないエラー: スクロールイベントのPassive Event Listeners
      • intersection-observer API
    • ただしjQuery v4 が開発中とのこと。そっちで既知の問題が解決してれば復権あるかも

といったところでしょうか。改めて振り返るとなかなかの量になってしまいました。

個人的にこの中でとくに大事だなと思うことは7. 別の手法がないか検討するです。webデザインにおいて美しいビジュアルと俊敏なパフォーマンス(さらに誰もが使いやすいアクセシビリティ)は時として相反しますが、それを実装の工夫により両立させて素晴らしいサイトが完成した時の充実感は何ものにも代え難いと思います。

今回のINSIDE UI/UXはここまでです。ありがとうございました。

P.S. アイレットではエンジニア、デザイナーを募集しています。詳しくは採用情報の募集職種ページをご覧ください。