ç§ã¯ãYandexãå°ãäžæããã2008幎ã«ãããªãåã«ã³ãŒãåå²ã«ééããŸããããµã€ãã«åææ¥ç¶ãããYandex.Directã¹ã¯ãªããã¯ãåã«ãã®ãµã€ããæ®ºããŸããã äžè¬ã«ããã¹ã¯ãªããããæ£ããé åºã§æ¥ç¶ãã10åã®ãã¡ã€ã«ã§ããå Žåãåœæã¯æ£åžžã§ããããããã§ãïŒé
å»¶ããŠïŒæ£åžžã«æ©èœããŸãã
ãã®åŸãã«ãŒããç©æ¥µçã«äœ¿çšãå§ããŸãããããããã¯ãŸã å€éšã¹ã¯ãªãããšããŠããã¡ããé
å»¶ããŒããšããŠæ¥ç¶ãããŠããŸãã æ¬¡ã«ãYandex.MapsããŒã ã®ã¡ã³ããŒãšããŠã ymodulesãç©æ¥µçã«äœ¿çšããŠã¯ã©ã€ã¢ã³ãã§ããªãŒã·ã§ãŒãã³ã°ã䜿çšããŸãããããã«ãããå®ç§ãªã³ãŒãåå²ãå®çŸããŸããã
ãããŠã webpack
ãšReact
ã«è¡ãã webpack
ãæ°ããéã®éçŸã®ããã«èŠãããã³ãã銬鹿ã®åœã«è¡ããŸããã
ã³ãŒãåââå²ã¯ãããæ©èœã§ã¯ãªããå¿
é ã§ãã ããã§ãã SSR
ã¯å¹²æžããŸãã...

