Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
モバイルページを爆速に ~Laravelで実現するAMP対応の自動化~ #PHPcon2017
Search
yaizuuuu
October 08, 2017
Programming
6.1k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
モバイルページを爆速に ~Laravelで実現するAMP対応の自動化~ #PHPcon2017
PHPcon2017で発表を行ったスライドです。
#PHPcon2017
#PHPカンファレンス2017
yaizuuuu
October 08, 2017
Other Decks in Programming
See All in Programming
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
340
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
190
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
130
カツオ、ご期待ください
suneo3476
0
120
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
Workers Cache を知る
syumai
0
310
FreeBSDでZabbixを動かす
kenkino
0
340
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
270
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
1
2k
Vue Fes Japan 2026 タイムテーブル徹底解説
448jp
1
570
AgentCore CLI で進化した AWS での AI エージェントの作り方 : 必要な機能を必要な時に
icoxfog417
PRO
4
400
SREの越境 / SRE Collaboration
y0hgi
2
290
Featured
See All Featured
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
How to train your dragon (web standard)
notwaldorf
97
6.8k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
Automating Front-end Workflow
addyosmani
1369
210k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.9k
Navigating Weather and Climate Data
rabernat
0
540
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
The Spectacular Lies of Maps
axbom
PRO
1
1.1k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
780
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
SEO for Brand Visibility & Recognition
aleyda
0
4.8k
Transcript
モバイルページを爆速に 〜Laravelで実現するAMP対応の自動化〜 株式会社イノベーション 小柳津裕真
自己紹介 名前: 小柳津 裕真(オヤイヅ ユウマ) 所属: 株式会社イノベーション 好きな技術: PHP, Laravel,
AMP 普段はITトレンドというサービスを開発しています AWS re:Invent 2017参加予定
アジェンダ 1. AMPってなに?? a. AMPとは何か b. なぜ早いのか c. どんな対応が必要なのか 2.
自動化の方法 a. LaravelのMiddlewareを活用 b. 画像サイズを動的に取得
アジェンダ 1. AMPってなに?? a. AMPとは何か b. なぜ早いのか c. どんな対応が必要なのか 2.
自動化の方法 a. LaravelのMiddlewareを活用 b. 画像サイズを動的に取得
AMPとは何か モバイルでブラウザから検索した時、 こんなマークを見たことありませんか??⚡⚡
AMPとは何か モバイルでブラウザから検索した時、 こんなマークを見たことありませんか??⚡⚡
AMPとは何か Q:AMPとは何か A:めっちゃ早いモバイルページ A:Accelerated Mobile Pages A:の略
なぜ早いのか
なぜ早いのか 1. 非同期スクリプトのみを許可 2. すべてのリソースサイズを静的に決定 3. サードパーティJavaScriptをクリティカルパスから外す 4. CSSはすべてインラインスタイルにしてサイズを固定 5.
ページが開かれる前に読み込む https://www.ampproject.org/ja/learn/about-how/ <script async src="~"></script> height="400" width="800" ex.
なぜ早いのか ex. 検索結果が開かれる前に レンダリングが開始
どんな対応が必要なのか 必須マークアップ
<!doctype html> <html amp> <head> <meta charset="utf-8"> <link rel="canonical" href="hello-world.html">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"> <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style> </noscript> <script async src="https://cdn.ampproject.org/v0.js"></script> </head> <body>Hello World!</body> </html>
どんな対応が必要なのか 一部のタグをAMP HTMLタグに置き換える https://www.ampproject.org/ja/docs/tutorials/create/include_image ほとんどの HTML タグは、そのまま AMP HTML でも使用できますが、
中には <img> タグのように同等か少し高機能のカスタム AMP HTML タグに置き換えなくてはいけないものがあります
どんな対応が必要なのか 一部のタグをAMP HTMLタグに置き換える 特定のタグはそのまま活用できない 下のようなimgタグ をAMP HTMLでは、height・width属性を必ず指定する必要がある ※video, audio,
iframeタグもそのままでは使用不可 <img src="welcome.jpg"> <amp-img src="welcome.jpg" height="400" width="800"></amp-img>
どんな対応が必要なのか CSSを一つのインライン要素にする https://www.ampproject.org/ja/docs/tutorials/create/presentation_layout <style amp-custom> body { background-color: white;} amp-img
{ background-color: gray; border: 1px solid black;} </style> 各 AMP ページで使える埋め込みスタイルシートは 1 つだけで、使用で きないセレクターもいくつかあります。
どんな対応が必要なのか CSSを一つのインライン要素にする CSSにもいくつかの制限 1. 他のスタイルシートを呼び出せない 2. !important修飾子は使えない 3. タグ内のstyle属性は使えない 4.
CSSは50KBまで
どんな対応が必要なのか CSSを一つのインライン要素にする CSSにもいくつかの制限 1. l 2. ! 3. 4. CSSは50KBまで
<link rel="stylesheet" href="~"> .mt10 {margin-top: 10px;!important} <div style="~"></div>
どんな対応が必要なのか CSSを一つのインライン要素にする CSSにもいくつかの制限 1. l 2. ! 3. 4. CSSは50KBまで
<link rel="stylesheet" href="~"> .mt10 {margin-top: 10px;!important} <div style="~"></div>
どんな対応が必要なのか 既存ページのAMP対応において厳しいところ 1. 既存のタグでそのまま使えない 2. imgタグで画像のheightとwidthを指定する必要がある ↓ よくある対応:既存ページとは別にAMP対応のページを新規で追加する
どんな対応が必要なのか 既存ページとは別にAMP対応のページを新規で追加する 非AMPページをコピーして 手動でAMP対応に修正する
どんな対応が必要なのか 既存ページからAMPページを手動作成するデメリット 1. 1ページ1ページHTMLをコピーして修正するコスト 2. 非AMPページ(オリジン)の方が変わるとAMP対応ページを変える必要がある
それはめんどくさい
自動でAMP HTMLに置き換えたい
どんな対応が必要なのか AMP対応ページにアクセスされたとき 非AMPページ(オリジン)から AMP対応ページを自動生成する
アジェンダ 1. AMPってなに?? a. AMPとは何か b. なぜ早いのか c. どんな対応が必要なのか 2.
自動化の方法 a. LaravelのMiddlewareを活用 b. 画像サイズを動的に取得
LaravelのMiddlewareを活用 非AMPページからAMP HTMLを自動生成するためには、 以下に対応しなければならない 1. AMPでは使用できない既存のタグの置き換え 2. imgタグで画像のheightとwidthを指定する必要がある LaravelのMiddlewareクラスを活用
LaravelのMiddlewareを活用 非AMPページからAMP HTMLを自動生成するためには、 以下に対応しなければならない 1. AMPでは使用できない既存のタグの置き換え 2. imgタグで画像のheightとwidthを指定する必要がある LaravelのMiddlewareクラスを活用
LaravelのMiddlewareを活用
LaravelのMiddlewareを活用 レスポンスの内容を取得できる
LaravelのMiddlewareを活用 <?php namespace App\Http\Middleware; use Closure; class Middleware { public
function handle($request, Closure $next) { $response = $next($request); return $response; } }
LaravelのMiddlewareを活用 <?php namespace App\Http\Middleware; use Closure; class Middleware { public
function handle($request, Closure $next) { $response = $next($request); return $response; } } // この記述でレスポンスの内容が取得できる
LaravelのMiddlewareを活用 public function handle($request, Closure $next) { $response = $next($request);
$content = $response->getContent(); return $response; } // この記述でレスポンスの // コンテンツ(HTML)を取得できる
LaravelのMiddlewareを活用 レスポンスの内容を取得し、 変更することも可能
LaravelのMiddlewareを活用 public function handle($request, Closure $next) { $response = $next($request);
$html = '<!DOCTYPE> <html> <head> <title>PHPcon2017</title> </head> <body><h1>PHPcon2017</h1></body> </html>'; $response->setContent($html); return $response; } // この記述でレスポンスの内容を変更できる
LaravelのMiddlewareを活用 既存のタグの置き換えは、 でレスポンス内容のHTMLを取得し、 正規表現で置き換え処理を行い、 変更したHTMLを で レスポンス内容としてセットする $response->getContent() $response->setContent($html)
LaravelのMiddlewareを活用 imgタグをamp-imgタグに置き換える例 ↓ <img src="welcome.jpg"> <amp-img src="welcome.jpg"></amp-img>
LaravelのMiddlewareを活用 $response = $next($request); $content = $response->getContent(); $pattern = '/<img
(\s|\w|[\^!"#$%&@\'()*+,.\/~;?:=\\-]|[^\x01-\x7E])+>/'; $replacement = '$0</amp-img>'; $content = preg_replace($pattern, $replacement, $content); $pattern = '/<img/'; $replacement = '<amp-img'; $content = preg_replace($pattern, $replacement, $content); $response->setContent($content); return $response;
LaravelのMiddlewareを活用 $response = $next($request); $content = $response->getContent(); $pattern = '/<img
(\s|\w|[\^!"#$%&@\'()*+,.\/~;?:=\\-]|[^\x01-\x7E])+>/'; $replacement = '$0</amp-img>'; $content = preg_replace($pattern, $replacement, $content); $pattern = '/<img/'; $replacement = '<amp-img'; $content = preg_replace($pattern, $replacement, $content); $response->setContent($content); return $response; //レスポンス内容のHTMLを取得
LaravelのMiddlewareを活用 $response = $next($request); $content = $response->getContent(); $pattern = '/<img
(\s|\w|[\^!"#$%&@\'()*+,.\/~;?:=\\-]|[^\x01-\x7E])+>/'; $replacement = '$0</amp-img>'; $content = preg_replace($pattern, $replacement, $content); $pattern = '/<img/'; $replacement = '<amp-img'; $content = preg_replace($pattern, $replacement, $content); $response->setContent($content); return $response; <img src=”~”> => <img src”~”></amp-img>
LaravelのMiddlewareを活用 $response = $next($request); $content = $response->getContent(); $pattern = '/<img
(\s|\w|[\^!"#$%&@\'()*+,.\/~;?:=\\-]|[^\x01-\x7E])+>/'; $replacement = '$0</amp-img>'; $content = preg_replace($pattern, $replacement, $content); $pattern = '/<img/'; $replacement = '<amp-img'; $content = preg_replace($pattern, $replacement, $content); $response->setContent($content); return $response; <img src”~”></amp-img> => <amp-img src”~”></amp-img>
LaravelのMiddlewareを活用 $response = $next($request); $content = $response->getContent(); $pattern = '/<img
(\s|\w|[\^!"#$%&@\'()*+,.\/~;?:=\\-]|[^\x01-\x7E])+>/'; $replacement = '$0</amp-img>'; $content = preg_replace($pattern, $replacement, $content); $pattern = '/<img/'; $replacement = '<amp-img'; $content = preg_replace($pattern, $replacement, $content); $response->setContent($content); return $response; //変更したHTMLをレスポンスの内容としてセット
LaravelのMiddlewareを活用 imgタグの置き換え以外も
LaravelのMiddlewareを活用 //CSSのAMP対応 //AMPではCSSの!importantが使用できないので削除する $pattern = '/!important/'; $replacement = ''; $content
= preg_replace($pattern, $replacement, $content); //AMPではタグ内のstyle属性が使用できないので削除する $pattern = '/style="*(\s|\w|[\^!#$%&@\'()*+,.\/~;?:=\\-])*"/'; $replacement = ''; $content = preg_replace($pattern, $replacement, $content);
LaravelのMiddlewareを活用 非AMPページからAMP HTMLを自動生成するためには、 以下に対応しなければならない 1. AMPでは使用できない既存のタグの置き換え 2. imgタグで画像のheightとwidthを指定する必要がある LaravelのMiddlewareクラスを活用
画像サイズを動的に取得 AMPのamp-imgタグにはwidth・height属性が必須 AMP HTMLを自動生成するためには、 HTMLに散りばめられる画像サイズを動的に取得して width・height属性に値をセットする必要がある
画像サイズを動的に取得 画像サイズを動的に取得するために 1. MiddlewareでHTMLを取得する 2. DOMDocumentクラスを活用してDOMにパースする 3. src属性に記述されるパスを取得 4. getimagesize関数で画像サイズを取得
LaravelのMiddlewareを活用 $dom = new \DOMDocument(); @$dom->loadHTML($response->getContent()); $img_tag_list = $dom->getElementsByTagName("img"); foreach
($img_tag_list as $img_tag) { } //取得したレスポンスのHTMLをDOMにパース
LaravelのMiddlewareを活用 $dom = new \DOMDocument(); @$dom->loadHTML($response->getContent()); $img_tag_list = $dom->getElementsByTagName("img"); foreach
($img_tag_list as $img_tag) { } //imgタグを全て取得
LaravelのMiddlewareを活用 $dom = new \DOMDocument(); @$dom->loadHTML($response->getContent()); $img_tag_list = $dom->getElementsByTagName("img"); foreach
($img_tag_list as $img_tag) { } //imgタグにheight・width属性をセットする処理を記述する
LaravelのMiddlewareを活用 if ($img_tag->getAttribute('height') == "" && $img_tag->getAttribute('width') == "") {
$filepath = $img_tag->getAttribute('src'); if (strpos($filepath, '//') === 0) { //CDNの場合 $filepath = 'https:' . $filepath; } elseif (strpos($filepath, '/') === 0) { //ローカルの場合 $filepath = ltrim($filepath, '/'); } @list($width, $height) = getimagesize($filepath); if ($width != "" && $height != "") { $img_tag->setAttribute('width', $width); $img_tag->setAttribute('height', $height); $img_tag->setAttribute('layout', 'responsive'); } } //高さ・幅が指定されていない場合は、 //画像サイズを取得して設定する ※foreach文の処理
LaravelのMiddlewareを活用 if ($img_tag->getAttribute('height') == "" && $img_tag->getAttribute('width') == "") {
$filepath = $img_tag->getAttribute('src'); if (strpos($filepath, '//') === 0) { //CDNの場合 $filepath = 'https:' . $filepath; } elseif (strpos($filepath, '/') === 0) { //ローカルの場合 $filepath = ltrim($filepath, '/'); } @list($width, $height) = getimagesize($filepath); if ($width != "" && $height != "") { $img_tag->setAttribute('width', $width); $img_tag->setAttribute('height', $height); $img_tag->setAttribute('layout', 'responsive'); } } //画像のパスを取得 ※foreach文の処理
LaravelのMiddlewareを活用 if ($img_tag->getAttribute('height') == "" && $img_tag->getAttribute('width') == "") {
$filepath = $img_tag->getAttribute('src'); if (strpos($filepath, '//') === 0) { //CDNの場合 $filepath = 'https:' . $filepath; } elseif (strpos($filepath, '/') === 0) { //ローカルの場合 $filepath = ltrim($filepath, '/'); } @list($width, $height) = getimagesize($filepath); if ($width != "" && $height != "") { $img_tag->setAttribute('width', $width); $img_tag->setAttribute('height', $height); $img_tag->setAttribute('layout', 'responsive'); } } //画像のサイズをセットする ※foreach文の処理
まとめ 1. モバイル爆速化はAMP対応することで可能 2. ミドルウェアを用いてレスポンス内容を変更 3. 正規表現を用いてレスポンス内容を変化させる 4. DOMDocumentクラスを活用して画像サイズを動的に https://testmysite.withgoogle.com/intl/ja-jp
エンジニアブログやってます! http://tech.innovation.co.jp/