Progressive Web AppsとAMPのさらっとした話をしました。
Progressive Web Apps+AMP= PWAMP (for PHPer)@yui_tangPHPΧϯϑΝϨϯεԬɹ2017.06.10
View Slide
• ࡔຊ ݁ҥ(@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 litePWAIUUQTCMPHUXJUUFSDPNP⒏DJBMKB@KQUPQJDTQSPEVDUUXJUUFSMJUF@IUNM
Twitter lite• Android App 23MB+• iOS App 100MB+• PWA 0.6MB
ԿނWebʁ• ΞϓϦ͕ྑ͍ / ѱ͍ͷͰͳ͍• WebϒϥβͰදݱग़དྷΔ͜ͱ͕૿͍͑ͯΔ• Ϣʔβʔ͕બΔબࢶ͕૿͑Δ• ݶΒΕͨϦιʔεͷதͰɺWebʹྗ͢Δ͜ͱͰେ͖ͳϝϦοτ͕͋ΔͳΒΦεεϝ
AMPAccelerated Mobile Pages
About AMP• AMPͱʁ• Pros ⤴ / Cons ⤵• ࣮ํ๏• ରԠϒϥβ• ͲΜͳαΠτʹ༗ޮʁ
About AMP• AMPͱʁ• Pros ⤴ / Cons ⤵• ࣮ํ๏• ରԠϒϥβ• ͲΜͳαΠτʹ༗ޮʁ• ϦονͰ͍ ✖ γϯϓϧͰૣ͍=>৽ఏҊ• htmlʹࣅֶ͍ͯͯशίετ͕͍• ؆୯ͳهड़ͰDLɾϨϯμϦϯά͕ૣ͍• ௨ৗͷhtmlͱൺͯग़དྷͳ͍͜ͱ͕͋Δ
"DDFMFSBUFE.PCJMF1BHFT1SPKFDU".1IUUQTXXXBNQQSPKFDUPSH
"DDFMFSBUFE.PCJMF1BHFT1SPKFDU".1IUUQTXXXBNQQSPKFDUPSH".1$POGߦ͖ͬͯ·ͨ͠".1$POGIUUQUFDINFSDBSJDPNFOUSZ
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)scale=1,initial-scale=1"><br/>script><br/><style amp-boilerplate> <!— தུ —!></style></noscript><br/><link rel="canonical" href=“/"><br/><title>AMP Test</title><br/></head><br/><body><br/>Hello.<br/></body><br/></html><br/>
AMP ࣮ํ๏• AMPʹඞཁͳίϯϙʔωϯτಡΈࠐΈ༻ͷJSҎ֎༻ग़དྷͳ͍• JSͰ͍ͬͯͨίτΛAMPͰஔ͖͑ΒΕΔ͔ʁ• ֎෦CSSಡΈࠐΉίτ͕ग़དྷͳ͍• λάͷstyleཁૉ or ʹهड़<br/>• PHPͰɺtemplateͰςΩετϑΝΠϧ͕ಡΈࠐ<br/>Ί·͢ΑͶ <br/>• 50KBͷ੍ݶ<br/>
AMP ࣮ํ๏• ༻ग़དྷͳ͍htmlλάସͷAMPίϯϙʔωϯτ͕͋Δλά͕ଘࡏ• × frame• img -> amp-img• form -> amp-form• and moreIUUQTXXXBNQQSPKFDUPSHEPDTSFGFSFODFDPNQPOFOUT
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
PWAProgressive 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
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 oldcache', 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 4FSWFS48TXKTnavigator.serviceWorker.register(‘./sw.js’);JOTUBMMBDUJWBUFXBJUJOH
Service Worker (install࣌)#SPXTFS 4FSWFS48TXKTnavigator.serviceWorker.register(‘./sw.js’);JOTUBMMBDUJWBUFXBJUJOH
Service Worker (installޙ)#SPXTFS 4FSWFS48TXKTnavigator.serviceWorker.register(‘./sw.js’);JOTUBMMBDUJWBUFXBJUJOH
Service Worker#SPXTFS 4FSWFS48fetchΠϕϯτ fetchevent.respondWith()
App Shell
App ShellϞσϧ
App ShellϞσϧ• ࠷ݶͷhtml, css, jsΛΦϑϥΠϯͰඳըͰ͖ΔΑ͏ʹΩϟογϡΛ͢Δ• ಈతίϯςϯπΩϟογϡΛར༻͠ͳ͕Β࠷৽ͷใΛฦ͢• ·ΔͰωΠςΟϒΞϓϦ
Twitter liteͷ࣮ࡍͷಈ͖• ͜Ε·Ͱͷઆ໌ʢҎ্ͷ͜ͱʣΛҰ௨Γߦ͍ɺΞϓϦͱશ͘Ḯ৭ͳ͍ಈ࡞Λମݧ͢Δ͜ͱ͕Ͱ͖Δɻ
PWA ϥΠϒϥϦ / πʔϧ• Workbox• sw-precacheʹมΘΔSW༻ϥΠϒϥϦ• Lighthouse• PWAύϑΥʔϚϯεɺΞΫηγϏϦςΟΛԽ
8PSLCPYIUUQTXPSLCPYKTPSH
-JHIUIPVTFIUUQTEFWFMPQFSTHPPHMFDPNXFCUPPMTMJHIUIPVTF
• Chrome• Firefox• Edge• OperaPWA ରԠϒϥβ PWA ඇରԠϒϥβ• Safari
PWA + AMP
PWAͱAMPΛΈ߹ΘͤΔϝϦοτ• PWASWΠϯετʔϧޙ͕ૣ͍• AMPϦονͳίϯςϯπͰ͖ͳ͍͕ɺ࠷ॳ͔Βૣ͍• AMPϖʔδͰSW͕Πϯετʔϧग़དྷͨΒʁ
amp-install-servieworkersrc=“https://cdn.ampproject.org/v0/amp-install-serviceworker-0.1.js">serviceworker.js" data-iframe-src=“https://www.your-domain.com/install-serviceworker.html" layout="nodisplay">
AMP as PWAAMP to PWAAMP in PWA
AMPͰߏங͞ΕͨϖʔδͰɺPWAͷػೳΛར༻͢ΔɻAMP as PWA
AMP to PWA
AMP to PWAAMP to PWA
૯ׅ
૯ׅ• ϢʔβʔʹαʔϏεʹϝϦοτͷ͋ΔAMP + PWA• Native App͔Web App͔ɺͲͪΒ͕͍қ͍͔ΛબͿͷϢʔβʔ• ͚ͲɺWebαʔϏεϝΠϯͷ߹ରԠͷՁ͕େ͍ʹ͋Δ• WebΛ࡞͍ͬͯΔօ͞ΜʹೃછΈқ͍ͣ• AppleWebͷਐԽΛࢭΊଓ͚Δͷ͔…
We’re hiring!!IUUQTXXXXBOUFEMZDPNDPNQBOJFTNFSDBSJBQQDPN