å°ããªç޹ä»
æè¿ã§ã¯ããã³ãã«ãæ¯æ¥å€§ãããªããšãã³ãŒãã®åå²ããããŸã§ä»¥äžã«éèŠã«ãªããŸãã åœåã人ã
ã¯ã¢ããªã±ãŒã·ã§ã³ã®åããŒãžã«åå¥ã®ãšã³ããªãã€ã³ããäœæããã ãã§ãã®ç¶æ³ããæãåºããŸãããããã¯äžè¬çã«ã¯è¯ãããšã§ãããSPAã§ã¯æ©èœããŸããã
次ã«ã require.ensure
颿°ãç»å ŽããŸããã require.ensure
ã仿¥dynamic import
ïŒåã«ã€ã³ããŒãïŒãšããŠç¥ãããŠããŸãããã®é¢æ°ã䜿çšããŠãã¢ãžã¥ãŒã«ãç°¡åã«èŠæ±ã§ããŸãã
Reactã®ãã®ã±ãŒã¹ã«é¢ããæåã®ã©ã€ãã©ãªã¯react- loadableã§ãããããã®åšå²ã®èªå€§åºåã¯ãŸã ç§ã«ã¯ããŸãæç¢ºã§ã¯ãªãããã§ã«æ»ãã§ããŸãïŒèè
ãåã°ããã®ããããŸããïŒã
ããŠãå€ããå°ãªãããå
¬åŒããªéžæã¯React.lazy
ãšReact.lazy
-components ïŒã¡ããã©@loadable
ïŒã§ããããããã®éã®éžæã¯æçœã§ãïŒ
- äžè¬çã«ãReact.lazyã¯SSRïŒãµãŒããŒãµã€ãã¬ã³ããªã³ã°ïŒãå®å
šã«äžå¯èœã§ãã ãã¹ãã§ãããåæãããã¹ããªã©ã®ã¿ã³ããªã³ãšã®ç¹å¥ãªãã³ã¹ãªãã§èœã¡ãŸãã
- Loadable SSRã¯ãSuspenseããµããŒãããªãããReact.LazyãããæªããããŸããã
ç¹ã«ãloadableã¯ã©ã€ãã©ãªãããŒãããããã®çŸããã©ãããŒïŒloadable.libãreact renderPropã«moment.jsãåã蟌ãããšãã§ããŸãïŒããµããŒããããµãŒããŒåŽã®webpackãããªãã§ããçšã®äœ¿çšæžã¿ã¹ã¯ãªãããã¹ã¿ã€ã«ãããã³ãªãœãŒã¹ã®ãªã¹ããåéããã®ãæ¯æŽããŸãïŒwebpackèªäœã¯å®éã«ã¯ç¥ããŸããïŒã äžè¬çã«ã å
¬åŒããã¥ã¡ã³ãããèªã¿ãã ããã
SSR
äžè¬ã«ãåé¡ã¯ãã¹ãŠSSRã«ãããŸãã CSRïŒã¯ã©ã€ã¢ã³ããµã€ãã¬ã³ããŒïŒã®å ŽåãReact.lazyãŸãã¯10è¡ã®å°ããªã¹ã¯ãªããã®ãããããé©åããŸã-ããã¯ééããªãååã§ããã倧ããªå€éšã©ã€ãã©ãªãæ¥ç¶ããããšã¯æå³ããããŸããã ãããããµãŒããŒäžã§ã¯ããã§ã¯ååã§ã¯ãããŸããã ãŸããSSRãæ¬åœã«å¿
èŠãªãå Žåã¯ãèªã¿é²ããããšãã§ããŸããã é·ãé£ãã解決ãå¿
èŠãªåé¡ã¯ãããŸããã
SSRã¯èŠçã§ãã ç§ã¯ïŒããæå³ã§ã¯ïŒããŒãå¯èœã³ã³ããŒãã³ãã®ã¡ã³ãããŒã®1人ã§ãããããŸããŸãªå Žæããããã€ã®ãã°ãåºãã®ããšããã®ã¯æãããããšã§ãã ãããŠãã¢ããããŒãã®ãã³ã«webpackã¯ããã«é£ã¶ããã«ãªããŸãã
SSR + CSS
SSRã®åé¡ã®ããã«å€§ããªåå ã¯CSSã§ãã
Styled-componentsã䜿çšããŠããå ŽåïŒããã»ã©å®³ã¯ãããŸããïŒã transform-stream
ãä»å±ããŠãããæçµçãªã³ãŒãã«å¿
èŠãªãã®ã远å ãããŸãã äž»ãªãã®ã¯ãã©ãã«ã§ãSCã®1ã€ã®ããŒãžã§ã³ãããã¯ãã§ããããã§ãªããã°ãã©ãŒã«ã¹ã¯æ©èœããŸãã-SCã®1ã€ã®ããŒãžã§ã³ã¯ããèªäœã«ã€ããŠä»ã«äœãäŒããããšãã§ãããSCã¯å¢æ®ããã®ã倧奜ãã§ãïŒãã³ãã«ã確èªããŠãã ããïŒã æ£çŽã«èšããšããã©ãŒã«ã¹ãé垞倱æããã®ã¯ããŸãã«ãã®å¶éã®ããã§ãã
Cã®ææ
ã¯ããåçŽã§ã-ãããã®styled
ã¢ããã¿ãŒã¯ãã³ã³ããŒãã³ãèªäœã®åã«<style>
åã«åãåºããåé¡ã¯è§£æ±ºããŸãã ã·ã³ãã«ã§å®ããŠéœæ°ãªã ååãšããŠãéåžžã«ã¢ãã€ã«ãã¬ã³ããªãŒã§ãããéåžžã«æåã®ãã¥ãŒã倧å¹
ã«æé©åããŸãã ãããã2çªç®ã¯å°ãæãªãããŸãã ãããŠå人çã«ãç§ã®è¯å¿ã¯ç§ããã®ãããªã¹ã¿ã€ã«ãã€ã³ã©ã€ã³åããããšãèš±å¯ããŠããŸããã
éåžžã®CSSïŒããŸããŸãªããžãã¯ãåããããŸããŸãªCSS-in-JSã©ã€ãã©ãªããååŸãããã®ãå«ãïŒã䜿çšãããšãããã«ã·ã³ãã«ã«ãªããŸãããããã«é¢ããæ
å ±ã¯webpackåã«ãããã©ã®CSSãæ¥ç¶ããå¿
èŠããããããããã£ãŠããŸããã
æ¥ç¶é åº
ããã§ç¬ã¯èªåèªèº«ãåããŸããã ãã€æ¥ç¶ããå¿
èŠããããŸããïŒ
SSRãã¬ã³ããªãŒã³ãŒãåå²ã®æå³ã¯ã ReactDOM.hydrate
ãåŒã³åºãåã«ããµãŒããŒã®å¿çã«æ¢ã«ååšãããã¹ãŠã®ãã³ã³ããŒãã³ãããããŠã³ããŒãããå¿
èŠãããããã¯ã©ã€ã¢ã³ãã«çŸåšããŒããããŠããã¹ã¯ãªããã«ã¯äœè£ããªãããšã§ãã
ãããã£ãŠããã¹ãŠã®ã©ã€ãã©ãªã¯ããã¹ãŠã®ãã¹ãŠãããŒãããå¿
èŠããããšãã«åŒã³åºãããç¹å®ã®ã³ãŒã«ããã¯ãæäŸãã è³ãèµ·åã§ããŸãã ããã¯ãSSRã³ãŒãåå²ã©ã€ãã©ãªã®äœæ¥ã®æå³ã§ãã
JSã¯ãã€ã§ãèªã¿èŸŒãããšãã§ããéåžžããã®ãªã¹ãã¯HTMLã®æåŸã«è¿œå ãããŸãããFOUCããªãããã«CSSãå
é ã«è¿œå ããå¿
èŠããããŸãã
ãã¹ãŠã®ã©ã€ãã©ãªã¯å€ãrenderToString
ã«å¯ŸããŠãããè¡ãããšãã§ãããã¹ãŠã®ã©ã€ãã©ãªã¯renderToString
ã«å¯ŸããŠãããè¡ãããšãã§ããŸãã ã
JSïŒããã¯çºçããŸããïŒãŸãã¯SC / EmotionïŒããèªäœã远å ãããŸãïŒã®ã¿ãæã£ãŠãããã©ããã¯é¢ä¿ãããŸããã ããã-ããããªãããã¡ããã©CSSããæã£ãŠãããªã-ããã ãã§ãã ããããæåŸã«ãªããã renderToString
ãŸãã¯ä»ã®ãããã¡ãªã³ã°ã䜿çšããå¿
èŠããããŸããããã¯ãTTFBïŒæåã®ãã€ããŸã§ã®æéïŒé
å»¶ãæäŸãããã®SSRã®äžè¬çãªæå³ããããã«æžãããŸãã
ãããŠãã¡ãã-ããã¯ãã¹ãŠwebpackã«é¢é£ä»ããããŠããããã以å€ã®æ¹æ³ã§ã¯ãããŸããã ãããã£ãŠãããŒãå¯èœã³ã³ããŒãã³ãã®äœæè
ã§ããGregã«æ¬æãæã£ãŠ-ä»ã®ãªãã·ã§ã³ãæ€èšããããšãææ¡ããŸãã
次ã¯3ã€ã®ããŒããããªãã¢ãžã§ã³ãã§ãããã®äž»ãªã¢ã€ãã¢ã¯ã殺ãããããã³ãã©ãŒã«äŸåããªãããšãè¡ãããšã§ãã
1. React-Imported-Component
React-Imported-Componentã¯æªããããŒããŒãã§ã¯ãªããå€ããå°ãªããæšæºçãªã€ã³ã¿ãŒãã§ã€ã¹ãæã¡ãããŒãå¯èœãªã³ã³ããŒãã³ãã«éåžžã«äŒŒãŠãããç§»åãããã¹ãŠã®ãã®ãSSRã§ããŸãã
ã¢ã€ãã¢ã¯ãšãŠãã·ã³ãã«ã§ãã
stats.json
ãstats.json
ãwebpackæé©åïŒé£çµããŸãã¯å
±éã³ãŒãïŒã«é©å¿stats.json
å¿
èŠã¯ãããŸãã-é
åã®ããŒã«ãã1ã€ã®ã€ã³ããŒãã®ãã©ãã«ããäžèŽãããŠãå床ã€ã³ããŒãããã ãã§ãã ç¹å®ã®ãã³ãã©ãŒã®äžéšãšããŠå®è¡ãããæ¹æ³ãå®éã«ããŠã³ããŒãããããã¡ã€ã«ã®æ°ãããã³ã©ãããã§ãåé¡ã§ã¯ãªãã
ãã€ãã¹-ãäœ¿çšæžã¿ããã£ã³ã¯ã®ããŒãã®éå§ã¯ããããã³ã°ãä¿åããã¡ã€ã³ãã³ãã«ã®ããŒãåŸã«çºçããŸããããã¯ããã®æ
å ±ãHTMLã«çŽæ¥è¿œå ããããŒãå¯èœã³ã³ããŒãã³ãã®å Žåãããå°ããåŸãã§ãã
ã¯ããCCSã§ã¯ãåèªããã¯ãŸã£ããæ©èœããŸããã
2.äœ¿çšæžã¿ã¹ã¿ã€ã«
ãã ãã used-styleã¯CSSã§ã®ã¿æ©èœããŸãããreact-imported-componentsãšã»ãŒåãæ¹æ³ã§æ©èœããŸãã
- ãã¹ãŠã®cssãã¹ãã£ã³ããŸãïŒãã«ããã£ã¬ã¯ããªå
ïŒ
- ã©ã®ã¯ã©ã¹ãå®çŸ©ãããŠããããèŠããŠãã
- åºåãã¹ãã£ã³renderToNodeStreamïŒãŸãã¯
renderToString
å¿çïŒ - class = 'XXX'ãèŠã€ãããã¡ã€ã«ãšäžèŽãããµãŒããŒã®å¿çã§ãããåãåºããŸãã
- ïŒããããããã€ãã¬ãŒããå£ããªãããã«ããã¹ãŠã®ãã®ãããªã¹ã¿ã€ã«ãé ã«ãã¬ããŒãããŸãïŒã ã¹ã¿ã€ã«ã³ã³ããŒãã³ãã¯ãŸã£ããåãããã«æ©èœããŸãã
TTBTã®é
å»¶ã¯ãããŸããããã³ãã©ãŒãšã¯é¢ä¿ãããŸãã-ããšã話ã§ãã ã¹ã¿ã€ã«ãããæžãããŠããã°ãæèšã®ããã«æ©èœããŸãã
React-import-component + used-styles + parcel workingã®äŸã
æãæãããªããŒãã¹ã§ã¯ãããŸãã-ãµãŒããŒã§ã¯ãäž¡æ¹ã®ã©ã€ãã©ãªã¯ãèµ·åæã«ããšã¯ã¹ãã¬ã¹ãµãŒããŒãæåã®ã¯ã©ã€ã¢ã³ããåä¿¡ã§ãããŸã§ããå¿
èŠãªãã¹ãŠããè¡ãããµãŒããŒãšãã¹ãã®äž¡æ¹ã§å®å
šã«åæãããŸãã
3. react-prerendered-component
ãããŠãã©ã€ãã©ãªã¯ããã3ãéããŸããããã¯ãéšåçãªæ°Žåè£çµŠããè¡ã ãããã«çåã«æãã»ã©ã®ç¥ç¶ã®ããæ¹ã§ãããè¡ããŸãã åœŒå¥³ã¯æ¬åœã«ããã£ãŒããã远å ããŸãã
- ãµãŒããŒäžïŒ
- ãæåãªIDããæã€divã«æšçãã©ããããŸã
- ã¯ã©ã€ã¢ã³ãäžïŒ
- ã³ã³ããŒãã³ãã³ã³ã¹ãã©ã¯ã¿ãŒãããã®ãdivãèŠã€ãã
- ReactãååŸããåã«innerHTMLãã³ããŒããŸãã
- ã¯ã©ã€ã¢ã³ãã
hydrate
æºåãã§ãããŸã§ãã®HTMLã䜿çšããŸã - æè¡çã«ã¯ãããã«ããHybrid SSRïŒRendertronïŒã䜿çšã§ããŸã
const AsyncLoadedComponent = loadable(() => import('./deferredComponent')); const AsyncLoadedComponent = imported(() => import('./deferredComponent')); <PrerenderedComponent live={AsyncLoadedComponent.preload()} // when Promise got resolve - component will go "live" > <AsyncLoadedComponent /> // meanwhile you will see "preexisting" content </PrerenderedComponent>
ãã®ãã©ãŒã«ã¹ã¯ãããªããŒãpromiseããè¿ãããªããããloadable-componentsã§ã¯æ©èœããŸãã ã ããã¯ããã³ã³ãã³ãããæã£ãŠããããå®éã®ãSSRãééããŠããªãã react-snap ïŒããã³ä»ã®ãã¬ã³ããªã³ã°ãïŒã®ãããªã©ã€ãã©ãªã«ãšã£ãŠç¹ã«éèŠã§ãã

