3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

PHPのincludeを簡単に非同期化するLazy Includeコンセプト

PHPで別ファイルのHTML部品を読み込むincludeを、できるだけ簡単にJavaScriptによる非同期読み込みに変えちゃおうという試みです。名付けてLazy Include

php-lazy-include
https://github.com/miyanaga/php-lazy-include

画像の遅延読み込みLazy LoadもちょっとしたHTMLとJavaScriptのトリックですが、それをHTMLの断片にまで拡張したものです。

※ 上記のソースコードは実用的なライブラリではなく、コンセプトの実装例です。ぜひ改良してみてください!

コンセプト

ソースコードはよく見るPHPのincludeです。

index.php
<div>Main File</div>
<?php include('includee.php') ?>

includeされる側のファイルも通常通りHTML断片を出力するPHPですが、先頭と末尾に1行ずつ決まったおまじないが記述されています。

includee.php
<?php if(include('lazyInclude.php')) return ?>
<div>Sub File</div>
<?php endLazyInclude() ?>

結果

上記のソースが実行されると、次のようなHTMLとJavaScriptに展開されます。

includeを行った場所にひとまず目印となるdiv要素を置いておき、DOMContentLoadedイベントでそこに元々includeされるはずだった内容を展開するという流れです。

index.php
<div>Main File</div>
<!-- 非同期にincludee.phpの内容を展開する目印 #the-lazy-include -->
<div class="lazy-include" id="the-lazy-include"></div>
<script>
/* <script src="/includee.php?id=the-lazy-include"> をbody末尾に追加 */
window.addEventListener('DOMContentLoaded', function once() {
  window.removeEventListener('DOMContentLoaded', once);
  var script = document.createElement('script');
  script.setAttribute('src', "\/includee.php?id=the-lazy-include");
  document.body.appendChild(script);
});
</script>

bodyに追加されたscript要素は次のJavaScriptを読み込んで実行します。

includee.php
/* 目印 #the-lazy-include にincludee.phpの本来の内容を展開 */
document.getElementById("abc").innerHTML = "<div>Sub File<\/div>\n";

2行のおまじないを追加すると、JavaScriptによる非同期includeになり、そのおまじないを除去するとPHPによる普通の同期includeに戻るというものです。

何が嬉しいの?

ページの読み込み直後のレンダリングから、Lazy IncludeしたDOMを除外することで表示の高速化を図っています。

PageSpeed Insightsの点数はどのように計算されているか。100点をとるための条件」という記事で、PageSpeed Insightsの点数においてはファーストビューの描画時間が重要であると書きました。

このHTMLデータ自体の軽量化もさることながら、初期のDOMのオブジェクト数を減らすことはPageSpeed Insightsの点数アップにもよい影響が期待できます。

そのような非同期処理が、JavaScriptの記述不要で簡単に実現できます。

ユースケース - ボリューム感のあるフッター

フッターにサイトマップをまるごと掲載するサイトが増えています。サイトによってはクローラー向けの内部リンク目的だったり、デザイン上どっしりボリューム感を出す目的かもしれませんが、ユーザーにとっては無駄の多いコンテンツです。

  • たまに役立つかもしれないがそこまで滅多にスクロールしない。
  • 大規模サイトだとけっこうなHTMLの量とDOMオブジェクトの数がある。
  • ほとんど変更されないのに毎回毎回、HTMLに含まれて送信される。

もしSEO上の意図がないのであれば、Lazy Includeによって少し後でレンダリングすることで次の効果が期待できます。

  • 読み込みとファーストビューの描画が速くなる。
  • JavaScriptのキャッシュでブラウザにキャッシュを持たせることもできる(上記コードではExpiresヘッダは未実装)
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
3
Help us understand the problem. What are the problem?