ふろしき Blog

コンテンツサービスを科学する株式会社ブートストラップ代表のブログ

1300の優良サイトが選んだ「AMD・遅延ロード」のベストプラクティス

1300の優良サイトが選んだシリース、第3回は「AMDと遅延ロード」です。

JavaScriptファイルのロードのパフォーマンス向上を図るメカニズムを「AMD(Asynchronous module definition)」といいます。Webアプリ開発を行なうデベロッパの方は、今後重要な知識になるでしょう。

一方で画像ファイルのパフォーマンスを向上させようという「遅延ロード(Lazy Load)」というアイデアもあります。こちらはサイトのデザインそのものにも影響を与えることになるため、Webアプリのデベロッパだけでなくデザイナの方も、仕組みを知る必要があるでしょう。

今回も、1300の優良サイトが採用しているAMD・遅延ロード手法を確認し、ベストプラクティスが何かを探ってみようかと思います。

画像ファイルの非可視エリアロード問題対策

画像ファイルのサイズは、比較的大きくなるという特徴を持ちます。そして対策を行わなかった場合、HTMLドキュメントのロードと同時に一斉にロードを始めて、サーバやネットワークのリソースを圧迫します。

しかしこれらの画像ファイルは、ロード直後にすぐ必要になるとは限りません。Webページの下部に配置された画像ファイルは、ユーザの目に触れることすら無い可能性があります。

こうしたWebページの特性に合わせて画像ロードをさせようというアイデアが、「Lazy Load(遅延ロード)」です。Webページ表示後、ユーザビリティを損なわない任意のタイミングで画像ファイルをロードさせることで、サーバやネットワークの負荷を最適化します。

f:id:furoshiki0223:20131014014812p:plain

1300中、5つのサイト(0.38%)にて、JSライブラリによる対策が確認されました。

★ Lazyload (5件)

JavaScriptの直列実行問題対策

画像ファイルは並列にロードすることでWebページ表示速度を改善しようとしますが、JavaScriptの場合はそうもいきません。JavaScriptファイル間に依存性を生じることがあるからです。

対策を行っていない場合、全てのJavaScriptファイルは直列にロードされます。一つずつ読み込みを行い、コンパイルを行ない、実行するという手順を踏みます。大規模な場合、Webページの初期表示のパフォーマンスの低下に繋がることがあります。

JavaScriptにもLazy Load(遅延ロード)という考え方があります。既にW3CのWeb標準にも組み込まれており、JavaScriptファイルの読み込みを行なうためのscript要素から、defer属性を通じて制御することができます。

<script src="xxx.js" defer></script>

また、最近は並列ロード・実行というアイデアにも注目を集めています。JavaScriptの依存関係を予め定義しておき、できる限りの並列実行を行おうというアプローチです。これを「AMD(Asynchronous module definition)」と呼び、CommonJSと呼ばれるデファクト標準でも扱われているテーマです。

1300中、14サイト(1.07%)にてJSライブラリによる対策が確認されました。

★ require.js (11件)

★ load.js (2件)

★ HeadJS (1件)

  • 公式サイト:http://headjs.com/
  • ライセンス:MIT License
  • 開発:Tero Piirainen

Modernizr(33件)のloadメソッドにもyepnope.js(0件)と互換のAPIを持ち、またSenchaフレームワーク(1件)やYeoman系フレームワーク(1件)にも活用されています。このため、上記の一覧が全てであるとは言い切れません。

ただ、単体での利用では、CommonJS準拠であり多くのフレームワークでも活用されている「require.js」がベストプラクティスであると判断できます。

CSSファイルとFOUC問題対策

CSSファイルは、JavaScriptや画像とはまた違った特性の問題を持ちます。

Webページを読み込み時、WebブラウザはHTMLドキュメントの内容を読み取り、逐次「レンダーツリー」という見た目の情報を整理します。

WebページはHTMLドキュメントを全て読み込んだ後に一括で表示するのではなく、読み込みを行いながら逐次Webブラウザのビューポート(コンテンツの表示エリア)に表示していくことで、体感速度の改善を図っているのです。

レンダーツリーを含む様々なツリー構築プロセスは「フロー処理」と呼びますが、その処理にはCSSプロパティ情報を必要とします。フロー処理完了後に遅延させてCSSファイルを読み込んでしまうと、これまで構築したレンダーツリー内で、影響のある範囲の情報を全て再修正を行なうことになり、フロー処理のパフォーマンスを劣化させることになります。

