WEBページを高速表示させるための研究成果

WEBページを高速表示させるための研究成果

最近ふと思ったのですが、「小さい、遅い」と聞いた時よりも、「大きい、速い」と聞いた時の方がなんとなく優位に感じますよね……。
つまり「小さい、遅い」はネガティブワード、そして「大きい、速い」がポジティブワードなのではないかと。

スーパーで果物や生鮮食品などを買う時は、同じ価格なのであれば「小さい」よりも「大きい」方がトクした気分になりますよね。買い物だけでなく、仕事だって「遅い」よりも「速い」ほうが圧倒的に良いわけです。

ことインターネットに関しても、ダウンロード速度は「速い」ほうが良いに決まっているし、ゲームをしていても「30fps※」よりも「60fps」が良いというわけです。
(※「fps」……frames per second。1秒あたりの静止画像数を意味し、数が多いほど滑らかな動きとなる)

前置きが長くなりましたが、ホームページに関しても、表示速度は「遅い」よりも「速い」ほうが確実に良いということは、過去のbitWaveでも何度も記事としてご紹介いたしました。
<bitWave関連記事『HTTP/2で爆速。ブラウザ表示速度が驚異的に速くなる実験結果』>
<bitWave関連記事『DNSキャッシュでWebの表示速度は速くなるか試してみた』>
<bitWave関連記事『モバイルの表示速度を上げるTips(SEO効果も)』>
<bitWave関連記事『読み込み速度の重要性』>
<bitWave関連記事『NEED FOR SPEED|世界最速のブログを発掘!!』>

大手ECサイトや検索エンジンに関して、「高速化することで業績向上に繋がる」という調査や分析などを公表しているデータもあり、世の中的にはマイクロ秒単位でも「速く」したいというニーズはあるようです。
「Google AMP」が昨年後半に次々と発表をする中、弊社研究室でも独自にWEBページを高速に表示させること技術の追求をしてみました。
今回はその成果を本記事で発表したいと思います。

何故企業のWEBページが遅いのか

多くの企業がCDNを活用したり、質の良いWEBサーバや回線帯域を確保しているため、非常に良好なスピードを出しているケースはあります。しかし、そうした施策を行っているにも関わらず、アクセスしてから表示までが非常にスピードが遅い企業ページがあったりもします。さすがにどことは言いませんが、WEBページを閲覧した際に、「遅い!」と感じたらそれが該当ページです。

考えられる主な要因は下記のとおりです。
要因1『外部ドメインで使っているサービスが遅い』
要因2『ブラウザのブロッキング制限に引っかかって遅い』
要因3『画像や各種プログラムの容量が圧迫して遅い』

要因1『外部ドメインで使っているサービスが遅い』

とにかくブラウザのデバッグツールを見ている限りでは、かなりの確率で広告バナーなどが遅いケースが多いようです。

すべてというわけではないものの、表示まで時間がかかったり、バナーのコンテンツが容量が肥大化していたり……。非同期処理が行われていなければ、コンテンツをダウンロードするまでページの読み込みは完了しません。最悪の場合、その読み込み中の間はずっと画面が真っ白のまま……なんていうケースもしばしば見受けられました。

要因2『ブラウザのブロッキング制限に引っかかって遅い』

Chrome、IE、Firefoxなどは、ブラウザ毎にサーバから同時に読み込みができるファイル数が制限されています。しかし、そういった情報をユーザはあまり意識せずに利用しているのではないでしょうか。
さらにはこうした事実を考慮していないWEBページ制作会社も多いのかもしれません。

ちなみに本稿執筆時点(2017年4月)では……
Chrome:同時読み込み6ファイルまで(変更不可)
IE:同時読み込み2ファイルまで(変更可能)
Firefox:同時読み込み6ファイルまで(変更可能)

また、ブラウザだけではなく、サーバ側で同時接続数の設定変更も可能なので、WEBページ制作時にこうした認識を考慮した設計ができていることが重要となります。
本当に考えなければいけないことは、ブロッキングの数字を上げることでサーバ負荷が増え、ネットワーク帯域の増大にも繋がってしまいますので、こういった “副作用” さえ知っていれば、制作側での対応もできるのではないでしょうか。

要因3『画像や各種プログラムの容量が圧迫して遅い』

最近のスマートフォンや携帯電話に実装されたカメラの性能はかなり素晴らしいのは周知の事実。撮影したデータをそのままWEBページに掲載させてしまうと、1回の画像表示で数メガバイトもの容量がダウンロードされることになってしまいます。

