Upgrade to Pro — share decks privately, control downloads, hide ads and more …

日経電子版へのPWA導入事例

7d6e26a4f1a9b5a866337f09178b0c9c?s=47 Ryo yasuda
October 31, 2018

 日経電子版へのPWA導入事例

7d6e26a4f1a9b5a866337f09178b0c9c?s=128

Ryo yasuda

October 31, 2018
Tweet

Transcript

  1. ೔ܦిࢠ൛΁ͷPWAಋೖࣄྫ ೔ຊܦࡁ৽ฉࣾ ҆ా ཽ "84%FW%BZ 

  2. ࣗݾ঺հ ҆ా ཽ (΍ͩ͢ Γΐ͏) 2015೥: NTTݚڀॴ ೖࣾ - ίϯςφܕԾ૝Խٕज़ؔ࿈ͷݚڀʹैࣄ

    2016೥: ೔ຊܦࡁ৽ฉࣾ ೖࣾ - ೔ܦిࢠ൛ϦχϡʔΞϧ൛ ։ൃϝϯόʔ - ϑϩϯτΤϯυɾόοΫΤϯυɾΠϯϑϥ౳ॾʑ୲౰ Α͘ॻ͘ݴޠ: js, golang, python
  3. ೔ܦిࢠ൛ 2010೥3݄૑ץ ຖ೔໿900ຊͷهࣄΛ഑৴ ༗ྉձһ54ສਓҎ্ɾແྉձһ300ສਓҎ্ ݄ؒ3ԯΞΫηε

  4. ೔ܦిࢠ൛ ϦχϡʔΞϧ ϓϩδΣΫτ (r.nikkei) SPAഇࢭ UI/UXվળ (PWAԽɾϨεϙϯγϒԽ) MicroservicesΞʔΩςΫνϟͷ࠾༻

  5. ϦχϡʔΞϧʹΑΔޮՌ Before After

  6. ϦχϡʔΞϧʹΑΔޮՌ •58% better conversion rate •40% more daily active user

    •2x faster Speed Index •14 seconds faster Time-To-Interactive •2.3x organic traffic
  7. PWA(Progressive Web Application)ͱ͸ ωΠςΟϒΞϓϦΆ͍UXΛఏڙ͢ΔWebΞϓϦ

  8. PWAͱ͸ – GoogleʹΑΔఆٛ • Fast • ϖʔδͷϩʔυ଎౓ɾԠ౴଎౓͕଎͍ • Reliable •

    ωοτϫʔΫঢ়گʹґଘ͠ͳ͍(ΦϑϥΠϯͰ΋ར༻Մೳ) • Engaging • ϓογϡ௨஌ • ϗʔϜը໘΁ͷ௥Ճ https://developers.google.com/web/progressive-web-apps/checklist
  9. ೔ܦʹ͓͚ΔPWA • Fast • ϦχϡʔΞϧલͷ਺ഒͷදࣔ଎౓ • Reliable • τοϓͷهࣄͳͲ͸ΦϑϥΠϯͰӾཡՄ •

    Engaging • ϓογϡ௨஌ • ϗʔϜը໘΁ͷ௥Ճ
  10. Fast

  11. ϑΝʔετϏϡʔදࣔ଎౓ͷ࠷దԽ • ϑΝʔετϏϡʔ • WebϖʔδΛ։͍ͨ࣌࠷ॳʹݟ͑ΔྖҬ • ͜ͷྖҬͷදࣔʹؔΘΔॲཧΛ࠷༏ઌ

  12. ϑΝʔετϏϡʔදࣔ଎౓ͷ࠷దԽ – PRPLύλʔϯ • Push: ϑΝʔετϏϡʔͷඳըʹඞཁͳϦιʔεΛPush • Render: ϑΝʔετϏϡʔΛඳը •

    Pre-cache: ࣍ʹඞཁͳϦιʔε΍ϖʔδΛPre-cache • Lazyload: ϑΝʔετϏϡʔ֎ͷίϯςϯπΛLazyload *Googleͷఏএ͢ΔSPAΛલఏͱͨ͠PRPLύλʔϯͱ͸ҟͳΔ΋ͷͷࢀߟʹ͍ͯ͠Δ
  13. ϑΝʔετϏϡʔදࣔ଎౓ͷ࠷దԽ – PRPLύλʔϯ • Push: ϑΝʔετϏϡʔͷඳըʹඞཁͳϦιʔεΛPush • Render: ϑΝʔετϏϡʔΛඳը •

    Pre-cache: ࣍ʹඞཁͳϦιʔε΍ϖʔδΛPre-cache • Lazyload: ϑΝʔετϏϡʔ֎ͷίϯςϯπΛLazyload *Googleͷఏএ͢ΔSPAΛલఏͱͨ͠PRPLύλʔϯͱ͸ҟͳΔ΋ͷͷࢀߟʹ͍ͯ͠Δ
  14. HTTP/2 Server Push ΫϥΠΞϯτ͔ΒͷϦΫΤετແ͠ʹαʔό͔Βσʔλૹ৴ ΫϥΠΞϯτ αʔό ΫϥΠΞϯτ αʔό index.html bundle.js

    bundle.css index.html index.html bundle.js bundle.css Pushແ͠ Push༗Γ
  15. HTTP/2 Server Push Pushແ͠ Push༗Γ ϖʔδͷμ΢ϯϩʔυޙʹjsɾcssΛμ΢ϯϩʔυ ϖʔδͷμ΢ϯϩʔυͱฒߦͯ͠jsɾcssΛμ΢ϯϩʔυ

  16. • HTTP/2 Server H2OΛར༻ • Link HeaderʹϦιʔεΛهड़͢ΔͱPushͯ͘͠ΕΔ HTTP/2 Server Push

    Origin Server H2O Client Link:<bundle.js>;rel=preload;, <bundle.css>; rel=preload; Push: bundle.css Push: bundle.js
  17. • Fastly(CDN)͕LinkϔομΛ࢖ͬͨPushΛαϙʔτ • r.nikkeiͰ͸Fastly࢖ͬͯͨͷͰPushͷಋೖͷखؒ͸খ͍͞ HTTP/2 Server Push Origin Server Fastly

    (CDN) Client Link:<bundle.js>;rel=preload;, <bundle. css>; rel=preload; Push: bundle.css Push: bundle.js
  18. ϑΝʔετϏϡʔදࣔ଎౓ͷ࠷దԽ – PRPLύλʔϯ • Push: ϑΝʔετϏϡʔͷඳըʹඞཁͳϦιʔεΛPush • Render: ϑΝʔετϏϡʔΛඳը •

    Pre-cache: ࣍ʹඞཁͳϦιʔε΍ϖʔδΛPre-cache • Lazyload: ϑΝʔετϏϡʔ֎ͷίϯςϯπΛLazyload *Googleͷఏএ͢ΔSPAΛલఏͱͨ͠PRPLύλʔϯͱ͸ҟͳΔ΋ͷͷࢀߟʹ͍ͯ͠Δ
  19. Render – Critical Rendering Pathͷ࠷దԽ Request Page Start building DOM

    Build CSSOM Run JS Continue Building DOM Render Page GET html Response Response Response GET css GET js
  20. Render – Critical Rendering Pathͷ࠷దԽ Request Page GET html

  21. Render – Critical Rendering Pathͷ࠷దԽ Request Page Start building DOM

    GET html Response
  22. Render – Critical Rendering Pathͷ࠷దԽ Request Page Start building DOM

    GET html Response GET css GET js
  23. Render – Critical Rendering Pathͷ࠷దԽ Request Page Start building DOM

    Build CSSOM Run JS GET html Response Response Response GET css GET js
  24. Render – Critical Rendering Pathͷ࠷దԽ Request Page Start building DOM

    Build CSSOM Run JS Continue Building DOM GET html Response Response Response GET css GET js
  25. Render – Critical Rendering Pathͷ࠷దԽ Request Page Start building DOM

    Build CSSOM Run JS Continue Building DOM Render Page GET html Response Response Response GET css GET js
  26. Render – Critical Rendering Pathͷ࠷దԽ Request Page Start building DOM

    Build CSSOM Run JS Continue Building DOM Render Page GET html Response Response Response GET css GET js CSSϒϩοΩϯά JSϒϩοΩϯά
  27. Render – Critical CSS • ϑΝʔετϏϡʔʹඞཁͳCSSͷΈΛinlineͰຒΊࠐΉ ɾ ɾ ɾ ←ͷදࣔʹඞཁͳ࠷௿ݶͷCSSΛ

    HTMLʹຒΊࠐΉ ←ͷCSS͸ը໘දࣔޙʹಡΈࠐΉ
  28. Render – Critical CSS • ϑΝʔετϏϡʔʹඞཁͳCSSͷΈΛinlineͰຒΊࠐΉ • CSSऔಘʹඞཁͳϦΫΤετ਺ΛݮΒͤΔ • CSSOMߏஙɾϨΠΞ΢τͷ࣌ؒΛ࡟ݮͰ͖Δ

  29. Render – Critical CSS • Ҏલ͸πʔϧͰࣗಈੜ੒͍ͯͨ͠ (https://github.com/addyosmani/critical) • ඞཁͳCSS͸༷ʑͳ৚݅ͰมΘΔͷͰࣗಈੜ੒Ͱ͸೉͍͠ •

    ݱࡏ͸ਓखͰඞཁͳCSSΛ؅ཧ هࣄ಺༰ʹΑͬͯϑΝʔετϏϡʔʹೖΔཁૉ͕ඍົʹมΘΔ
  30. Render – async/defer <script src= ”/bundle.js” async> <script src=”/bundle.js” defer>

    • r.nikkei͸non-SPA+SSRͳͷͰϑΝʔετϏϡʔදࣔʹjs͸ෆཁ • jsͷ࣮ߦ͸ը໘දࣔޙͰे෼ • async/deferͰjsͷಡΈࠐΈɾ࣮ߦλΠϛϯάΛมߋ
  31. Render – async/defer ύʔα͕scriptλάʹ౸ୡ HTMLύʔε׬ྃ DOMContentLoaded default https://html.spec.whatwg.org/multipage/scripting.html#attr-script-async HTMLύʔε JSμ΢ϯϩʔυ

    JS࣮ߦ
  32. Render – async/defer ύʔα͕scriptλάʹ౸ୡ HTMLύʔε׬ྃ DOMContentLoaded default async https://html.spec.whatwg.org/multipage/scripting.html#attr-script-async HTMLύʔε

    JSμ΢ϯϩʔυ JS࣮ߦ
  33. Render – async/defer ύʔα͕scriptλάʹ౸ୡ HTMLύʔε׬ྃ DOMContentLoaded default async defer https://html.spec.whatwg.org/multipage/scripting.html#attr-script-async

    HTMLύʔε JSμ΢ϯϩʔυ JS࣮ߦ jsͷDLɾ࣮ߦʹΑΔ ϒϩοΩϯάΛճආ
  34. Render – Critical Rendering Pathͷ࠷దԽ Request Page Start building DOM

    Build CSSOM Run JS Continue Building DOM Render Page GET html Response Response Response GET css GET js
  35. Render – Critical Rendering Pathͷ࠷దԽ Request Page Build CSSOM Run

    JS Continue Building DOM Render Page GET Html + Critical CSS Response Response GET js Start building DOM
  36. ϑΝʔετϏϡʔදࣔ଎౓ͷ࠷దԽ – PRPLύλʔϯ • Push: ϑΝʔετϏϡʔͷඳըʹඞཁͳϦιʔεΛPush • Render: ϑΝʔετϏϡʔΛඳը •

    Pre-cache: ࣍ʹඞཁͳϦιʔε΍ϖʔδΛPre-cache • Lazyload: ϑΝʔετϏϡʔ֎ͷίϯςϯπΛLazyload *Googleͷఏএ͢ΔSPAΛલఏͱͨ͠PRPLύλʔϯͱ͸ҟͳΔ΋ͷͷࢀߟʹ͍ͯ͠Δ
  37. Pre-cache Ϣʔβ͕࣍ʹඞཁͱ͢ΔίϯςϯπΛࣄલʹΩϟογϡ

  38. Pre-cache – ServiceWorker • ϒϥ΢β্ʹଘࡏ͢ΔϓϩΩγαʔόΈ͍ͨͳ΋ͷ • jsͰॊೈʹΩϟογϡͷ੍ޚ͕Մೳ • ΦϑϥΠϯͰ΋ΩϟογϡʹΞΫηεՄೳ ϒϥ΢β

    Service Worker Cache Network
  39. Pre-cache – ServiceWorkerͷޮՌͷҰྫ ServiceWorkerແ͠ ServiceWorker༗Γ

  40. Pre-cache – Ωϟογϡઓུ • τοϓϖʔδ΍ே༦ץͷهࣄͳͲΛΩϟογϡ • ճ༡͠ͳ͍Ϣʔβʹ͸pre-cache͠ͳ͍ • େ͖ͳίϯςϯπ͸wifi઀ଓ࣌ͷΈΩϟογϡ NetworkInformation

    APIͰwifi઀ଓঢ়گ֬ೝ
  41. Pre-cache Service Worker͸ॊೈ͚ͩͲखؒ΋͔͔Δ

  42. Pre-cache – ΩϟογϡͷTTL؅ཧ • ݹ͍ΩϟογϡΛ࡟আͯ͘͠ΕͨΓ͸͠ͳ͍ͷͰࣗલ࣮૷ • URLͱtimestampΛIndexed DBʹอଘ • Ωϟογϡߋ৽࣌ʹtimestampൺֱͯ͠ݹ͚Ε͹࡟আ

  43. Pre-cache – Ωϟογϡͷಉظ • Ϣʔβͷೝূঢ়ଶ͕มԽͨ͠ࡍʹෆ੔߹͕ੜ͡Δ • ϩάΞ΢τͯ͠΋ϩάΠϯঢ়ଶͷΩϟογϡ͕දࣔ͞ΕΔ • ༗ྉձһʹͳͬͯ΋ແྉձһ࣌ͷΩϟογϡ͕දࣔ͞ΕΔ etc…

  44. Pre-cache – Ωϟογϡͷಉظ • ϩάΠϯ/ϩάΞ΢τΛݕ஌ͯ͠Ωϟογϡ࡟আ • ձһঢ়ଶΛ؂ࢹͯ͠ɺมԽ͕͋ͬͨΒΩϟογϡ࡟আ Ϣʔβ͕ ༗ྉձһԽ ϒϥ΢β

    Service Worker Auth Status API purge ݖݶͷมԽΛݕ஌
  45. Resource Hints • ࣍ʹඞཁͱͳΔϦιʔεΛࣄલʹ४උ͢ΔͨΊͷAPI • dns-prefetch: DNSʹΑΔ໊લղܾΛࣄલʹߦ͏ • preconnect :

    TCP઀ଓΛࣄલʹߦ͏ • prefetch : ࣄલʹίϯςϯπΛऔಘͯ͠Ωϟογϡ • prerender : ϖʔδશମΛࣄલʹϨϯμϦϯά ྫ: <link rel="preconnect" href="//example.com">
  46. Resource Hints - ே༦ץϖʔδͷprefetch • ϢʔβͷಡΜͰ͍Δ໘ͷ࣍ͷ໘Λprefetch • URLݻఆɾϦιʔε͕੩తͳͷͰprefetch͠΍͍͢ Prefetchແ͠: ServerSide+Clientͷoverhead

    Prefetch༗Γ: overheadແ͠
  47. Resource Hints – ֎෦ίϯςϯπͷpreconnect • ޿ࠂ౳ͷ֎෦ίϯςϯπͰར༻͞ΕΔυϝΠϯ͸preconnect • ίϯςϯπ΍URL͕ಈతͰprefetch͸ͮ͠Β͍ ྘: DNSʹΑΔ໊લղܾ

    ᒵ: TCP handshake ࢵ: SSL handshake փ: ࣮σʔλͷऔಘ
  48. Resource Hints – ಈతͳprerender • Ϣʔβ͕࣍ʹ։͜͏ͱ͍ͯ͠ΔϖʔδΛprerender • Ϛ΢εΧʔιϧ͕ϦϯΫʹ͍ۙͮͨΒlinkλάΛૠೖ • λϒ੾Γସ͑ͱಉ͡଎౓ͰϖʔδભҠ

    LinkλάΛૠೖ
  49. ϑΝʔετϏϡʔදࣔ଎౓ͷ࠷దԽ – PRPLύλʔϯ • Push: ϑΝʔετϏϡʔͷඳըʹඞཁͳϦιʔεΛPush • Render: ϑΝʔετϏϡʔΛඳը •

    Pre-cache: ࣍ʹඞཁͳϦιʔε΍ϖʔδΛPre-cache • Lazyload: ϑΝʔετϏϡʔ֎ͷίϯςϯπΛLazyload *Googleͷఏএ͢ΔSPAΛલఏͱͨ͠PRPLύλʔϯͱ͸ҟͳΔ΋ͷͷࢀߟʹ͍ͯ͠Δ
  50. Lazyload ϑΝʔετϏϡʔपลͷΈಡΈࠐΈ PlaceholderΛૠೖ ࣮σʔλΛಡΈࠐΈ • DOMϊʔυͷେ͖͞ɾਂ͞Λ཈͑ͯߴ଎Խ

  51. ύϑΥʔϚϯεϞχλϦϯά • ϑΝΠϧαΠζ΍ϨϯμϦϯάऴྃ࣌ؒͳͲΛ؂ࢹ • Ұఆͷਫ४ΛԼճͬͨΒslackʹ௨஌

  52. Reliable

  53. ΦϑϥΠϯͰ΋هࣄ͕ӾཡͰ͖Δ ϒϥ΢β Service Worker Cache Network Offlineͷ৔߹͸ ServiceWorkerͷΩϟογϡฦ͢

  54. ΦϑϥΠϯͰ΋ϢʔβߦಈΛτϥοΩϯάͰ͖Δ • Background Sync • ΦϑϥΠϯ࣌ʹૹ৴ͨ͠ϦΫΤετΛΦϯϥΠϯ෮ؼ࣌ʹ࠶ૹ • τϥοΩϯά༻ͷσʔλΛBackground SyncͰૹ৴ •

    ΦϑϥΠϯ࣌ͷهࣄอଘɾίϝϯτ౤ߘͳͲʹ΋Ԡ༻Մೳ ϦΫΤετΛ อଘ ϒϥ΢β Indexed DB Server Service Worker Background Sync ͷొ࿥ ΦϯϥΠϯ෮ؼ·Ͱ଴ػ ϦΫΤετΛ ૹ৴
  55. Engaging

  56. ϗʔϜը໘΁ͷ௥Ճ • ϫϯλοϓͰΞΫηεՄೳ • ωΠςΟϒΞϓϦͬΆ͍ݟͨ໨ web manifestΛొ࿥͢ΔͱϗʔϜը໘΁ొ࿥Մೳ

  57. ϗʔϜը໘΁ͷ௥Ճ • ϗʔϜը໘͔Βىಈ͞Εͨ৔߹ʹ͸Ωϟογϡྔ૿΍͢ • ΑΓαΫαΫಈ͔ͨ͢Ί • ϗʔϜը໘͔Βͷىಈ͸navigator.standalone౳Ͱ൑ผՄೳ

  58. Push௨஌ • ଎ใ௨஌ʹར༻ • ए೥૚͸ϝʔϧΑΓ։෧཰͕ߴ͍ • ػցֶशʹΑΔΫϦοΫ཰࠷େԽ ͳͲΛݕ౼த

  59. Service Workerͷ։ൃ

  60. Workbox΁ͷஔ͖׵͑ • ࠷ۙ·ͰϑϧεΫϥονͰॻ͍͍͕ͯͨϝϯς͕͖͍ͭ • ΩϟογϡͷTTLͳͲɺΩϟογϡ؅ཧ͸શͯࣗྗ࣮૷ • IDB࢖ͬͯtimestamp؅ཧ͢Δͷͱ͔໘౗… Google੡ͷServiceWorker։ൃ༻ͷϥΠϒϥϦɾπʔϧ

  61. WorkboxͰग़དྷΔ͜ͱ – TTLͷ࣮૷ྫ WorkboxΛར༻͠ͳ͍৔߹ WorkboxΛར༻ͨ͠৔߹

  62. WorkboxͰग़དྷΔ͜ͱ • SWͰ΍Γ͍ͨجຊతͳࣄ͸֓Ͷ࣮૷͞Ε͍ͯΔ • Precaching • Runtime caching • Cache

    Strategies (stale-while-revalidateͱ͔) • Request routing • Background sync • ϩά͕਌੾Ͱڍಈ͕ͱͯ΋Θ͔Γ΍͍͢
  63. ServiceWorkerͷςετ • seleniumͰෳ਺ϒϥ΢βͰͷࣗಈςετΛ࣮ߦ • ServiceWorker༻ͷUnit/E2EςετϔϧύΛར༻ • https://github.com/GoogleChromeLabs/sw-testing-helpers • Ͱ΋΋͏ϝϯς͞Εͯͳͦ͞͏…

  64. ·ͱΊ • ೔ܦిࢠ൛͸PWAԽͰCVRɾDAU౳ଟ͘ͷࢦඪ͕վળͨ͠ • PWAԽͰ͸ϑΝʔετϏϡʔͷදࣔ଎౓Λॏࢹ • දࣔ଎౓վળͰ͸PRPLύλʔϯΛࢀߟ • ύϑΥʔϚϯε͸ܧଓతʹվળ͕ඞཁ •

    ServiceWorker։ൃͰ͸workbox΍sw-testing-helper͕ศར
  65. ͋Γ͕ͱ͏͍͟͝·ͨ͠