Tech blog Produced by FOURIER

JavaScriptの読み込み時にblocking=”render”でFOUC対策

Sena Sena 2023.11.10

⚠️ この機能は今後変わる可能性があり、2023/11/09現在の状況で実験して書いた物です。

はじめに

以前、JavaScript呼び出し時のasyncにていての記事を書きました。

要約すると、JavaScriptのコードの内容によっては、deferやasyncで読み込むとFOUC(ちらつき)が発生してしまうことがあるという内容になります。

特に React や Vue.js を使ったサイトでは、ローディング画面を作って FOUC を防止することが多いと思いますが、閲覧者にとっては(ブラウザの)ローディングした後にローディングとなってしまいます。

なんとかする方法は無いかと Chrome の開発ブログを見ていましたが、ついに出ました!

FOUCへの救世主 blocking=”render”

<script async blocking="render" src="async-script.js"></script>

blocking=”render”を付けることにより、レンダリングの開始前に評価されます。

今まではレンダリングされた後に評価・実行されてしまっていたのでFOUCが発生していましたが、これで防ぐことが出来ます!

軽く実験

以下のようなJavaScriptを書いたとします。

'use strict';
{
    const root = document.getElementById('root');
    const div = document.createElement('div');
    div.style.paddingBlock = '1000px';
    root.appendChild(div);
}

同じコードをheadタグ内から様々な方法で読み込んでみます。

  1. 同期的に読み込みます。
  2. <script src="/js/app.js"></script>
  1. deferで読み込みます。
  2. <script defer src="/js/app.js"></script>
  1. asyncで読み込みます。
  2. <script async src="/js/app.js"></script>
  1. 2.にblocking=”render”を付けて読み込みます。
  2. <script defer blocking="render" src="/js/app.js"></script>

Performance InsightsでCumulative Layout Shift (CLS)の値を図ってみると、以下のような結果になりました。

レンダリング方法Cumulative Layout Shift (CLS)
同期的に読み込む0.436
deferで読み込む0.436
asyncで読み込む0.436
blocking=”render”を付けて読み込む0

濫用に注意

blocking=”render”を使えばレンダリングブロックを意図的に行える事が分かりました。

ただし、レンダリングが遅くなるため、UXやSEO的には弱くなります。

そのためblocking=”render”が必要なリソースかどうか見極める必要があります。

まとめ

blocking=”render”が使えるようになれば、簡単にFOUCを防ぐ事が出来ます。

執筆時では対応しているブラウザが少ないですが、非常に便利な機能なので対応ブラウザが増えて欲しいところです。

Sena

Sena / Engineer

生涯に亘り技術を極めていきたい。