一昔前の「テレホーダイ」などの定額制サービスが普及していた “ナローバンド時代” では、必ずデータサイズをブラウザサイズよりも小さくし、画像にモアレや粒状感が表示されないレベルのギリギリの圧縮率まで容量削減するというのが、インターネット界の常識でした。
しかし “ブロードバンド時代” を迎えてからは一転、容量がケタ違いに大きい動画コンテンツが当たり前となり、「容量」というものを意識する機会が減ってしまいました。つまり、容量制限のためにしていた努力を止めてしまったようにも思えます。
それでも時代が変わったとはいえ、容量制限はスピードアップに有効な手段であることは変わりません。コンテンツ容量を下げるだけでWEBページは驚くほど速くなるものなのです。

今回の研究に関する制限事項

今回の研究テーマは『既存企業のWEBページを高速表示させる』ということに決まりました。

そして、ショーケース・ティービーで提供するサービスとして考えた場合、以下の制限も条件として加えることにしました。
条件1『すべてにおいてjavascriptを使う』
条件2『ブラウザ上で実行される』
条件3『scriptタグを貼ることで実現できる』

さぁ大変だぞ……果たしてできるのか?????

研究過程

前記のとおり、速度アップの方法はたくさんありますので、最初は色々な視点で「とにかく速くする」ことだけに狙いを定め、以下のような研究をしました。

研究テーマ1『画像の遅延読み込み』
研究テーマ2『背景画像の遅延読み込み』
研究テーマ3『CSS、JSファイルのDL数を絞り込む』
研究テーマ4『JSの遅延読み込み』
研究テーマ5『CSSの遅延読み込み』
研究テーマ6『ページソースのみを取得してJSでコントロールする』

研究テーマ1『画像の遅延読み込み』

すでに「Lazy Load Plugin for jQuery」というライブラリが存在していることは知っていましたが、導入にあたりHTMLソースを書き換える必要が生じています。もっと簡単に導入できることを前提に考えることにしました。
<参照:『Lazy Load Plugin for jQuery』>

ページ内に存在するすべての画像に対して、「Lazy Load」と同じ仕組みになるよう、いったんsrc属性をattributeに移しました。src属性には1ドットの透明データpng情報をbase64で入れておきます。
スクロール、または画面サイズ変更のイベント時に、画面領域内に入った場合にsrcに正規の画像パスを入れ替えてあげるとことで、無事「Lazy Load」処理を実装させることができました。

ポイントは、「既存の画像データを読み込み開始前に、src属性を入れ替えすることができるのか」という点に尽きるのですが、「mutationObserve」というイベントを使うこと、そしてheadタグ内でそうした元設定を行うことで、画像をすべてコントロールすることが可能だったということが分かりました。
ただ、閲覧環境のネットワークやブラウザ状態に依存するようだ。若干のブランクの時間も存在するのは。

研究テーマ2『背景画像の遅延読み込み』

IMGタグ以外にも、最近ではCSSのbackground-imageで画像表示するケースも多いようです。
無断で画像の抜き取りや流用防止を目的としているのかもしれませんが、そもそもIMGタグでないため『研究テーマ1』に挙げた「Lazy Load」の対象外となってしまいます。

IMGタグ以外のほぼすべてのタグで背景画像を扱えてしまうため、少し躊躇しました。
すべてのタグの座標を計算し、任意のclassを付与することでCSSのnot-selector機能を使ってみたろころ、初回読み込み時はページ内のすべての背景画像が読み込まれませんでしたが、スクロールと画面サイズを変更したことにより、すべてのタグ(一部除外)にclass名を付与していくことができ、『研究テーマ1』の「lazy Load」と同じ処理にが働くことが確認できました。

ただ、前記で「一部除外」としたとおり、この機能はすべての事象に適合するというものではなく、JSなどで動的コンテンツなどを読み込むページなどでは、ページが正常に閲覧できないという事象が起こり得てしまいます。
簡易的なやり方としては成立しましたが、実サービスとして盛り込むには不十分でしたので、いったんペンディングとすることにしました。

研究テーマ3『CSS、JSファイルのDL数を絞り込む』

ブロッキング数を極限まで減らすことを考えれば、画像数をサーバ側で対応ができるであれば実現可能です。
しかし極力そこには手を入れずに、CSSとJSの読み込みファイルのみと考えてみました。これらのテキストファイルを文字列としてajaxで読み込み、ただ展開すればいいとも考えましたが、ajaxを読み込む時点でブロッキングの対象になってしまうことに気が付きました。

つまり、画像と同様にサーバ側で1ファイルとして出力しなければならず、この研究は「できない」という結論に至りました。

