日経電子版のマイクロフロントエンドとPWA / devsum2019

96030bc60c6fc8a91f25ccda9b413b24?s=47 Sho Miyamoto
February 14, 2019

日経電子版のマイクロフロントエンドとPWA / devsum2019

日経電子版の最近の取り組みをマイクロフロントエンドとPWAに絡めて紹介します。(Developers Summit 2019でお話した内容です)

96030bc60c6fc8a91f25ccda9b413b24?s=128

Sho Miyamoto

February 14, 2019
Tweet

Transcript

  1. ೔ຊܦࡁ৽ฉࣾ ٶຊ ক (@shqld) 1 ೔ܦిࢠ൛ͷ ϚΠΫϩϑϩϯτΤϯυͱ PWA

  2. !2 - ໊લ - ٶຊ ক (Sho Miyamoto) - @shqld

    (Twitter, GitHub) - ࢓ࣄ - ೔ຊܦࡁ৽ฉࣾͷ૯߹৬ - r.nikkei.comͷϑϩϯτΤϯυɺ
 όοΫΤϯυɺCDNपΓ - ܦྺ - 2017/9: ֶ෦ଔۀ - 2018/4: ೔ܦ ৽ଔೖࣾ - JavaScriptͱͯ΋޷͖ ͩΕʁ
  3. !3 - 2010೥3݄૑ץ - ຖ೔໿900ຊͷهࣄΛ഑৴ - ݄ؒ3ԯΞΫηεҎ্ - ੈք࠷େͷܦࡁϝσΟΞ -

    ࠶དྷि͸ʮถேट೴ձஊϥΠϒʯʂ ೔ܦిࢠ൛
  4. !4 Server (BFF) Client Node.js (w/ Express) VanillaJS
 (Babel7) Sass

    handlebars
 (& JSX) ిࢠ൛ͷٕज़ελοΫ Script Webpack4 Style Markup SSR CDN Fastly
  5. ϚΠΫϩϑϩϯτΤϯυઃܭ 5

  6. 6 ϚΠΫϩϑϩϯτΤϯυͱ͸ https://micro-frontends.org

  7. 7 ϚΠΫϩϑϩϯτΤϯυͱ͸ Monolithic Frontends Organisation
 in Verticals https://micro-frontends.org

  8. 8 - ϚΠΫϩαʔϏε on ϑϩϯτΤϯυ - લఏɿʢϞμϯʣ΢ΣϒΞϓϦ - Ұͭͷը໘Λෳ਺ͷαʔϏε
 ʢಠཱͨ͠νʔϜʹΑΔػೳͷू߹ମʣʹ෼ׂ

    - SSR࣌ʹ݁߹ - ٕज़తཁૉ - SPA(s) - Web Components - SSI (ESI) ϚΠΫϩϑϩϯτΤϯυͱ͸
  9. ిࢠ൛͸ ʢϞμϯʣ΢ΣϒΞϓϦʁ !9

  10. !10 https://2018.ar.al/notes/the-documents-to-applications-continuum

  11. !11 https://2018.ar.al/notes/the-documents-to-applications-continuum ೔ܦిࢠ൛

  12. 12 - શମతʹ͸ - WebDocuments & Content-Centric - MPA -

    ੩త - ϖʔδ୯ҐͰੑ࣭͕େ͖͘ҟͳΔ - τοϓɺهࣄ - ݕࡧɺMyχϡʔε - ΞϓϦέʔγϣϯدΓ - ಈత ೔ܦిࢠ൛ͷίϯςϯπ
  13. ೔ܦిࢠ൛ͷϚΠΫϩઃܭ !13

  14. !14 - ʮҰͭͷը໘ʯ୯ҐͰ͸ͳ͘
 ʮϖʔδ͝ͱʹʯϚΠΫϩαʔϏεʹ෼ׂ - CDN(Fastly)Ͱ֤αʔϏεΛ݁߹ ೔ܦిࢠ൛ͷϚΠΫϩઃܭ https://speakerdeck.com/ryysd/microservices-on-fastly

  15. !15 - ϖʔδ ≒ αʔϏε - ϦϙδτϦ - σϓϩΠϑϩʔ -

    ٕज़બ୒ - ։ൃऀ - ֤αʔϏεؒ͸ૄ݁߹ - ଞαʔϏεͰඞཁͳ΋ͷ͸APIԽͯ͠CDNܦ༝ͰऔΓʹߦ͘ - αʔϏεؒͰڞ௨͢Δίʔυ - ϓϥΠϕʔτͳnpmύοέʔδʹ - ֤ύοέʔδ͸ͨͩͷػೳ܈ - ࢖͏ଆ͕దٓ औࣺબ୒ ೔ܦిࢠ൛ͷϚΠΫϩઃܭ
  16. !16 Server (BFF) Client ڞ௨ϥΠϒϥϦ APIGW Fastly هࣄ τοϓ ݕࡧ

  17. ϚΠΫϩϑϩϯτΤϯυ
 ͷԸܙ 17

  18. େ͖ͳมߋΛগͣͭ͠ !18

  19. TypeScriptΛಋೖͨ͠ !19

  20. !20 - JSͷͭΒ͞ - ʢαʔόʔαΠυʣϛυϧ΢ΣΞ΍ϧʔτ͝ͱͷॲཧɺҾճ ͢σʔλͷܗ - ʢϏϡʔʣίϯϙʔωϯτͷΠϯλʔϑΣʔε - ੩తܕݕ͕ࠪཉ͍͠

    - Flow vs Typescript - Flow͸ܕਪ࿦ڧ͍ - ϓϩδΣΫτͷઃఆ͕ॊೈ͡Όͳ͍ - ϓϩδΣΫτΛ·͍ͨͰܕఆٛΛڞ༗͠ʹ͍͘ - ઴ਐతͳTypeScriptԽ - ·ͣ͸ίʔυͷগͳ͍̍αʔϏε͔Β TypeScriptಋೖ
  21. !21 - TypeScript with Babel - tsc͸͋͘·ͰܕͷνΣοΫ͚ͩ - τϥϯεύΠϧ͸ࠓ·Ͱ௨ΓBabel7Ͱ -

    @babel/preset-typescript - TS͔ΒTSཁૉΛফ͚ͩ͢ - ECMAScriptඪ४͔Β֎Εͳ͍ʢಠ֦ࣗு͸αϙʔτ͞Ε͍ͯ ͳ͍ e.g. Enumʣ - JavaScriptͱͷڞଘ - JS͸BabelΛ௨ͯ͠΋Կ΋ى͖ͳ͍ - ιʔεϚοϓͷੜ੒͚ͩͰܕఆ͕ٛڞ༗Ͱ͖Δ TypeScript with Babel
  22. !22 - `NoImplicitAny` ͸େม - ґଘϞδϡʔϧ΍ؔ਺ͷҾ਺
 શͯʹܕΛ͚ͭΔඞཁ͕͋Δ - ίʔυͷن໛ʹΑͬͯ͸Ϟνϕʔγϣϯ͕ଓ͔ͳ͍ -

    ࠷ॳͷҰา͕Ұ൪େ͖͍นʹͳͬͯ͠·͏ - ޙ͔ΒͰ΋ྑ͍ ؤுΓ͗͢ͳ͍ܕ෇͚
  23. JSXΛಋೖͨ͠ !23

  24. !24 - ≠ Reactಋೖ - طଘͷςϯϓϨʔτΤϯδϯhandlebars͕ͭΒ͍ - ͋͘·ͰͨͩͷจࣈྻςϯϓϨʔτ - HTML༻͡Όͳ͍

    - ϦϯτͰ͖ͳ͍ - (͜͜ʹ͸ऩ·Γ͖Βͳ͍) - handlebars͔ΒJSX with Reactʹஔ͖׵͑ͨ - ϏϡʔͷϚʔΫΞοϓΛJSXͰॻ͘ - expressͷrenderॲཧͰSSR(react-render-to-string) JSXಋೖ
  25. !25 - Ұ౓Ͱશஔ͖׵͑͸ແཧ - htmlʹԊͬͨύʔε͕Ͱ͖ͳ͍ͷͰػցతͳஔ׵΋ݫ͍͠ - ϑΝΠϧ਺͕ଟ͘ɺґଘؔ܎΋ෳࡶ - ΞμϓλʔΛڬΜͩ -

    JSX͔ΒHBSɺHBS͔ΒJSXΛ૬ޓʹݺ΂ΔΑ͏ʹͨ͠ - https://github.com/shqld/handlebars-jsx-adapter Handlebars -> JSX
  26. !26 - JSX(TSX)ͷྑ͞ - ิ׬ɺϑΥʔϚςΟϯά͕ޮ͘ - ঢ়ଶͷड͚౉͕͠໌֬ - ܕͰറΕΔ -

    ΫϥΠΞϯταΠυͰReactΛ࢖Θͳͯ͘΋े෼Ըܙ͕͋Δ - ͋ΔαʔϏεͰReactΛ࢖͍ͨ͘ͳͬͨΒطଘͷϏϡʔʹΫϥ ΠΞϯτॲཧΛॻ͖଍͚ͩ͢ - lit-htmlͱ͔htm΋΋ͬͱ੒ख़࢝͠ΊͨΒݕ౼͍ͨ͠ ςϯϓϨʔτΤϯδϯͱͯ͠ͷJSX
  27. !27 https://medium.com/dev-channel/a-netflix-web-performance-case-study-c0bcde26a9d9

  28. E2Eςετ on Codebuild !28

  29. !29 - E2E͸ӡ༻తʹ΋Ϧιʔεతʹ΋େม - ಛʹΫϩεϒϥ΢βʔ(incl. IE11) - ීஈ࢖͍ͷCircleCIͰ΍Δͱڞ༗ͷΩϡʔΛ٧·Βͤͯ͠·͏ - ͦ͏ͩɺCodeBuildͰ΍Ζ͏ʂ☺

    - CircleCIͰϏϧυɺηΧϯμϦίϯςφʹσϓϩΠ - CodeBuildΛτϦΨʔ͢Δ - CodeBuild্ͰσϓϩΠ͞ΕͨηΧϯμϦͷURLʹରͯ͠E2Eς ετ - ੒ޭͨ͠Βεϫοϓ(Codebuild) E2Eςετ on CodeBuild
  30. !30 CodeBuild Github CircleCI build push deploy Secondary Primary swap

    E2E test test
  31. PWA 31

  32. !32 - ࠓߋײͷ͋Δ࿩Ͱ͕͢… - PWȀຊப - ৴པ(࣮֬)ੑ - ଎͞ -

    ΞϓϦͱͯ͠ͷັྗ PWA • Reliable - Load instantly and never show the downasaur, even in uncertain network conditions. • Fast - Respond quickly to user interactions with silky smooth animations and no janky scrolling. • Engaging - Feel like a natural app on the device, with an immersive user experience. https://developers.google.com/web/progressive-web-apps/
  33. Fast & EngagingΛ೦಄ʹ
 ৭ʑ΍ͬͨ !33

  34. !34 AppShell - https://developers.google.com/web/fundamentals/architecture/app-shell

  35. !35 - https://developers.google.com/web/fundamentals/architecture/ app-shell - FirstPaint͕ߴ଎ʹͳΔ - ΦϑϥΠϯ࣌Ͱ΋࠷௿ݶͷΞϓϦײ͕ग़Δ - MPAͰ΋SPAͷΑ͏ͳUX

    - ͍·೔ܦిࢠ൛Ͱ͸࣮ݧத AppShell
  36. !36 - Πϝʔδɿίϯςϯπ෦෼ͷશLazyload - ྲྀΕɿ - SWͰφϏήʔγϣϯϦΫΤετΛδϟοΫͯ͠AppShellΛฦ ͢ - AppShellͷεΫϦϓτλάͰwindow.locationΛfetch

    - DOMΛॻ͖׵͑Δ - ग़͠෼͚ - CacheϛεɿAppShellΛฦ͢ - Cacheώοτɿͦͷ··ΩϟογϡΛϨϯμϦϯάͨ͠ํ͕ ଎͍ AppShellͷ࣮૷
  37. !37

  38. !38 - GoogleChromeLabs/quicklink - ը໘಺ʹೖͬͨaλάཁૉΛࣗಈͰϓϦ Ωϟογϡͯ͘͠ΕΔ͓खܰϥΠϒϥϦ - ॎʹΞΠςϜΛฒ΂ΔΑ͏ͳίϯςϯπʹ ͸޲͍͍ͯΔ

  39. !39 - IntersectionObserverͰviewportʹೖͬͨaλάΛ؂ࢹ - ༏ઌ౓ผͷઓུ - ߴ: fetch - ௿:

    ResourceHints௥Ճ (`<link rel=“prefetch” ~`) - requestIdleCallbackͰΫϦςΟΧϧϨϯμϦϯάΛअ ຐ͠ͳ͍
  40. !40 - hrefΛSWʹpostMessageͰ౉ͯ͠ϓϦΩϟογϡ - ϝϦοτ - UIεϨου͸observeͯ͠postMessage͢Δ͚ͩ - ϦΫΤετ͕ൃੜ͠ͳ͍෼ɺෛՙ͕গͳ͍ -

    طଘͷSWͷΩϟογϡઓུΛ׆͔ͤΔ - ҰݩతʹΩϟογϡΛѻ͑Δ - ༏ઌ౓Λؾʹ͠ͳͯ͘ྑ͍ with SW
  41. None
  42. Critical CSS !42

  43. !43 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ϒϩοΩϯά
  44. !44 Render – Critical CSS • ϑΝʔετϏϡʔʹඞཁͳCSSͷΈΛinlineͰຒΊࠐΉ ɾ ɾ ɾ

    ←ͷදࣔʹඞཁͳ࠷௿ݶͷCSSΛ HTMLʹຒΊࠐΉ ←ͷCSS͸ը໘දࣔޙʹಡΈࠐΉ
  45. !45 Render – Critical CSS • ϑΝʔετϏϡʔʹඞཁͳCSSͷΈΛinlineͰຒΊࠐΉ • CSSऔಘʹඞཁͳϦΫΤετ਺ΛݮΒͤΔ •

    CSSOMߏஙɾϨΠΞ΢τͷ࣌ؒΛ࡟ݮͰ͖Δ
  46. !46 - ίϯςϯπ΍ձһଐੑʹΑͬͯඞཁͳCSS ͷ͹Β͖͕ͭେ͖͍ - e.g. ࣸਅɺϏσΦɺදɺPaywall - ಈతʹग़͠෼͚ΒΕͳ͍ -

    ʮίϯςϯπʹΑͬͯ͸ݟͨ໨͕େ͖͘ ่Εͯ͠·͏ʯ͸ڐ༰Ͱ͖ͳ͍ - ͍·͸ࣗಈੜ੒Ͱ͸ͳ͘ਓखͰ؅ཧ ೔ܦిࢠ൛ͷCCSSࣄ৘
  47. !47 - HTMLαΠζͷ50%લޙ͕CCSS - ʢαʔϏε͝ͱʹʣશϖʔδʹಉ͡CCSS͕ΠϯϥΠϯͰຒΊ ࠐ·Ε͍ͯΔ - CDNͷసૹྔͷແବ - ΫϥΠΞϯτΩϟογϡͷ༰ྔΛṧഭ

    - ௨৴ͷύϑΥʔϚϯεͷ௿Լ - ΠϯϥΠϯͳͷͰ੾Γ཭ͤͳ͍ - e.g. هࣄϖʔδ - CSS: 544k - CCSS: 489k CCSS͕ॏ͍
  48. Dynamic Critical CSS Optimization !48

  49. !49 - ֤ϖʔδ͝ͱʹ࠷దͳCCSSΛಈతʹϏϧυ͢Δ - ΦϦδϯ͔Β഑৴͢ΔHTMLʹ͸CCSSΛؚΊͳ͍ - ίϯςϯπ΁ͷϦΫΤετ͕͋Δ౓ʹɺVarnishͷESIΛ༻͍ͯ Vary͝ͱͷίϯςϯπʹ࠷దԽ͞ΕͨCSSΛੜ੒͠ɺS3ʹΞο ϓϩʔυ -

    ࠷దCCSSϏϧυ͕ऴΘͬͨΒΩϟογϡΛύʔδ - Edge-side Includes CCSS - ESIͰσϑΥϧτ(or ࠷దԽࡁ)CCSSͷಡΈࠐΈ - htmlͱ݁߹ - e.g. هࣄϖʔδ - CCSS: 489k - Optimized critical: 69k Dynamic Critical CSS Optimization
  50. !50 CSS Default CCSS / Dynamic CCSS HTML
 w/ ESI

    tag CSS Complete HTML /article/123 Edge-side Includes Critical CSS (Origin Server) (CSS Server) build ESI request Fetch
 contents Fetch
 CCSS Purge cache
  51. !51 - ݱঢ়͸EBͰ৭ʑ΍ͬͯΔ - ੍໿͕ͳ͍ & σόοά͠΍͍͢ - Ϗϧυ͕٧·ͬͯαʔό͕མͪΔՄೳੑ͕͋Δ -

    CCSSͷ࠷దԽ෦෼͸αʔόϨεʹ͍ͨ͠ - ϦΫΤετϋϯυϦϯά: on CDN - Ϗϧυ: Lambda (w/ @serverless/chrome) Future Works
  52. !52 CSS Default CCSS / Dynamic CCSS HTML
 w/ ESI

    tag Complete HTML /article/123 Serverless (Origin Server) Fetch
 contents Fetch CCSS
 as ESI request Purge Trigger build
  53. ϚΠΫϩϑϩϯτΤϯυͱ PWA !53

  54. ϞϊϦεԽ͢ΔServiceWorker !54

  55. - ServiceWorker͸ϞϊϦεʹͳΓ͕ͪ - ϚΠΫϩϑϩϯτΤϯυͳ؀ڥͳΒSW΋ϚΠΫϩαʔϏε ୯ҐͰ͋ͬͯ΄͍͠ - جຊతʹ͸มߋ͕શମʹ೾ٴͯ͠͠·͏ͷͰɺ༧ظͤ͵ෆ۩ ߹͕ͰΔՄೳੑ - είʔϓͰӨڹൣғΛݶఆͰ͖Δͷ͸҆৺

    !55 ͏Θͬ…ࢲͷSWɺϞϊϦγοΫ͗͢…?
  56. ϚΠΫϩ ServiceWorkers !56

  57. !57 Server (BFF) Client Service
 Worker هࣄ ݕࡧ τοϓ ڞ௨ϥΠϒϥϦ

    APIGW
  58. !58 - είʔϓ͕۠੾ΒΕ͍ͯΔͷͰɺͦͷαʔϏεͷ͜ͱ͚ͩΛߟ ͑Ε͹Α͍ͷͰ͔ͳΓ҆৺ɺσϓϩΠ΋ָ - ؆୯ - ֤ϚΠΫϩαʔϏεͷαʔόͰείʔϓΛݶఆͯ͠഑৴ - ϨεϙϯεϔομͰ`Service-Worker-Allowed`Λࢦఆ͢Ε͹

    είʔϓͷύε੍ݶΛճආͰ͖Δ - ΫϥΠΞϯτଆͰݶఆ͞ΕͨείʔϓʹSWΛΠϯετʔϧ ϚΠΫϩαʔϏεϫʔΧʔ
  59. !59 - ֤ϫʔΧʔ͕উखʹଞͷϫʔΧʔͷΩϟογϡΛফͯ͠͠·͏ɺͱ͍͏ έʔε͕͋Δ - ಡΈग़࣌͠ʹଞͷϫʔΧʔͷΩϟογϡ͋ΔͳΒͦΕΛ࢖͍͍ͨ - ํ๏͸̎ͭ - ͦΕͧΕͷΩϟογϡΞΠςϜͷॴ༗ऀ͕୭͔Λ؅ཧ͢Δ

    - ಡΈग़͕͠଎͍ - Ωϟογϡɺύʔδ͕खؒ - GoogleͷWorkboxʹ৐͍ͬͯΔͱ೉͍͠ - ΩϟογϡετϨʔδΛαʔϏε͝ͱʹ੾Γ෼͚Δ - Ωϟογϡɺύʔδָ͕ - ಡΈग़͕͠஗͍ - ࠓ͸ͬͪ͜Ͱ࣮ݧத ϚΠΫϩͳΩϟογϡ؅ཧઓུ
  60. Feature Flags !60

  61. !61 https://martinfowler.com/articles/feature-toggles.html

  62. !62 - a.k.a Feature Toggles - ֎෦ͷίϯϑΟά(Key-Value)Λࢀর - ͦͷ஋ʹΑͬͯػೳΛग़͠෼͚Δ -

    SaaS΋͋Δ - http://featureflags.io/ - FirebaseͷRemoteConfigʢωΠςΟϒΞϓϦ޲͚ʣ Feature Flags
  63. Feature Flags for SW !63

  64. !64 - ϚΠΫϩαʔϏε(SW)Խʹ - ϑϥάͰΑΓҰݩతʹػೳ։ൃ/௥ՃΛ؅ཧ͍ͨ͠ - SWͷڍಈΛ֎͔Β੍ޚͰ͖ͳ͍ͷ͸ා͍ - PWA։ൃͰ΋μʔΫϩʔϯνΛ͍ͨ͠ Feature

    Flags for SW
  65. !65 - ServiceWorkerͷregisterPathʹϑϥά৘ใΛ৐ͤΔ - ϑϥά͕มΘΕ͹SW͕ߋ৽͞ΕΔ - φϏήʔγϣϯϦΫΤετ͕SWͰδϟοΫ͞Ε͍ͯΔͱ͖͸ ཁ஫ҙ - ిࢠ൛Ͱ͸NR͸جຊతʹશͯ

    `no-cache` Feature Flags for SW
  66. - ϚΠΫϩϑϩϯτΤϯυͰϚΠΫϩ։ൃ - TypeScript͸ݞͷྗΛൈ͍ͯऔΓ૊Ή - JSX͸ςϯϓϨʔτΤϯδϯͱͯ͠΋࠷ߴ - E2E͸ผͷCIͰ΍Δͱ͖ͬ͢Γ - AppShell

    & Quicklink ͓͢͢Ί - Edge-side optimizationʹ͸ເ͕͋Δ - ϚΠΫϩαʔϏεϫʔΧʔ҆৺ - Feature FlagsΛ࢖ͬͯμʔΫϩʔϯν !66 ·ͱΊ
  67. ͋Γ͕ͱ͏͍͟͝·ͨ͠ !67