На Хабре есть несколько статей про изоморфность, которые на вопрос, что такое изоморфность, отвечают: “Изоморфность — это когда один и тот же код используют и на клиенте, и на сервере”. Да, это так, но не совсем понятно, для чего она вообще нужна. Собственно на этой почве и была рождена эта статья.
Фреймворки, используемые на стороне клиента — великолепны. Они могут помочь вам построить интерактивное и быстрое веб-приложение, которое будут обожать пользователи.
К сожалению, этот мир не идеален, и у них существует несколько недостатков. Один из главных — это скорость начальной загрузки.
Клиентские фреймворки получают очень маленький HTML файл, в котором подключены стили и пару скриптовых файлов, содержащий единственный div для монтирования приложения. Однако файл с JavaScript (bundle), содержащий даже минифицированый код зачастую очень большой и может достигать нескольких мегабайт.
Браузер должен запросить эти файлы и страница не будет показана пользователю, пока они оба не будут доставлены. Возможно еще потребуется запрос к api для получения начальных данных для самого приложения.
С другой стороны, традиционные веб сайты рендерят все на сервере и, как только HTML будет доставлен на клиентскую машину, пользователь увидит страницу. Более того, большинство веб серверов могут сделать рендер страницы быстрее, чем машина пользователя. В результате всего этого начальная загрузка страницы происходит очень быстро.
Спасительный React
Конечно же, вы бы хотели иметь преимущества обоих подходов. Быстрая начальная загрузка и быстрое и интерактивное приложение.
React может помочь с этим.
Вот как это работает. React имеет возможность отрендерить любой компонент, включая его данные на стороне сервера. То есть React на стороне сервера собирает дерево компонентов и превращает их в HTML каркас. Все это мы кладем в index.html, который отправиться пользователю. Также этот файл хранит в себе данные приложения для рендера на клиенте.
Как только HTML будет доставлен пользователю, браузер отобразит страничку. В это время все еще за кулисами будет подгружаться “тяжелый” файл JavaScript и, как только он загрузится, React сделает такие же расчеты для рендера локально. Умный алгоритм React понимает, что результат локального рендера соответствует тому, что уже было отображено на странице. В результате этого сравнения React не будет делать никаких изменений, а просто добавит необходимые обработчики событий к элементам.
В этом случае HTML файл, конечно, становиться немного “тяжелее”, но это просто не сравнить с размером файла, содержащего JavaScript. В результате HTML файл доставляется очень быстро.
Насколько это быстро? Разве мы не делаем почти одно и то же в двух местах? Да, но почти здесь ключевое слово.
Во первых — как только сервер ответит на запрос браузера, пользователь тут же увидит страничку.
Во вторых — React идентифицирует, что изменения в DOM ненужны, и поэтому не трогает его, а ведь это самая медленная часть рендеринга.
И в дополнение мы экономим один запрос, так как данные уже приняли участие в рендеринге на сервере и у нас нету необходимости еще раз их запрашивать.
- Начало загрузки страницы.
- HTML файл загружен, начало загрузки стилей и js.
- Загружены стили и пользователь уже видит красивую страничку, JS файл тем временем продолжает загружаться за кулисами (страничка безжизненна).
- JS файл загружен и реакт начинает рендер и сравнение виртуального DOM с отображенным.
- React понимает что различий нет и просто подключает обработчики событий к уже существующей разметке. Пользователю доступна полноценная страничка.
Возможно ли такое, что, пока JavaScript загружается, а страничка уже отображена, пользователь не сможет взаимодействовать с ней, потому что обработчики событий еще не прикреплены на страничку?
Теоретически это возможно, более того — так и есть. Однако, с помощью этой техники мы избегаем всех дорогостоящих операций (запросов) и, как результат, не только начальная скорость загрузки растет, но и прикрепление обработчиков событий происходит очень быстро.
В конечном счете ваше приложение будет всегда интерактивным и ни один из ваших пользователей не столкнется с проблемами, время загрузки страницы будет предельно маленьким, а пользователи бесконечно счастливыми!
Автор: piotrovskyi