研究テーマ4『JSの遅延読み込み』

この課題は「async」と「defer」という属性がHTMLで実装されていたので、タグ情報を読み込み開始前にそれを更新しておくことで対応ができます。

一番カンタンなのは、ページのソースコードで外部読み込みのJSには、「async」と「defer」の属性は入れるというルールにした方が無難かもしれません。
残念なことに、SaaSサービスを展開しているような会社のサービスタグの場合、この属性を入れることで動作しなくなるという制限のあるサービスも結構多いようです。

つまり、すべてを同時に行うことは、非常に危険が伴うということですね。
いっそのこと世の中のWEBページの制限事項として、非同期処理がルール化されなければいけないかもしれませんね。壮大すぎることですけど(笑)。

そしてもう一つ残念なことに、弊社の製品も非同期処理で動作しないというものがいくつかあり、今後の改修課題としなければいけないということもあからさまになりました。
これが判明したことを良しとするか、現時点での残念な仕様と判断するかは……、今は言及を避けておきます。。。

研究テーマ5『CSSの遅延読み込み』

不思議なことにCSSにはJSと異なり、非同期読み込みの属性機能が存在しません。
WEBで調べてみると、多くの人や企業がこの機能を欲しがっているようです。

同時に判明したのは、かなり多くの外部CSSファイルが使われているということです。
WordPressのテーマに頼り切っている企業では、自社でどのくらいのブロッキングが行われているかも気づいておらず、ただ闇雲に「遅い!」と言っているだけというケースも少なくはないようです。

ただ、矛盾している点ではありますが、CSSはheadタグ内で読み込みが完了していない場合、ページが読み込まれた後にCSSが適用されることになり、ページがガタついてさらに切り替わろうとする瞬間を目の当たりにすることになります。これを体験すると、かなりのストレスが溜まるようです。

もしかするとWEBページの基本仕様として、CSSに非同期が設定されていないのかもしれません。
ちなみに、この後からCSSが読み込まれてページが「ガクッ」と変わる事象を「FOUC(Flash of Unstyled Content)」と言うらしいですね。知らんかった……。

研究テーマ6『ページソースのみを取得してJSでコントロールする』

最初のヨミでは今回の研究テーマの中でも一番のキラー機能と思っていたのがこの機能。

本来であればAリンクをクリックした際、WEBブラウザのURLアドレスを書き換えてページを遷移させるものなのです。しかし、今回の研究でAリンクを押した時に、対象URLからAjaxでHTMLソースのみを取得し、それを閲覧していたページのBODY内部で入れ替えて展開することで、非常に高速にページ切り替えができることが分かりました。

ただし、この手法にもいくつかの制限があり、一部のサイトにしか使えないことが判明しました。。。
制限1:ページ切り替えの際に「window.onload」などのページ依存イベントの発火が困難
制限2:前ページと次ページにおいて、JSの処理などでグローバルメモリ保存されたデータがクリアされない

しかし、上記のようなデメリットばかりではありません。メリットは以下3つが挙げられます。
利点1:ページの特定部分の更新を行う分には、ページ切り替えを行うよりも遥かに高速
利点2:静的ページに近い、JS実行が無視できるWEBページであれば、ページ全体切り替えが高速
利点3:ページソースを一度読み込んでから適応させるまで、ソースなどをコントロールすることが可能

いくつかのニュースサイトや、ECページで試してみましたが、記事や商品の読み込みなどが非常に高速に行えることが確認できました。もちろんページ内がJSで構成されているページにおいては、一切WEBページが機能しなくなるということもありました。

忘れてならないのはリンク先を切り替えた際、併せてページのアドレスも「history.push」で切り替えてあげると、閲覧ユーザはページが切り替わったことを操作体験できるんですね。

3つのツール誕生!

6つの研究テーマを通して、できること・できないこと、そしてメリット・デメリットを踏まえて3つのツールを作成することができました。

ツール1:タグを貼るだけで画像の遅延読み込みを可能とする『wpa-ImageLazyLoader
ツール2:CSSタグをJSタグに張り替えて非同期読み込みができる『wpa-CssAsyncLoader
ツール3:リンクページのソースと入れ替え『wpa-LinkSourceGetter

これらのツールはOSSとしてGithubに公開しました。
ご興味のある方は、ぜひお試しくださいませ。

WebPageAccerelator
https://github.com/yugetakoji/WebPageAccerelator

また、高速化に関する情報などがあれば、ブログコメントや私宛にメールをください。
引き続き研究を行いたいと思います。

コメント