f:id:furoshiki0223:20131014021125p:plain

また、HTMLドキュメントの読み込み完了後からCSSファイルの読み込み完了までの間、ビューポート上にはCSSプロパティが適用されていない状態で表示されることになります。

非常に小さなファイルであれば気になりませんが、大規模なものになると読み込み直後に不格好な画面を一瞬だけユーザに見せてしまうことになります。これを「FOUC(Flash of Unstyled Content)」と呼び、一般的にはアンチパターンとして扱っています。

f:id:furoshiki0223:20131014021659p:plain

上記の特性から、CSSファイルのロード処理を最高のパフォーマンスで動作させることができるのは、フロー処理が開始される前です。

フロー処理は「フローコンテンツ」の読み込みによって行われ、これらはbody要素内に含めて記述するのがWeb標準のお約束です。つまり、head要素内で行うのが、ベストプラクティスです。

<head>
    ・・・
    <link rel="stylesheet" href="xxx.css" />
</head>
<body>
    ・・・
</body>

ただし、特定の条件を満足させた場合のみ特定のCSSファイルの内容を反映させたいというケースがあります。CSSファイルの読み込みはbody要素内で読み込んでも問題無いため、この場合例外的に遅延ロードは許容するというお作法があります。

多くの場合、JSライブラリを経由するのが一般的で、HTMLドキュメントのエディタは、CSSファイルが遅延ロードされていることを意識するようなことはありません。1300中17つのサイト(1.30%)にて対策が確認されました。

★ styleswitcher.js (17件)

注意点

画像の遅延ロードについては、PNG Fix対策と競合するため注意が必要です。遅延ロード対象は写真・絵でJPGフォーマットのみに限定し、PNG Fix対象はアイコン・ロゴをPNGフォーマットで縛るといった、用途ごとの使い分けが求められます。

Lazyloadは予め画像の縦・横サイズをimg要素に明示しないと、無駄なフロー処理を発生させることになります。このため、ユーザがアップロードした画像に対して利用する場合、サーバ側で画像の解析を行なう必要があります。こうした問題を解決してでも、対策が必要と感じる時に利用すべきです。

JavaScriptのAMDは、元はサーバサイドJavaScriptが発祥で、DHTMLベースRIAの実装技術として輸入されたものです。JavaScriptであまり複雑なことをさせない場合は、オーバヘッドが大きいためお勧めできません。script要素のdefer属性を利用する程度にしておくのが良いでしょう。

多くは、Webの進化で発生した問題への対応策で、正攻法とは言い難いです。Web技術を扱うプレイヤーはとても多様なので、ドメインを履き違えると逆に問題を大きくしてしまいます。何に対する対策なのかを明確にして、実装の可否を判断は慎重に行なうようにして下さい。

このブログの筆者について

川田 寛

コンテンツサービスの開発や運営代行を専門とする集団「株式会社ブートストラップ」の社長です。ネットではふろしきと呼ばれています。

2009年にNTTグループへ新卒入社し、ITエンジニアとしてクラウド技術・Web技術の研究開発と技術コンサルティングに従事。2015年よりピクシブに入社し、エンジニアリングマネージャー・事業責任者・執行役員CCOなど、様々な立場からコンテンツサービスの事業づくりに関わりました。2021年にメディアドゥへVPoEとしてジョインし出版関係の事業に関わったのち、2023年に独立しています。

関わってきたインターネット事業としては、ECサービスのBOOTH、UGCプラットフォームのpixiv(主に海外展開)、制作ツールのpixiv Sketch、VR・VTuber関連ではVRoid、Wikiサービスのピクシブ百科事典など、10を超える多様なCtoCコンテンツサービス。また、NTTドコモのすご得コンテンツ、メディアドゥのWeb3サービスであるFanTopなど、いくつかのBtoCコンテンツサービスにも関わってきました。

幸運なことに、私はコンテンツに関係する幅広いインターネットサービスのテクノロジー&ビジネスの知識を得ることができました。これを日本のコンテンツ発展に役立てたいと思い、株式会社ブートストラップを創業しました。

このブログでは現在、出版社やIPホルダー、ライセンサーといったコンテンツに関わる人々に向けて、インターネット事業に関するTipsや業界内のトレンドなどの情報を発信しています。私と話をしてみたいという方は、以下のフォームより気軽にご連絡ください。

お問い合わせフォーム