LazyなLazyload

Google PageSpeed Insightsのテスト結果を見ながらページの読み込み速度高速化のための最後の切り札として導入したjQuery Lazyload。

このブログでは起きなかったのに何故か別のブログではレンダリングブロックが発生して30ポイント近くもパフォーマンスが悪化。

ページ読み込み速度が向上すると期待した画像遅延読み込みで、パフォーマンスが向上するパターンと下落するパターンがある模様。

ちなみに Wordpress の jQueryプラグインはとても賢くて、確認したところレンダリングブロックは発生していません。(他のプラグインはブロックしまくりですが)

jQuery Lazyload 単体の導入で、どうしてブログによって結果が違うのか、その原因とは何なのか。

Sponsored Link

Sessaa ブログの jQuery Lazyload 基本設定

パフォーマンスに大きな違いが出たのは、このとある秘密ブログの更新うぇぶろぐと似たようなつくりのブログA。Seesaaブログなので Wordpress のようにプラグインではなくjQuery.Lazyload.min.js を cloudflare から読み込んでいます。

HTMLの設定

<script src='//cdnjs.cloudflare.com/ajax/libs/jquery_lazyload/1.9.5/jquery.lazyload.min.js'></script>

コンテンツ(#content)とサイドバー(#sidebar)の両方で、lazyクラスは指定せず全ての画像で遅延させるように設定。

$("#content img").lazyload({effect:"fadeIn",threshold:200,effectspeed:500}),
$("#sidebar img").lazyload({effect:"fadeIn",threshold:100,effectspeed:500})

記事の設定

<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAGUExURf///wAAAFXC034AAAABdFJOUwBA5thmAAAADElEQVR42mJgAAgwAAACAAFPbVnhAAAAAElFTkSuQmCC' data-original='実際に表示する画像.jpg' width='480' height='320' alt=''>

事前読み込みのダミー画像は 1 x 1ピクセルの PNG 画像を Base64 でエンコードしたもの。実際に表示する画像は Picasa Web アルバムに置いている画像リンクが入ります。記事中の全ての貼り付け画像にこの形式で遅延読み込みを指定しました。

PageSpeed Insights のテスト結果

下図は jQuery Lazyload を有効にしたときと無効にしたときのブログAの PageSpeed Insights テスト結果です。PageSpeed Insights Lazyload導入前後

有効時64ポイント、無効時90ポイント。26ポイントの差。修正が必要と提示された改善ポイントは以下2件。

スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する

このページには、レンダリングをブロックするスクリプト リソースが 2 個あります。これが原因で、ページのレンダリングに遅延が発生しています。

以下のリソースによる読み込みが終わるまで、このページでスクロールせずに見えるコンテンツを約 36% しかレンダリングできませんでした。ブロックするリソースの読み込みを遅延させるか、非同期に読み込むか、これらのリソースの重要部分を HTML 内に直接インライン化してください。
レンダリングをブロックする JavaScript を除去してください:
http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js http://cdnjs.cloudflare.com/…ry_lazyload/1.9.5/jquery.lazyload.min.js

表示可能コンテンツの優先順位を決定する

スクロールせずに見えるコンテンツをレンダリングするには、追加でネットワークのラウンド トリップが必要です。最適なパフォーマンスを得るには、スクロールせずに見えるコンテンツをレンダリングするのに必要な HTML の量を減らしてください。

HTML レスポンス全体だけを使用した場合、スクロールせずに見えるコンテンツが、最終的に表示される内容の約 36% しかレンダリングできませんでした
スクリーンショットを見る。

1件目のjQueryのレンダリングブロックはもう見慣れてますが、問題は2つめの表示コンテンツの優先順位。アイキャッチ画像が全く表示できてない。パソコンのテスト結果に至ってはラウンドトリップなしの1回目の読み込みで 21% しかレンダリングできなかったと。

レンダリングブロックの原因はアイキャッチ画像の遅延読み込み

トップページのアイキャッチ画像の読み込み速度を上げるために導入した jQuery Lazyload。ところがレンダリングブロックを起こしていた原因は、皮肉なことにこのアイキャッチ画像の Lazyload 設定でした。

  1. ページの読み込みを開始
  2. 最初に表示されるべきアイキャッチが遅延読み込み対象
  3. フッター下に記述した jQuery.min.js と jQuery.lazyload.min.js の読み込みと jQuery, JavaScript の処理完了を待つ
  4. その後アイキャッチ描画開始

だからレンダリングブロックが発生。1回の読み込みで 36% しかレンダリングできなかったのはそのため。

つまり Above The Fold(ATF:画面に見えるている部分)の画像に Lazyload を指定してはいけないということです。

先ほど「記事中の全ての貼り付け画像に Lazyload を設定した」と書きましたが、実はそれが大間違い。ページ読み込みを高速化させるためにはアイキャッチをLazyloadから除外しないと逆効果です。

jQuery Lazyload のレンダリングブロック回避策

アイキャッチ画像の読み込み速度を改善したかった。なのに Lazyload がパフォーマンスを落としていたとなれば対策を考えないといけません。

アイキャッチ画像をLazyloadから除外する

全ての画像を遅延読み込みなどと欲張らずに、基本通り Lazyクラスを付与した画像のみ遅延。そしてアイキャッチ画像はオリジナル画像1本で Lazyload 対象外とする。

$("#content img.lazy").lazyload({effect:"fadeIn",threshold:200,effectspeed:500}),
$("#sidebar img.lazy").lazyload({effect:"fadeIn",threshold:100,effectspeed:500})

アイキャッチ画像をLazyload対象外とすることで、PageSpeed Insights 修正が必要だった2項目はキレイさっぱり解決しポイントが飛躍的に上がります。

そもそも jQuery Lazyload は導入しない

ブログに使っている画像と言えば記事先頭のアイキャッチ画像くらいで記事中の画像は多くない。アイキャッチ画像を遅延読み込み対象外としたら遅延させる画像がほとんど無い。そういうケースでは Lazyload を導入しないことです。

画像をロスレス圧縮して最小化。実際の表示サイズよりも小さい画像をリンクし width, height で少し拡大表示する方が良い。

でも、これだけ有名なプラグインだし、ネットで画像遅延読み込みで検索すると Lazyload が出てくるし、導入すればパラダイスみたいな記事も多いし。やっぱり導入したほうがパフォーマンスが向上するのでは?

Lazyload を導入するとページ読み込みが格段に速くなるという誤解

先述の通りアイキャッチ画像に Lazyload を設定するとパフォーマンスが落る。どれくらい落ちるのか比較したのが下表です。

アイキャッチ画像をオリジナル(High)と劣化版(Low)の2つ作成。劣化版は縦横2分の1サイズ。img src は劣化版で data-original はオリジナルという記述。アイキャッチが表示される10記事のトップページを読み込み、アイキャッチ画像のみ抜粋したもの。測定は Chrome Developerツールの Network。

アイキャッチ画像にLow画像を指定したときのLazyloadパフォーマンス

アイキャッチに劣化画像を指定した場合、Low画像のデータ量 127.6KB を 284ミリ秒で読んでいます。但し PageSpeed Insights ではレンダリングがモバイル 36%、パソコン 21% と ATF すら読み込みが完了していないという低評価。

ページ最下部までスクロールダウンしてオリジナル画像(High)を読み込ませると Low, High の合計で 385.5KB を 786.5ミリ秒で完了。

一方、同じブログでアイキャッチ画像はオリジナル(High)のみ、Lazyload は無効(data-original無し)にしている状態のトップページ測定結果が下表です。

アイキャッチ画像にLazyloadを指定しないときのパフォーマンス

10記事分のアイキャッチ画像を全て読み込んだとき、データ量 259.6KB を 565ミリ秒。Lazyload有効時に比べほぼ2倍のサイズと読み込み時間が掛かっている。但し、PageSpeed Insights の評価はモバイル・パソコンともに高パフォーマンスに分類される緑色の約90でレンダリングブロックもありません。

レンダリングが完了するまでに2回、3回とラウンドトリップを重ねてアイキャッチ画像の読み込みが完了する「アイキャッチ画像もLazyload版」と2倍の負担が掛かるけどレンダリングブロックを起こさずに1回の読み込みで表示が完了する「Lazyloadは導入しない版」。どちらが良いかは説明するまでもありません。

ページ読み込み速度比較

注目したいのはページ全体の読み込み速度です。備考欄のページ読み込み速度を比較すると、Lazyload有効時が 2.27秒、無効時が 1.98秒。

測定は10回。Chrome Developerツールを有効にした状態で「キャッシュの消去とハード再読み込み」を5回、通常再読み込みを5回、この10回の平均値です。

コンマ3秒程の差で無効時の方が返って速い。もちろん実際にスマホやパソコンからの読み込みで ATF だけの読み込みを比較したら Lazyload 有効時の方が速いはず。でも jQuery Lazyload に劇的な読み込み速度改善を期待していたワリには拍子抜けの検証結果です。

Lazyloadがあってもなくてもページ全体の読み込み速度はほとんど変わらない前提であれば、レンダリングがブロックされる Lazyload をアイキャッチに設定する意味はまるでないという結論。

おわりに

PageSpeed Insights で jQuery.min.js や jQuery.Lazyload.min.js がレンダリングブロックを起こしていると注意されると、この2つ自身が重たすぎると誤解していました。しかしそうじゃない。今回アイキャッチ画像に誤って遅延読み込みを設定してしまったように、jQuery.js や lazyload.js を呼んでいる別の要因がこれらを犯人に見せていたということでした。

それからモバイルフレンドリーという観点では jQuery Lazyload ってどう判断されるのか気になる所です。上の検証のように画像オリジナル版と劣化版を2つ用意するというパターンが結構あると思うのですが、結局、ページを最後まで見たときは劣化版とオリジナル版のペアを両方読み込むことになる。ほぼ倍のデータ転送量が発生。

ATF だけ考えれば確かに画像遅延読み込みは有効に思えますが、記事を読み進む閲覧者はポロリポロリとオリジナル画像を読み込んで行くわけで。結果ダウンロード量が約2倍になる劣化版画像遅延読み込みってモバイルフレンドリーなんでしょうか。ちょっと違うような気もします。

ただ冒頭に書きました通り Wordpress の Lazyload プラグインはこういう問題は無いみたいです。あくまでも単体で jQuery Lazyload を導入したときの話です。

このカスタマイズでのスコアアップは?

このカスタマイズでアップする Google Pagespeed Insights のスコアは26。90越えの道のりはまだまだ長いのであります。

Sponsored Link

この記事へのコメント

1件
とてもいい記事ですね!

実際、画像の遅延読み込みは完全ではありません。そもそも画像は(基本的に)レンダリングブロックしないので、普通に読み込んでおけば良いと思います。

ちなみに、ファーストビューのアイキャッチ画像に関しては(容量が少ないのなら)base64でhtml内に埋め込むと良いですよ。ファーストビューの表示が高速化されます(利用者のブラウザにキャッシュされませんが、そもそも容量の少ない画像がキャッシュされるメリットはそこまでありません。それよりも、ファーストビュー内で通信が発生しないメリットのほうが大きいです。(ユーザー体験としても、ファーストビューがサッと出てきたほうが嬉しい)

あと、個人的に遅延読み込みをしてみたいのは広告ですね。広告をスクロールして画面内に入った段階で読み込む、というふうにすれば、ユーザー体験は大幅に上がりそうです。

あとの課題は、ファーストビューの広告ですね。ファーストビューの広告は通信を伴うため、非同期だとしても、画面の体感レンダリングが遅れます。かといってファーストビューから広告を外すのは、収益とのバランスで厳しい、、

という感じです。この課題さえクリアできれば、ほとんどのサイトはおなじような技術で高速化できるかもしれません。
at
コメントをどうぞ
お名前:[必須入力]

メールアドレス:

ホームページアドレス:

コメント:[必須入力]

Sponsored Link