Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PWA+AMPの話
Search
Yui Sakamoto
June 10, 2017
Programming
25
23k
PWA+AMPの話
Progressive Web AppsとAMPのさらっとした話をしました。
Yui Sakamoto
June 10, 2017
Tweet
Share
More Decks by Yui Sakamoto
See All by Yui Sakamoto
TypeScript エンジニアが Android 開発の世界に飛び込んだ話
yuisakamoto
6
2.4k
Modular Monolith Monorepo ~シンプルさを保ちながらmonorepoのメリットを最大化する~
yuisakamoto
12
8.6k
Google I/O '18 Overview @わいわい報告会
yuisakamoto
3
4.4k
Google I/O 2017 注目のmobile Web技術
yuisakamoto
7
6.1k
アプリファーストの影で頑張るWebの話
yuisakamoto
8
6.5k
Other Decks in Programming
See All in Programming
contribution to astral-sh/uv
shunsock
0
560
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
610
コードとあなたと私の距離 / The Distance Between Code, You, and I
hiro_y
0
210
AI 駆動開発におけるコミュニティと AWS CDK の価値
konokenj
5
290
Node-REDのノードの開発・活用事例とコミュニティとの関わり(Node-RED Con Nagoya 2025)
404background
0
110
O Que É e Como Funciona o PHP-FPM?
marcelgsantos
0
230
Temporal Knowledge Graphで作る! 時間変化するナレッジを扱うAI Agentの世界
po3rin
5
1k
CSC509 Lecture 08
javiergs
PRO
0
270
kiroとCodexで最高のSpec駆動開発を!!数時間で web3ネイティブなミニゲームを作ってみたよ!
mashharuki
0
990
Swift Concurrency 年表クイズ
omochi
3
170
あなたとKaigi on Rails / Kaigi on Rails + You
shimoju
0
220
他言語経験者が Golangci-lint を最初のコーディングメンターにした話 / How Golangci-lint Became My First Coding Mentor: A Story from a Polyglot Programmer
uma31
0
480
Featured
See All Featured
Side Projects
sachag
455
43k
How to Think Like a Performance Engineer
csswizardry
27
2.2k
Optimising Largest Contentful Paint
csswizardry
37
3.5k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.5k
Being A Developer After 40
akosma
91
590k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Designing for humans not robots
tammielis
254
26k
Rails Girls Zürich Keynote
gr2m
95
14k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.2k
Speed Design
sergeychernyshev
32
1.2k
Designing for Performance
lara
610
69k
Transcript
Progressive Web Apps + AMP = PWAMP (for PHPer) @yui_tang
PHPΧϯϑΝϨϯεԬɹ 2017.06.10
• ࡔຊ ݁ҥ(@yui_tang) • Software Engineer • Mercari, inc. •
ೖࣾ3 • αʔόʔαΠυɺϑϩϯτΤϯυɺϓϩδΣΫτ Φʔφʔʑ • ༷ʑͳϓϩδΣΫτʹؔΘΓͳ͕ΒɺೖࣾҎདྷ WebΛ୲͍ͯ͠Δ About Me
PHPΧϯϑΝϨϯεԬ2017 ͰPHPʹ৮Εͳ͍Λ͢Δ
ग़ͯ͘Δαϯϓϧίʔυ ຊ൪Ͱ͑·ͤΜ
Contents • ԿނWebʁ • AMPʢAccelerated Mobile Pagesʣͱ • PWAʢProgressive Web
Appsʣͱ • PWA ʴ AMP • ૯ׅ
ࠓͷΰʔϧ ͜ΕΒͷٕज़ʹ৮Εͨ͜ͱͷͳ͍ ਓୡʹڵຯΛ࣋ͬͯΒ͑Δ
ԿނΞϓϦͰͳ͘ WebͷΛ͢Δͷʁ
ԿނWebʁ
ԿނWebʁ • ճઢڥͷѱ͍ࠃʑͰɺΞϓϦΛμϯϩʔ υ͢Δ͜ͱͷ߅ײ͕ະͩڧ͍ • ࠃͰʁ • ݄ʹ੍ݶֻ͕͔ΔϢʔβʔ • ి͕ແ͍ঢ়گͰɺͦΕΛײͣ͡ʹಈ͘Ξϓ
Ϧ͔ΓͰແ͍
Twitter litePWA IUUQTCMPHUXJUUFSDPNP⒏DJBMKB@KQUPQJDTQSPEVDUUXJUUFSMJUF@IUNM
Twitter lite • Android App 23MB+ • iOS App 100MB+
• PWA 0.6MB
ԿނWebʁ • ΞϓϦ͕ྑ͍ / ѱ͍ͷͰͳ͍ • WebϒϥβͰදݱग़དྷΔ͜ͱ͕૿͍͑ͯΔ • Ϣʔβʔ͕બΔબࢶ͕૿͑Δ •
ݶΒΕͨϦιʔεͷதͰɺWebʹྗ͢Δ͜ ͱͰେ͖ͳϝϦοτ͕͋ΔͳΒΦεεϝ
AMP Accelerated Mobile Pages
About AMP • AMPͱʁ • Pros ⤴ / Cons ⤵
• ࣮ํ๏ • ରԠϒϥβ • ͲΜͳαΠτʹ༗ޮʁ
About AMP • AMPͱʁ • Pros ⤴ / Cons ⤵
• ࣮ํ๏ • ରԠϒϥβ • ͲΜͳαΠτʹ༗ޮʁ • ϦονͰ͍ ✖ γϯϓϧͰૣ͍=>৽ఏҊ • htmlʹࣅֶ͍ͯͯशίετ͕͍ • ؆୯ͳهड़ͰDLɾϨϯμϦϯά͕ૣ͍ • ௨ৗͷhtmlͱൺͯग़དྷͳ͍͜ͱ͕͋Δ
"DDFMFSBUFE.PCJMF1BHFT1SPKFDU".1 IUUQTXXXBNQQSPKFDUPSH
"DDFMFSBUFE.PCJMF1BHFT1SPKFDU".1 IUUQTXXXBNQQSPKFDUPSH ".1$POGߦ͖ͬͯ·ͨ͠".1$POG IUUQUFDINFSDBSJDPNFOUSZ
AMPͱʁ • Google / Twitter͕த৺ͱͳͬͯ࢝·ͬͨOSS • ύϒϦογϟͱίϯςϯπϗϧμ͕͍Δ • ੍ݶͷ͋ΔHTML5Ͱ࣮͢Δ •
PublisherଆͰΩϟογϡΛ͢Δ͜ͱͰߴԽ • ϖʔδίϯςϯπ࣍ୈͰGoogleݕࡧͷ݁ՌͰԸܙΛड ͚ΒΕΔ
AMPͱʁ • AMP͚ͩͲɺผʹMobileઐ༻Ͱͳ͍ • Mobileઐ༻Ͱͳ͍͠ɺϨεϙϯγϒରԠ Մೳ
AMP Pros / Cons
AMP Pros / Cons • ࣮͕؆୯ ֮͑Δ͜ͱ͕গͳ͍ • ग़དྷΔίτ͕υϯυϯ૿͍͑ͯΔ ⤴
• αʔόʔαΠυݴޠͱવΈ߹ΘͤΒΕΔ • વૣ͍ • Googleݕࡧ݁ՌͰ༏۰͞ΕΔ߹
AMP Pros / Cons • “ग़དྷແ͍ίτ” Λཧղ͢Δඞཁ͕͋Δ • طଘϖʔδͱͷ2ॏཧͷ߹ͷཧίετ •
…͜ͷ͘Β͍͔ʁ
AMP ࣮ํ๏
AMP ࣮ํ๏ (minimum) <!DOCTYPE html> <html ⚡ lang=“en"> <head> <meta
charset=“UTF-8"> <meta name="viewport" content=“width=device-width,minimum- scale=1,initial-scale=1"> <script async src=“https://cdn.ampproject.org/v0.js”></ script> <style amp-boilerplate> <!— தུ —!></style></noscript> <link rel="canonical" href=“/"> <title>AMP Test</title> </head> <body> Hello. </body> </html>
AMP ࣮ํ๏ • AMPʹඞཁͳίϯϙʔωϯτಡΈࠐΈ༻ͷJSҎ֎༻ ग़དྷͳ͍ • JSͰ͍ͬͯͨίτΛAMPͰஔ͖͑ΒΕΔ͔ʁ • ֎෦CSSಡΈࠐΉίτ͕ग़དྷͳ͍ •
λάͷstyleཁૉ or <style>ʹهड़ • PHPͰɺtemplateͰςΩετϑΝΠϧ͕ಡΈࠐ Ί·͢ΑͶ • 50KBͷ੍ݶ
AMP ࣮ํ๏ • ༻ग़དྷͳ͍htmlλάସͷAMPίϯϙʔ ωϯτ͕͋Δλά͕ଘࡏ • × frame • img
-> amp-img • form -> amp-form • and more IUUQTXXXBNQQSPKFDUPSHEPDTSFGFSFODFDPNQPOFOUT
AMP ࣮ํ๏ • amp-form, amp-bindʹΑͬͯɺECαΠτ AMPԽ͕ग़དྷΔΑ͏ʹͳͬͨ!! • ߏԽσʔλΛՃ͢Δ ▶ Optional
• URLඌʹ “#development=1” • dev toolͷconsoleʹ݁Ռදࣔ IUUQTXXXBNQQSPKFDUPSHEPDTSFGFSFODFDPNQPOFOUT
AMP ࣮ํ๏ • AMP Start • AMP Official
AMP ରԠϒϥβɹ • ػೳΛ੍ݶͨ͠HTML5ͳ͚ͩ • ϞμϯϒϥβͳΒجຊతʹಈ͘ • amp-◦◦ʹΑͬͯڍಈ͕ҧ͏߹͋Δ
AMP ͲΜͳαΠτʹ༗ޮ • ϒϩά • χϡʔεαΠτ • ϨγϐαΠτ • E-Commerce
• ؆୯ͳίʔϙϨʔταΠτ
AMPʹ͍ͭͯ࠷ߴʹৄ͍͠هࣄ • “ελϯυΞϩϯAMPͷεεϝ” • http://tech.mercari.com/entry/ recommending-standalone-amp
PWA Progressive Web Apps
About PWA • PWA Overview • Prosɹ/ɹCons • ࣮ํ๏ •
֤छπʔϧ • ରԠϒϥβ
https://developers.google.com/web/progressive-web-apps/
PWA Overview • Reliable / Fast / Engage • ৴པੑ:
ॠ࣌ʹϩʔυ͠ɺෆ࣮֬ͳωοτ ϫʔΫͰ404Λग़ͣ͞ʹϖʔδΛදࣔ • ͞: ϢʔβʔͱͷΓͱΓʹਝʹରԠ • Τϯήʔδ: ΞϓϦͷΑ͏ͳମݧΛಧ͚Δ
PWA Overview • WebϖʔδͰAppͷΑ͏ͳUXΛ࣮ݱ͢Δ • ϗʔϜը໘ʹΞΠίϯΛՃͰ͖Δ • Native AppͷΑ͏ͳfull screen
UI • ϒϥβ Push Notification • Service WorkerʹΑΔߴԽΦϑϥΠϯΩϟογϡ
PWA Pros / Cons
PWA Pros / Cons • ஈ֊తʹಋೖग़དྷΔ • PWAͱҰͭͷܗ͚ͩΛࢦ͢༁Ͱແ͍ • ࠓطʹಈ͍͍ͯΔΞϓϦέʔγϣϯͰঃʑʹ
ରԠͰ͖Δ • HTTPSԽͷνϟϯε
PWA Pros / Cons • ίϯςϯπͷCache Controll • SafariඇରԠ •
େنαΠτʹશରԠ͢ΔʹͦΕͳΓͷ ֻ͕͔Δ
PWA ࣮ʹඞཁͳཁૉ • manifest.json • Add to home screen •
Full Screen like native apps • Service Worker • and more
PWA ࣮ʹඞཁͳཁૉ • manifest.json • Add to home screen •
Full Screen like native apps • Service Worker • and more
Service Worker
Service WorkerʢSWʣ • ௨ৗͷϖʔδͰಈ͘JSͱҧ͍ɺϒϥβͰྑ͠ͳ ʹىಈ/ఀࢭ͢ΔJS Workerʢ͔ͩΒΠϯετʔϧ͢ Δʣ • Service Workerࣗମ͕Ӭଓతͳσʔλอ࣋Ͱ͖ͳ͍
• IndexedDBΛ͏ • DOMૢ࡞ग़དྷͳ͍
Service WorkerʢSWʣ • ҎԼͷ༷ʹSWΛొ͢Δ͜ͱͰɺରείʔ ϓҎԼͰಈ࡞͠ଓ͚Δ navigator.serviceWorker.register(‘./sw.js’, {scope: './'}).then(function(registration) { console.log(‘SW
registered with scope: ‘, registration.scope); }); ɹɹɹɹɹɹ • ొޙɺΠϕϯτۦಈͰಈ࡞͢Δʢinstall, activate, fetch֤छΠϕϯτʹରԠʣɹ
Service WorkerʢSWʣ • SWϓϩάϥϚϒϧͳϓϩΩγͰ͋Δ • ϖʔδ͔ΒͷϦΫΤετΛΠϯλʔηϓτ ͠ίϯτϩʔϧ͢Δ • ֎͔Βͷ௨Λྑ͠ͳʹૢ࡞ͯ͠ϖʔδʹϨ εϙϯεͱͯ͠ฦ͢
Service WorkerʢSWʣ ϒϥβ͔ΒͷϦΫΤετΛfetchΠϕϯτͰड͚ͯɺSW͔ΒϨεϙϯεΛฦ͢ self.addEventListener('fetch', function(event) { console.log(event.request.url); event.respondWith(new Response('Hello, world!
from SW')); }); SW͕ड͚ͨϦΫΤετΛͦͷ··fetch APIͰSW͕ϦΫΤετΛ͛ͯฦ͢ self.addEventListener('fetch', function(event) { event.respondWith(fetch(event.request)); });
Service WorkerʢSWʣ const dataCacheName = ‘v1'; const cacheName = ‘v1';
const filesToCache = [ ‘/index.html', ‘/images/logo.png' ]; self.addEventListener('install', function(e) { console.log('[ServiceWorker] Install’); e.waitUntil( caches.open(cacheName).then(function(cache) { console.log('[ServiceWorker] Caching app shell’); return cache.addAll(filesToCache); }) ); }); self.addEventListener('activate', function(e) { console.log('[ServiceWorker] Activate’); e.waitUntil( caches.keys().then(function(keyList) { return Promise.all(keyList.map(function(key) { if (key !== cacheName && key !== dataCacheName) { console.log('[ServiceWorker] Removing old cache', key); return caches.delete(key); } })); }) ); return self.clients.claim(); }); self.addEventListener('fetch', function(e) {ɹ ɹɹɹ console.log('[Service Worker] Fetch’, ɹɹɹɹ e.request.url); ɹɹɹ const dataUrl = 'https://example.com/data/v1'; if (e.request.url.indexOf(dataUrl) > -1) {ɹɹɹɹ e.respondWith(ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ caches.open(dataCacheName).then(function(cache) { return fetch(e.request).then(function(response){ cache.put(e.request.url, response.clone()); return response; });ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ ɹɹ }) ); } else { e.respondWith( caches.match(e.request).then(function(response) { return response || fetch(e.request); })ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ ); } });
Service Worker #SPXTFS 4FSWFS 48 TXKT navigator.serviceWorker.register(‘./sw.js’); JOTUBMM BDUJWBUF XBJUJOH
Service Worker (install࣌) #SPXTFS 4FSWFS 48 TXKT navigator.serviceWorker.register(‘./sw.js’); JOTUBMM BDUJWBUF
XBJUJOH
Service Worker (installޙ) #SPXTFS 4FSWFS 48 TXKT navigator.serviceWorker.register(‘./sw.js’); JOTUBMM BDUJWBUF
XBJUJOH
Service Worker #SPXTFS 4FSWFS 48 fetchΠϕϯτ fetch event.respondWith()
Service Worker
App Shell
App ShellϞσϧ
App ShellϞσϧ • ࠷ݶͷhtml, css, jsΛΦϑϥΠϯͰඳըͰ͖ ΔΑ͏ʹΩϟογϡΛ͢Δ • ಈతίϯςϯπΩϟογϡΛར༻͠ͳ͕Β ࠷৽ͷใΛฦ͢
• ·ΔͰωΠςΟϒΞϓϦ
Twitter liteͷ࣮ࡍͷಈ͖ • ͜Ε·Ͱͷઆ໌ʢҎ্ͷ͜ ͱʣΛҰ௨Γߦ͍ɺΞϓϦ ͱશ͘Ḯ৭ͳ͍ಈ࡞Λମݧ ͢Δ͜ͱ͕Ͱ͖Δɻ
PWA ϥΠϒϥϦ / πʔϧ • Workbox • sw-precacheʹมΘΔSW༻ϥΠϒϥϦ • Lighthouse
• PWAύϑΥʔϚϯεɺΞΫηγϏϦ ςΟΛԽ
8PSLCPY IUUQTXPSLCPYKTPSH
8PSLCPY IUUQTXPSLCPYKTPSH
-JHIUIPVTF IUUQTEFWFMPQFSTHPPHMFDPNXFCUPPMTMJHIUIPVTF
• Chrome • Firefox • Edge • Opera PWA ରԠϒϥβ
PWA ඇରԠϒϥβ • Safari
PWA + AMP
PWAͱAMPΛ Έ߹ΘͤΔϝϦοτ • PWASWΠϯετʔϧޙ͕ૣ͍ • AMPϦονͳίϯςϯπͰ͖ͳ͍͕ɺ࠷ ॳ͔Βૣ͍ • AMPϖʔδͰSW͕Πϯετʔϧग़དྷͨΒʁ
amp-install-servieworker <script async custom-element="amp-install-serviceworker" src=“https://cdn.ampproject.org/v0/amp-install- serviceworker-0.1.js"></script> <!— தུ —!> <amp-install-serviceworker
src=“https://www.your-domain.com/ serviceworker.js" data-iframe-src=“https://www.your-domain.com/ install-serviceworker.html" layout="nodisplay"> </amp-install-serviceworker>
AMP as PWA AMP to PWA AMP in PWA
AMPͰߏங͞ΕͨϖʔδͰɺ PWAͷػೳΛར༻͢Δɻ AMP as PWA
AMP to PWA
AMP to PWA AMP to PWA
AMP to PWA AMP to PWA
૯ׅ
૯ׅ • ϢʔβʔʹαʔϏεʹϝϦοτͷ͋ΔAMP + PWA • Native App͔Web App͔ɺͲͪΒ͕͍қ͍͔ΛબͿͷ Ϣʔβʔ
• ͚ͲɺWebαʔϏεϝΠϯͷ߹ରԠͷՁ͕େ͍ʹ͋Δ • WebΛ࡞͍ͬͯΔօ͞ΜʹೃછΈқ͍ͣ • AppleWebͷਐԽΛࢭΊଓ͚Δͷ͔…
We’re hiring!! IUUQTXXXXBOUFEMZDPNDPNQBOJFTNFSDBSJBQQDPN