React и Code Splitting

С code splitting я познакомился очень давно, в году так 2008, когда Яндекс немного подвис, и скрипты Яндекс.Директа, синхронно подключенные на сайте, просто этот сайт убили. Вообще в те времена было нормой, если ваши «скрипты» это 10 файлов которые вы подключаете в единственно правильном порядке, что и до сих пор (с defer) работает просто на ура.
Потом я начал активно работать с картами, а они до сих пор подключаются как внешние скрипты, конечно же lazy-load. Потом уже, как член команды Яндекс.Карт, я активно использовал ymodules возможность tree-shaking на клиенте, что обеспечивало просто идеальный code splitting.

А потом я переметнулся в webpack и React, в страну непуганных идиотов, которые смотрели на require.ensure как баран на новые ворота, да и до сих пор так делают.

Code splitting — это не «вау-фича», это «маст хэв». Еще бы SSR не мешался…

477yayld6xtgc06hmgfejbrfpxc.jpeg


Маленькое введение

В наше время, когда бандлы полнеют с каждым днем, code splitting становиться как никогда важен. В самом начале люди выходили из данной ситуации просто, создавая отдельные entrypoint, для каждой страницы своего приложения, что вообще хорошо, но для SPA работать не будет.
Потом появилась функция require.ensure, сегодня известная как dynamic import(просто import), посредством которой можно просто запросить модуль, который чуть позже и «получите».

Первой библиотекой «про это дело» для React был react-loadable, хайп вокруг которой мне до сих пор не очень понятен, и которая уже сдохла (просто перестала нравиться автору).

Сейчас более менее «официальным» выбором будут React.lazy и loadable-components (просто @loadable), и выбор между ними очевиден:


  • React.lazy совсем никак не может SSR (Server Side Rendering), от слова вообще. Даже в тестах упадет без особых плясок с бубном, типа «синхронных промисов».
  • Loadable SSR может, и при этом поддерживает Suspense, те ничем не хуже React.Lazy.

В том числе loadable поддерживает красивые обертки над загрузкой библиотек (loadable.lib, можно увести moment.js в React renderProp), и помогает webpackу на стороне сервера собрать список использованных скриптов, стилей и ресурсов на префетч (чего сам webpack не очень умеет). В общем читайте официальную документацию.


SSR

В общем — все проблема в SSR. Для CSR (Client Side Render) сгодиться или React.lazy или маленький скрипт в 10 строчек — этого точно будет вполне достаточно, и подключать большую внешнюю библиотеку смысла не имеет. Но на сервере этого будет совсем не достаточно. И если вам SSR особо не нужен — дальше можно не читать. У вас нет проблем, которые надо долго и упорно решать.

SSR это боль. Я (в неком роде) один из маинтейнеров loadable-components и это просто жуть сколько багов вылезает из разных мест. И с каждым обновлением webpack прилетает еще больше.


SSR + CSS

Еще больший источник проблем при SSR — это CSS.
Если у вас Styled-components — это не так чтобы больно — они поставляются с transform-stream который сам добавит в конечный код что надо. Главное — должна быть одна версия SC везде, иначе фокус не получится. Буду честен — именно из-за этого ограничени он обычно и не получается.

C emotion попроще — их styled адаптер просто выплюнет