ã³ãŒãã®èгç¹ããèŠããšãããã¯10è¡ã«å ããŠãã³ãŒãã®ããŒããšå®è¡ã®ã©ã³ãã ãªé åºãèæ
®ããŠã å®å®ããSSR-CSR UIDãååŸããããã®ããå°ãã®è¡ã§ãã
ããŒãã¹ïŒ
- é è³ãéå§ããåã«ããã¹ãŠã®ã¹ã¯ãªããã®ããŒãããåŸ
ã€å¿
èŠã¯ãããŸãã-é è³ã¯æºåãã§ãããšãã«éå§ããŸã
- ãã¬ã€ã³ãããŒãããå¿
èŠã¯ãŸã£ãããããŸãããSSRãããããŒã¿ãæ®ãå¿
èŠããããŸãïŒSSRããŒãžã§ã³ããªãå Žåããã¬ãŒã³ã¯ããŒããããŸãïŒã jQueryã®æä»£ã®ããã«ã
- 倿ã¹ããªãŒã ã䜿çšããŠã倧ããªã¬ã³ããŒãããã¯ã®ã¹ããªãŒã ãã£ãã·ã³ã°ãå®è£
ããããšãã§ããŸãïŒçè«çã«ã¯SuspenceäºæïŒã
- jQueryã®ãšãã®ããã«ãç¶æ
ãHTMLãã/ã«ã·ãªã¢ã©ã€ãº/ãã·ãªã¢ã©ã€ãºããŸã
ååãšããŠãç¶æ
ã®è€è£œã®åé¡ã解決ããããã®ã©ã€ãã©ãªãäœæããäž»ãªã¢ã€ãã¢ã¯ãã·ãªã¢ã«åãšã·ãªã¢ã«åè§£é€ã§ãïŒSSRã«é¢ããèšäºã®åçïŒã ãã£ãã·ã³ã°ã¯åŸã§å°çããŸããã

åèš
åèšã§ãSSRãšã³ãŒãåå²ã®èŠæ¹ãå€ããããšãã§ãã3ã€ã®ã¢ãããŒãããããŸãã æåã¯JSã³ãŒãåå²ã§åäœããå£ããŸããã 2çªç®ã¯CSSã³ãŒãåå²ã§æ©èœããå£ããŸããã 3çªç®ã®æ¹æ³ã¯HTMLã¬ãã«ã§æ©èœããäžéšã®ããã»ã¹ãç°¡çŽ åããã³é«éåããŸãããŸããç ŽæããŸããã
ã©ã€ãã©ãªãžã®ãªã³ã¯ïŒ
èšäºïŒè±èªïŒ