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.3k
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
React Nativeならぬ"Vue Native"が実現するかも?_新世代マルチプラットフォーム開発フレームワークのLynxとLynxのVue.js対応を追ってみよう_Vue Lynx
yut0naga1_fa
2
1.4k
alien-signals と自作 OSS で実現する フレームワーク非依存な ロジック共通化の探求 / Exploring Framework-Agnostic Logic Sharing with alien-signals and Custom OSS
aoseyuu
2
650
CSC509 Lecture 08
javiergs
PRO
0
250
CSC509 Lecture 07
javiergs
PRO
0
240
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
270
NIKKEI Tech Talk#38
cipepser
0
240
理論と実務のギャップを超える
eycjur
0
180
Android16 Migration Stories ~Building a Pattern for Android OS upgrades~
reoandroider
0
140
Server Side Kotlin Meetup vol.16: 内部動作を理解して ハイパフォーマンスなサーバサイド Kotlin アプリケーションを書こう
ternbusty
3
250
Google Opalで使える37のライブラリ
mickey_kubo
3
150
AIと人間の共創開発!OSSで試行錯誤した開発スタイル
mae616
2
810
登壇は dynamic! な営みである / speech is dynamic
da1chi
0
360
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
135
9.6k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
37
2.6k
BBQ
matthewcrist
89
9.9k
Balancing Empowerment & Direction
lara
5
700
Context Engineering - Making Every Token Count
addyosmani
8
300
Building Better People: How to give real-time feedback that sticks.
wjessup
369
20k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.5k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
30
2.9k
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
Agile that works and the tools we love
rasmusluckow
331
21k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
19k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
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