RitoLabo

LaravelでAMPページを作成するベストプラクティス

  • 公開:
  • 更新:
  • カテゴリ: PHP Laravel
  • タグ: Laravel,Webpack,5.5,5.4,5.3,Build,sass,AMP,CSS

昨年頃から段々と話題になってきたAMP(Accelerated Mobile Pages)ページですが、今や実装も当たり前になりつつあるかなと思いつつ、ここで一度、LaravelでAMPページを作成する際の自分なりのベストプラクティスをまとめようと思います。

というのも、LaravelでAMPぺージを作成する方法は1つではありません。ミドルウェアで、コントローラでと、処理の流れも含め実装手段はいくつでもあります。

はっきり言ってどの方法が最も優れているというような結論は出ないと思います。そしてそもそも、そういう話ではないと思っています。

大切な事は、開発するWEBアプリケーションによってベストな手法で実装する事です。

ここでいう「ベスト」というのは、実装の手間を少なくするかとかロジックを最短にする事、色々とこねくり回さなくて済むような手法でという意味です。

AMPページを作成しようとする時点で既に通常のページが出来上がっている事を想定していますが(新規開発時に企画出来ているともちろんベストです)、AMPページを作成する為にロジックをあれこれとAMPぺージ用に組むと、機能追加や修正の際に工数が肥大化し、作業が大変になってしまいます。

なのでAMPページを実装する際には、対象のWEBアプリケーションとを突き合せた設計がとても大切です。

のっけからまとめ的な雰囲気ですが、ここにLaravelでAMPページを作成する際の一つの実装パターンを紹介します。

LaravelでAMPページを作成するロジック図

この図を基にこれから解説していきます。

CSS、style開発のロジックについて

まず、スタイル周りについてですが、開発時にはSASSで実装し、Webpackでコンパイルを行う流れを推奨します。

ここで一つ補足しておくと、LaravelではSASSなどのコンパイルに関して、5.4以降はWebpack、それ以前ではGulpでのコンパイルを標準で提供しています(厳密に言えば5.3以前でもwebpackは提供されています)。API名称としては

  • 5.4以降 Laravel Mix
  • 5.3以前 Laravel Elixir

という事になります。

本記事ではこれから「webpackでのコンパイル」と記載しますが、どのバージョンであっても、それぞれのAPIでのプリプロセッサーを使う。という事を指しています。なので、基本的にはLaravel5系であればバージョン関係なく実現は可能です。

それでは本題へ戻ります。図での流れを解説すると、webpackでSASSをCSSにコンパイルする際にいきなり1つのファイルにまとめるのではなく、一度それぞれのSASSファイルをそれぞれのCSSファイルにビルドしてから、それをpublic.cssにまとめる。という流れになっています。

こうする事によって、機能・ページ別でCSSを分けられるので、AMPページに必要なだけのソースをコントローラから取得する事が出来るようになります。

では何故こういった流れにするのか?利点(必要性というべきか)としては、AMPぺージのCSSに関するルールが関係しています。

AMPぺージでは、通常ページのように「<link rel="stylesheet" href="~">」のようにしてCSSファイルを外部読み込みする事が許可されておらず、headタグ内に「<style amp-custom></style>」として直接記述する必要があり、そしてそれは、50KB以内という制限があります。

故に、通常ページと同じスタイルを使った場合、50KBの制限をオーバーする可能性があります。(ちなみにbootstrapのコアソースなどは余裕でアウトです)

もちろん制限をオーバーすれば、それはAMPページとして認められません。

LaravelではデフォルトのSASSにbootstrapがインクルードされていたりするので、気を付けたいところです。

とはいえ、AMPぺージの為だけに「そもそもbootstrapは使わない」という選択は違うと思いますので(というか、AMPページを実装しようと思った時点で既に一通りの通常ページは実装済みの場合が多いので、既にbootstrapを使ってしまっているよ!泣 みたいな事も往々にしてあるでしょう)、bootstrapを使うなら使うで、ビルド時に一度、それぞれのCSSファイルにビルドしておく事で、AMPぺージの時には必要なだけのCSSを取得し再構築する事で必要最小限のスタイルを用意できる。という仕組みを構築する事が出来ます。

コントローラのロジックについて

コントローラでは、通常ページと同じロジックで必要なデータの取得をモデルから行うので、基本的にはAMPぺージ用にデータ取得のロジックを変更する必要はありません。

この点に関して突っ込んだ話をすると、2017年11月28日のGoogleウェブマスター向け公式ブログにて
「通常ページとAMPぺージでは同一のコンテンツが配信されるべきである」
とアナウンスされており、AMPぺージだから表示内容を制限する。といった考え方はNGとなりました。(よくある「続きを読む」みたいなAMPページは今後淘汰されていくと思われます。)

そういった点からも、モデルからのデータ取得に関しては通常ページと同一でいくべき=いかに基本ロジックにて通常用とAMP用の処理が別れないかが大切だと思います。

ちなみに今回のロジックの場合では、

  • 通常ページかAMPぺージかを判定する処理の追加
  • AMPぺージの時のみ追加処理を行う処理の追加

