ServiceWorkerや各種APIの基本的なユースケースは周知されてきたPWAですが、それらを組み合わせて具体的にそんな実装パターンがあるかについては未だに不透明に感じられます。 今回はLaravel/Vue.jsでPWAのサンプルアプリを作った時の知見を元に、どんなことを考え、どんな実装パターンにしたかを語りました。
ౡܛ(.01FQBCP *ODୈճ1)1ษڧձ18"ͷαϯϓϧΞϓϦ࡞ͬͯΈͨ
View Slide
ΤϯδχΞౡܛ!OB[POPIJUP4)ࣄۀ෦+6(&.νʔϜIUUQOB[POPIJUPKVHFNKQ
TDIPP͞ΜͰ-BSBWFMͷतۀ࡞Γ·ͨ͠
࣍w18"ͱw18"͕ͨΒ͢ϝϦοτw18"ͷݱࡏwαϯϓϧΞϓϦͷσϞwαϯϓϧΞϓϦͷ࣮ύλʔϯ
ࠓ͢͜ͱɾ͞ͳ͍͜ͱw͢͜ͱw18"ͷ֓ཁwαϯϓϧΞϓϦΛ࡞ͬͨಘͨݟw͞ͳ͍͜ͱwϑϩϯτΤϯυٕज़
18"ͱ
18"ͱw1SPHSFTTJWF8FC"QQTͷུশw৽͍ٕ͠ज़ʹΑͬͯωΠςΟϒΞϓϦͷΑ͏ͳಈ࡞͕Մೳʹͳͬͨ8FCΞϓϦέʔγϣϯ
4UBU$PVOUFS %FTLUPQWT.PCJMFWT5BCMFU.BSLFU4IBSF8PSMEXJEFIUUQHTTUBUDPVOUFSDPNQMBUGPSNNBSLFUTIBSFEFTLUPQNPCJMFUBCMFUXPSMEXJEFNPOUIMZ
18"ͷੜ·ΕͨഎܠwϞόΠϧͷར༻࣌ؒͷׂωΠςΟϒΞϓϦʹΘΕ͍ͯΔ[email protected]/FXTSFMFBTFIUNM˞͜ͷൃදதͷఆٛ˞ϞόΠϧ8FCϞόΠϧͰϒϥβΛ௨ͨ͠8FCମݧ
ϞόΠϧ8FCʻωΠςΟϒΞϓϦwΦϑϥΠϯͰಈ࡞్͕ΕΔwಈ࡞͕ॏ͘ײ͡Δwϓογϡ௨Ͱ͖ͳ͍ʢαʔϏεఏڙଆࢹʣ
྆ऀͷൺֱϞόΠϧ8FC ωΠςΟϒΞϓϦΦϑϥΠϯಈ࡞ ෆՄ Մೳϓογϡ௨ ෆՄ Մೳىಈ·Ͱεςοϓ ଟ͍ʢϒοΫϚʔΫొͰ؇Ͱ͖Δʣ গͳ͍ʢϗʔϜը໘͔Βىಈʣ69 ѱ͍ʢKBWBTDSJQUͰ؇Ͱ͖Δʣ ྑ͍Πϯετʔϧ ෆཁ ඞਢݕࡧੑ ߴ͍ ͍։ൃίετ ͍ ߴ͍ϦϦʔείετ ͍ ߴ͍
྆ऀͷ͍͍ͱ͜औΓwΦϑϥΠϯಈ࡞wϓογϡ௨wΠϯετʔϧϨεwݕࡧɾϦϯΫՄೳԿ͔
྆ऀͷ͍͍ͱ͜औΓwϞόΠϧ8FCΛϕʔεʹɺ৽͍͠ςΫϊϩδʔΛ༻͍࣮ͯݱ͢Δ.PCJMF8FC /FX5FDIOPMPHZ18"
18"ͷॾٕज़w4FSWJDF8PSLFSw8FC"QQ.BOJGFTUw1BZNFOU3FRVFTU"1*w"VUPpMMw'FUDI"1*w$BDIF"1*w1VTI"1*w#BDLHSPVOE4ZOD"1*w(FPMPDBUJPO"1*w%FWJDF.PUJPO&WFOUw'VMMTDSFFO"1*w$SFEFOUJBM.BOBHFNFOU"1*
4FSWJDF8PSLFSͷओͳׂw)551ϦΫΤετͷΠϯλʔηϓτw)551Ϩεϙϯεͷίϯτϩʔϧwϓογϡ௨ͪड͚wόοΫάϥϯυಉظ
4FSWJDF8PSLFSᶃᶄ
4FSWJDF8PSLFSᶃ ᶄᶅᶆDMJFOUTJEF
4FSWJDF8PSLFSᶃᶄᶅ165DMJFOUTJEF
4FSWJDF8PSLFSᶃᶄᶅ(&5DMJFOUTJEF
4FSWJDF8PSLFS(&5DMJFOUTJEF+BWBTDSJQUͰ੍ޚ͢Δ
4FSWJDF8PSLFSᶃᶅ/FUXPSL'JSTUᶆ(&5ᶄᶃ ᶅ$BDIF'JSTUᶆ(&5ᶄ165ᶇᶈ
4FSWJDF8PSLFSᶄᶃϒϥβ͕ด͡ΒΕͯಈ͘
4FSWJDF8PSLFSᶃTZODSFHJTUFS
4FSWJDF8PSLFSᶃTZODFWFOUᶄᶅΦϯϥΠϯ෮ؼ࣌ʹൃੜ͢ΔΠϕϯτ
4FSWJDF8PSLFSͷಛwෆ҆ఆͳωοτϫʔΫڥΛٵऩ͢ΔϓϩΩγw௨ͷͪड͚Λߦ͏όοΫάϥϯυϓϩηεwΦϯϥΠϯ࣌ͷδϣϒΛ࣮ߦ͢ΔϫʔΧʔϓϩηε
8FC"QQ.BOJGFTUw8FCΞϓϦέʔγϣϯͷϗʔϜը໘ͷՃํ๏Λఆٛ͢ΔKTPOwΞϓϦέʔγϣϯىಈ࣌ͷΦϓγϣϯࢦఆͰ͖Δ
8FC"QQ.BOJGFTU{"short_name": "PWA TEST","name": "PWA TEST(Vue.js/OnsenUI)","icons": [{"src": "/images/launcher-icon-1x.png","type": "image/png","sizes": "128x128"},{"src": "/images/launcher-icon-2x.png","type": "image/png","sizes": "256x256"},{"src": "/images/launcher-icon-4x.png","type": "image/png","sizes": "512x512"}],"start_url": "/app","background_color": "#FFFFFF","theme_color": "#FFFFFF","display": "standalone"}ϗʔϜը໘ʹදࣔ͞ΕΔΞϓϦ໊ىಈ࣌ʹΞΫηε͢Δ63-ϗʔϜը໘ʹදࣔ͞ΕΔΞΠίϯϒϥβͷදࣔϞʔυ
8FC"QQ.BOJGFTU̍̎̏ϗʔϜը໘Ճϓϩϯϓτʢϒϥβϝχϡʔ͔ΒՄʣϗʔϜը໘ʹΞϓϦͷՃ
8FC"QQ.BOJGFTU̐ ̑ ̒ىಈ࣌ͷεϓϥογϡը໘ʢΧϥʔΞΠίϯࢦఆՄʣϒϥβϝχϡʔ͕ඇදࣔ
18"ͷಛwஈ֊తwϨεϙϯγϒwωοτϫʔΫଓʹґଘ͠ͳ͍wΞϓϦײ֮wৗʹ࠷৽ࢀߟIUUQTEFWFMPQFSTHPPHMFDPNXFCGVOEBNFOUBMTDPEFMBCTZPVSpSTUQXBQQ IMKBw҆શwൃݟ͍͢͠w࠶ΤϯήʔδϝϯτՄೳwΠϯετʔϧՄೳwϦϯΫՄೳ
ʮ18"ʯͱϚʔέςΟϯάϫʔυͳͷͰ͢ɻݫີͳఆٛಛʹ͋Γ·ͤΜɻ1SPHSFTTJWF8FC"QQT3PBETIPX5PLZP2"
·ͱΊw18"ͱ৽͍ٕ͠ज़ʹΑͬͯҰ࣍ݩ্ͷମݧΛఏڙ͢Δ8FCΞϓϦw8FCͱωΠςΟϒΞϓϦͷ྆໘ͷྑ͞Λ࣋ͪ߹Θ͍ͤͯΔ
18"ͷͨΒ͢ϝϦοτ
18"ͷͨΒ͢ϝϦοτw8FCͷٕज़Ͱ݁Ͱ͖ΔwҰͭͷίʔυͰ݁͢ΔwΞϓϦϚʔέοτʹറΒΕͳ͍wΞϓϦར༻։࢝·Ͱͷোน͕খ͘͞ͳΔ
8FCͷٕज़Ͱ݁͢ΔૉࡐIUUQXXXGSFFQJLDPN8FC%JSFDUPS8FC%FTJHOFS8FC&OHJOFFSJ04&OHJOFFS"OESPJE&OHJOFFS8FC%JSFDUPS8FC%FTJHOFS8FC&OHJOFFS
ҰͭͷίʔυͰ݁͢Δ
ΞϓϦϚʔέοτʹറΒΕͳ͍wϦϦʔε͕αʔϏεଆͰશʹίϯτϩʔϧͰ͖ΔwόʔδϣϯΞοϓςετʹର͔͚ͯ͠Δίετ͕গͳ͘ͳΔ
ΞϓϦར༻։࢝·Ͱͷোน͕খ͘͞ͳΔwΠϯετʔϧϨεwσʔλαΠζখ͘͞ͳΔ͕͋Δ
18"ͷݱࡏ
4FSWJDF8PSLFSͷ࣮ঢ়گIUUQTDBOJVTFDPNGFBUTFSWJDFXPSLFST
Կނɺࠓ18"ͳͷ͔ʁw8FCLJU͕ΑΓ4FSWJDF8PSLFSͷ࣮ʹணखͨ͠IUUQTXFCLJUPSHTUBUVT TFBSDITFSWJDFXPSLFSʢJ04ͷϒϥβ8FCLJUͰ࣮͠ͳ͚ΕͳΒͳ੍͍͕͋Δʣ
σϞ
ߏw-BSBWFMw7VFKTw0OTFO6*IUUQTTISPVEFEEVTLIFSPLVBQQDPN
"QQ4IFMMϞσϧ"QQMJDBUJPO4IFMM෦ʢ੩తίϯςϯπʣಈతίϯςϯπ18"Λߏங͢ΔΞʔΩςΫνϟɻ6*͕ػೳ͢Δ࠷ݶͷΞηοτʢ"QQMJDBUJPO4IFMMʣΛࣄલΩϟογϡ͢Δɻ
ϓογϡ௨ʹΑΔԾొϓογϡ௨ΛڐՄͯ͠Β͏͜ͱΛϢʔβԾొͱͯ͠ѻ͏ɻΞϓϦར༻։࢝·ͰͷεςοϓΛগͳ͘͢Δɻ
ϓογϡ௨ڐՄͷࣄલ֬ೝϓογϡ௨ڐՄͷϓϩϯϓτҰϒϩοΫ͞ΕΔͱೋͱදࣔ͞Εͳ͘ͳΔɻμϒϧύʔϛογϣϯύλʔϯͰΑΓ࣮֬ʹڐՄͯ͠Β͏ɻ͠Β͘࠶දࣔͰ͖ͳ͍ೋͱ࠶දࣔͰ͖ͳ͍ʂʂ
ొ͞Εͨϓογϡ௨ڐՄΛऔΓԼ͛ͨޙʹɺϓϩϯϓτΛ࠶දࣔͤͨ͘͞ͳ͍ɻ௨ͷ༗ແબͰ͖Δ͕ɺϒϥβͷ௨ڐՄͨ͠··ʹ͢Δ͜ͱͰଈ࣌ݩʹͤΔΑ͏ʹ͢Δɻϓογϡ௨ڐՄͷऔΓԼ͛"MMPX௨ڐՄͨ͠··
هࣄͷϓϦϑΣονλΠϜϥΠϯը໘ʹදࣔ͞ΕͨهࣄϓϦϑΣον͢Δ͜ͱͰɺهࣄৄࡉͷදࣔΛߴԽ͍ͯ͠ΔɻϓϦϑΣον͞Εͨهࣄใ4FSWJDF8PSLFSͷΩϟογϡʹͨ·ΔɻӬଓతʹ͢ඞཁͰͳ͍ͷͰఔͰFYQJSFͤ͞ΔɻGFUDIGFUDIGFUDIGFUDIGFUDI165
هࣄͷϓϦϑΣονදࣔ͞Ε͍ͯΔهࣄͷͷϦΫΤετΛ͛·͘ΔϦΫΤετͷॏෳؾʹ͠ͳ͍Ωϟογϡ͞Ε͍ͯͳ͍͔͠ωοτϫʔΫʹग़ͯߦ͔ͳ͍
هࣄͷϓϦϑΣονᶃᶄᶅωοτϫʔΫΑΓશવૣ͍͕ɺ͘͝Θ͔ͣʹ͕͔͔࣌ؒΔɾɾɾʢdNTʣ
هࣄͷϓϦϑΣον{4: {id: 4, title: 'title', body: 'body'},5: {id: 5, title: 'title', body: 'body'},6: {id: 6, title: 'title', body: 'body'}}ᶄᶃᶅ4FSWJDF8PSLFSͷΩϟογϡΛ͞Βʹ+4্Ͱอ࣋
ϓϦϑΣονPOϓογϡ௨wهࣄߘ͕ϓογϡ௨͞Εͨ߹ɺରͷهࣄΛϓϦϑΣονwϓογϡ௨͕λοϓ͞Εͨ࣌ʹରͷهࣄΛߴͰදࣔͰ͖Δᶄᶃᶅ165ᶆᶇ
όοΫάϥϯυಉظʮ͍͍ͶʯԆ͕ڐ͞ΕΔͷͰΦϑϥΠϯͰૹ৴Ͱ͖ͨΑ͏ͳදࣔΛߦ͏ɻૹ৴όοΫάϥϯυಉظͰΦϯϥΠϯ෮ؼ࣌ʹࣗಈͰߦΘΕΔɻΦϑϥΠϯͰද্ࣔૹ৴Ͱ͖͔ͨͷΑ͏ʹදࣔ͢Δ
Ξόλʔը૾ͷΩϟογϡઓུwΩϟογϡ͔Βฦ͕͢ɺಉ࣌ʹωοτϫʔΫ͔Βऔಘ͠ɺΩϟογϡΛߋ৽͢Δʢࠓճ$MPVEJOBSZΛ༻͍ͯ͠ΔͷͰҙຯ͕ແ͍ʜʣwৗʹ࠷৽ͷը૾͕දࣔ͞ΕΔΘ͚Ͱͳ͍͕ɺߋ৽ස͕͍ͨΊڐ͞ΕΔᶃ ᶄ`4UBMF8IJMF3FWBMJEBUFᶅ`(&5ᶄ165ᶆ`ᶅ
ᶇΞόλʔը૾ͷϑΥʔϧόοΫw4FSWJDF8PSLFSऔಘʹࣦഊͨ͠߹ͷϨεϙϯε੍ޚͰ͖ΔwϑΥʔϧόοΫϨεϙϯεͷ༰63-ผʹ͚Δ͜ͱͰ͖Δᶃ(&5ᶄ ᶆᶅϑΥʔϧόοΫ༻ը૾
4FSWJDF8PSLFSͷճආઃఆը໘ͷΞόλʔը૾͚ͩ࠷৽ͷͷ͕දࣔ͞Εͳ͍ͱߋ৽͕ଈ࣌ө͞Εͳ͍ɻΫΤϦύϥϝʔλʹΑͬͯ4FSWJDF8PSLFSͷΩϟογϡΛճආ͢Δɻ௨ৗϦΫΤετJNBHFTBWBUBSTVTFSOBNFQOH4FSWJDF8PSLFS௨աϦΫΤετJNBHFTBWBUBSTVTFSOBNFQOH TFMG
ߋ৽࣌ͷϦϩʔυཁٻ4FSWJDF8PSLFSͷߋ৽ଈ࣮࣌ߦ͞Εͣɺલͷόʔδϣϯͷ4FSWJDF8PSLFS͕ཧ͍ͯ͠Δશͯͷϒϥβλϒ͕ด͡ΒΕΔ·Ͱߋ৽͞Εͳ͍ɻʢྫ֎͋ΓʣϞʔμϧΛग़͢͜ͱͰϢʔβʹ࠶ىಈΛଅ͢ɻ
4FSWJDF8PSLFSͷߋ৽ᶃᶄᶅ(&5
4FSWJDF8PSLFSͷߋ৽ᶃᶄᶅ(&5"QQMJDBUJPO4IFMMͷΞηοτΛߋ৽ͯ͠ϩʔΧϧΩϟογϡ͕༻͞ΕΔίʔυʹมߋ͕ͳ͚Εɺ4FSWJDF8PSLFSߋ৽͞Εͳ͍
4FSWJDF8PSLFSͷߋ৽࣮ߦ݅ᶆᶄᶅ165ᶃ৽͍͠4FSWJDF8PSLFSͷΠϯετʔϧϓϩηεͰ৽͍͠Ξηοτ͕Ωϟογϡ͞ΕΔ
4FSWJDF8PSLFSͷߋ৽৽͍͠4FSWJDF8PSLFSͷΠϯετʔϧόοΫάϥϯυͰߦΘΕΔ
4FSWJDF8PSLFSͷߋ৽4FSWJDF8PSLFSͷަશͯͷϒϥβλϒ͕ด͡ΒΕͨ࣌
4FSWJDF8PSLFSͷߋ৽
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠࠷৽ͷ࠾༻ใΛνΣοΫˠ [email protected]