はじめに
以前、JavaScript呼び出し時の async にていての記事を書きました。
JavaScriptの呼び出しにasyncを付けない方がよいときってどんなとき? | FOURIER TECH BLOG 〜 IT技術ブログ 〜
Web Componentsが呼び出される際に、Layout Shiftと判定される可能性があることに気づいたので解説します。
https://www.fourier.jp/techblog/articles/call-webcomponents-with-perser-blocking/
要約すると、JavaScriptのコードの内容によっては、defer や async で読み込むと FOUC(ちらつき)が発生してしまうことがあるという内容になります。
Flash of unstyled content(FOUC)について
特に React や Vue.js を使ったサイトでは、ローディング画面を作って FOUC を防止することが多いと思いますが、閲覧者にとっては(ブラウザの)ローディングした後にローディングとなってしまいます。
なんとかする方法は無いかと Chrome の開発ブログを見ていましたが、ついに出ました!
'blocking=render' attribute on scripts and style sheets - Chrome Platform Status
https://chromestatus.com/feature/5452774595624960
FOUC への救世主 blocking="render"
Feature proposal: blocking=render attribute on <link>, <script> and <style> · Issue #7131 · whatwg/html
https://github.com/whatwg/html/issues/7131
<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 タグ内から様々な方法で読み込んでみます。
- 同期的に読み込みます。
<script src="/js/app.js"></script>
- defer で読み込みます。
<script defer src="/js/app.js"></script>
- async で読み込みます。
<script async src="/js/app.js"></script>
- 2.に blocking="render"を付けて読み込みます。
<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的には弱くなります。
レンダリング ブロッキング リソースを回避する | Publisher Ads Audits for Lighthouse | Google for Developers
https://developers.google.com/publisher-ads-audits/reference/audits/ad-render-blocking-resources?hl=ja
そのためblocking="render"
が必要なリソースかどうか見極める必要があります。
まとめ
blocking="render"
が使えるようになれば、簡単に FOUC を防ぐ事が出来ます。
執筆時では対応しているブラウザが少ないですが、非常に便利な機能なので対応ブラウザが増えて欲しいところです。
新しいメンバーを募集しています
Sena / Engineer
生涯に亘り技術を極めていきたい。