この2点だけで済む事になります。

通常ページかAMPかを判定する処理

色々な実装方法があると思いますが、一番簡潔にいくのはURL判定かなと思います。例えば

  • 通常ページ: /page
  • AMPぺージ: /page.amp

とした場合は、簡単なURLのParseでAMPのリクエストかどうかを判断する事が出来ますので、冒頭で判定して結果を変数に持たせておけば、あとはAMPぺージか否かで追加処理を実行していけばよいだけになります。

AMPぺージの時のみ追加処理を行う処理

ここについてはまさに、開発するWEBアプリケーションによって様々なパターンがあると思いますが、今回の図に示しているのは
「モデルから取得したデータにHTMLタグやインラインスタイルが含まれるものがある場合」
を指しています。

つまり、CMSなどでユーザによる入力機能をWYSIWYGで構築してる場合などです。ブログシステムや掲示板システムのような場合ですね。

図では「convert HTML source to AMP-HTML」の部分になります。

ここでは、モデルから受け取ったデータの中の、HTMLタグやインラインスタイルが含まれるデータについて、AMPぺージ用の変換を行うという流れを示しています。

変換の手段としては正規表現がおすすめです。WYSIWYGなどを取り入れている場合には不規則かつ無秩序にHTMLタグやスタイルが差し込まれる事も往々にしてあるので、あらゆる書式に対応できる点でおすすめです。

順番はどちらからでも構いませんが、HTMLの変換については結構決め打ちで行えるので、まずはHTMLタグをAMPぺージ用に変換してしまうのが良いでしょう。

そして次に、データ内から取り出したスタイルをクラス定義(CSSのクラスです)していき、クラス名に置き換えていきます。

簡単に紹介すると、以下のような変換を行います。

<p style="AAA:aaa; BBB:bbb;">sample</p>

<p class="amp_01">sample</p>
.amp_01 { AAA:aaa; BBB:bbb; }

全ての置き換えが完了したら、クラス定義したCSSソースを、必要なものだけ取得したCSS内に追加する。という流れになります。

これでCSSに関しては、どんなインラインスタイルがあったとしてもHTMLから除去し、head内のstyle amp-customに乗せ換える事が可能になります。

インラインスタイルの変換に関しては、そのデータにどういったインラインスタイルが存在しているかによって都度行うので、動的にクラス設定を行うようなイメージです。なのでクラス名は機械的なものでよいと思います。(「.a01」「.a02」...のような)

先ほど少し触れましたが、CSSに関してはビルドした個別のCSSファイルから必要なものだけを読み出し、そこにインラインスタイルを変化したスタイル達を追加してあげる事で、そのAMP専用のstyle amp-customが完成します。

これで、ビューにデータを渡す直前の時点で必要なデータとCSSが用意できた事になります。

ビューのロジックについて

ここも2通りの実装方法があります。ビュー、LaravelではいわゆるBlade.phpを、通常ページとAMPで1つにしてしまう方法と、それぞれを別に分ける方法です。

ビューにどれくらいの記述量があるかにもよりますが、記述量が多いとBladeテンプレートの中でAMPか否かの条件分岐によってあれこれ書くのは結構ごちゃごちゃしてきて見通しが悪くなる(レイアウトで切り出したとしても)場合が多いので、基本的にはビューは分けてしまう方が後々メンテナンスし易いと思います。

個人的には、ビューディレクトリの中に通常用とAMP用でディレクトリを分けてしまい、共通のコードはレイアウト化しそれぞれで読み込む。といった構造の方が後々メンテナンスしやすいし、冗長にもなりにくいなと思いますが、それももちろんビューのコード量と個人の好みがあるので、規模や好みで決めれば良いと思います。

そして図にもある通り、通常ページの場合はlink relでpublic/css/public.cssを読み込み、AMPの場合はhead内にstyle amp-customを設置しその中に生成したスタイルを置く、という流れになります。

この流れを組む事で、通常ページとAMPの場合の重複コードがほぼなくなります。

まとめ

紹介は以上になります。

コントローラの部分でHTMLやインラインスタイルを置換する処理を紹介しましたが、通常ページよりも処理が増えるので、処理する量によっては多少オーバーヘッドが発生します。

ですがAMPページとは、最終的にGooleがキャッシュし、表示してくれるものなので、その辺りの心配はほぼ気にしなくてよいでしょう。(もちろん何事も、やりすぎは良くありません)

LaravelでAMPページを実装する際には、「どこをAMP対応させるのか」「現在のアプリケーションのベースロジック」そして「AMPの仕様」をよく確認し、まずは設計を行ってから開発に入る事が大切です。

最後に、2017年10月8日(日)に大田区産業プラザ PiOにて開催された「phpcon 2017」において、株式会社イノベーション 小柳津裕真氏が登壇した 「モバイルページを爆速に~Laravelで実現するAMP対応の自動化~」 のスライドを紹介して終わりにします。

私も会場で拝聴しましたが、ミドルウェアを使ってAMPページを生成するロジックについて話されていたので、本記事を最後まで読んだのであれば是非参考までに目を通すと良いと思います。