公開日: 2019-09-20
更新日: 2020-05-27

Laravel Bladeに@inlineディレクティブを実装し、CSSやJavaScriptをインライン読み込みに変更して、パフォーマンスを向上させる。

リソースのインライン化

これまでLaravel Mixを使ってCSSをカスタマイズしたり、Font Awesomeの表示を高速化したり、 instant.pageをminifyして、CSSやJavaScriptのリソースの削減に努めてきました。
これらのファイルを外部ファイルとして参照する場合、読み込みの完了を待つため、ブロッキングリソースとして扱われています。
今回は、これらのファイルをインラインリソースとして読み込むように変更を行い、さらにパフォーマンスを向上させます。

最初に、LaravelのテンプレートエンジンであるBladeが外部ファイルをインライン展開できるように、新しいディレクティブを追加します。 Bladeの拡張については、こちらに解説があります。
AppServiceProvider.phpboot()メソッドに新しいディレクティブ@inlineを追加します。 @inlineディレクティブは、渡された引数をインライン読み込みするファイルのパスとして、readfile()メソッドで読み込み、標準出力に出力します。

use Illuminate\Support\Facades\Blade;

/**
 * Bootstrap any application services.
 *
 * @return  void
 */
public function boot()
{
  Blade::directive('inline', function($path) {
    return "<?php readfile($path); ?>";
  });
}
            

file_get_contents()を使うこともできるのですが、readfile()の方がより高速に動作するとのことなので、今回はreadfile()を使います。

次に、layouts/app.blade.phpなど、外部のリソースファイルを読み込んでいる箇所を下記のように修正します。

<!--
  <link rel="stylesheet" href="{{ asset('css/fontawesome.css') }}">
-->
  <style>
    @inline(public_path('css/fontawesome.css'))
  </style>

  :

<!--
    <script src="https://tiny-services.com/js/instantpage.js" type="module" defer crossorigin="crossorigin"></script>
-->
    <script type="text/javascript">
      @inline(public_path('js/instantpage.js'))
    </script>
  </body>
</html>
            

修正したら、ブラウザで正しく表示されることを確認します。正しく表示されていたら、次はソースを表示して、CSSのファイルがインライン展開されていることを確認します。 view-source

確認したら、ブラウザの検証ウィンドウからネットワークのタブを開いて、外部リソースとして読み込まれていないことを確認したり、Google PageSpeed InsightsGTmetrixなどのサービスで現在のパフォーマンスを計測しましょう。 のみログ

@inlineディレクティブはCSSだけでなく、JavaScriptもインラインリソース化することができるので、ブロッキングリソースとなっているCSSやJavaScriptのうち、サイズが小さなものについては、インライン化していくのがいいでしょう。