Рассвет одностраничных приложений SPA
Модель одностраничных приложений The Single Page Application (SPA) набрала высокую популярность за последние несколько лет. Оно и понятно, этот подход даёт определённый профит по скорости, качеству обслуживания и создаёт основу для новых паттернов клиентской веб-разработки.
Как все, я думаю, прекрасно знают, SPA работает внутри браузера и не требует перезагрузки страницы во время использования.
Супер идея! Но, конечно, есть «подводные камни».
В числе самых распространённых случаев (если взять любой tutorial по react или vue) главная страница index.html содержит практически пустой HTML-файл с небольшим количеством глобальных для всего проекта ссылок CSS, JavaScript, шрифты и т.п.
И это проблема:
- В процессе первоначальный рендеринг пользователю придётся ждать загрузки всей кодовой базы и всех ресурсов (конечно, есть исключения, и можно реализовать динамическую подгрузку так называемых js / css чанков, но это отдельная история)
- Некоторые сканеры или парсеры, которые не умеют дожидаться подгрузки асинхронных запросов, просто увидят все страницы пустыми
Ну вы поняли:
<!DOCTYPE html>
<html>
<head>
<title>My first SPA app</title>
<script src="https://cdn_нашей_либы"></script>
</head>
<body>
<div id="app"></div>
<script>
...
бла бла бла, регистрация приложения
...
</script>
</body>
</html>
Рендеринг на стороне сервера SSR
В отличие от рендеринга на стороне клиента Client Side Rendering (CSR), который использует браузер для рендеринга всего содержимого приложения и получения данных с API и т.п., SSR использует… сервер. То есть, всё тот же рендеринг и получение данных обрабатывается сервером (NodeJS с помощью фреймворков Express, Next, Vue SSR, Nuxt или что там ещё...), а затем ответ с разметкой HTML, стилями, скриптами и полученными данными с API, отправляется браузеру.
Таким образом, вы можете использовать преимущества двух подходов: скорость / SEO и интерактивность / UX.
И так, всё же, что такое гидратация / регидратация?
Регидратация — это своего рода мост между SSR и CSR.
Существует такой показатель производительности веб страницы, как First Contentful Paint (FCP) — в приближённом переводе будет звучать как 'первая значимая отрисовка' — время, когда браузер начал отображать любой текст, изображения (включая фоновые). Это первые элементы, которые пользователь увидит на странице. Создав отчёт с помощью Lighthouse в Chrome, в закладке performance, вы сразу же увидите этот показатель.
Время, потраченное на генерацию содержимого на сервере и будет являться First Contentful Paint временем.
Сразу после этого, клиентский JavaScript начинает выполнение по созданию полноценного клиентского приложения (в большинстве случаев популярных фреймворков — virtual dom и binding интерфейса управления им).
В этот момент нет необходимости заново рендерить весь DOM на клиенте, но необходимо добавить недостающие события, методы, а в некоторых случаях и элементы, которые не рендерились на сервере.
Именно этот процесс и называется гидратацией или регидратацией (hydration / re-hydration). Немного более подробное описание можно найти в Руководстве Vue SSR (которое также есть на русском языке), но, соответственно, с некоторыми особенностями конкретно этого фреймворка.
Производительность
А вот в этой части появляются некоторые проблемы. Регидратация имеет определённый недостаток — это время до взаимодействия или Time to Interactive, которое можно увидеть во всё том же, известном нам, Lighthouse Chrome. Даже если вы организовали всё идеально на стороне сервера и страница имеет быструю первую отрисовку содержимого, пользователь сможет с ней взаимодействовать только после CSR регидратации, которая иногда выполняется довольно медленно. Это большой минус в части UX.
Ещё один показатель Max Potential First Input Delay — задержка первого ввода (англ. First input delay, FID) — одна из метрик производительности веб-страниц, которая описывает время, прошедшее с момента, когда пользователь впервые начал взаимодействовать с веб-страницей, т.е. нажал на ссылку, кнопку или использует элемент управления на основе JavaScript, до момента, когда веб-браузер может ответить на данное взаимодействие (определение с сайта mozilla).
И время регидратации напрямую влияет на этот показатель. И чем больше компонентов и логики на вашей странице — тем стремительнее увеличивается этот показатель.
Одним из способов решения является lazy load для hydration.
Примером реализации подобного подхода на Vue SSR / NuxtJS является пакет vue-lazy-hydration (в npm репозитории), который реализует выполнение гидратации только в видимой части viewport браузера и «гидрирует» остальную часть только в случае скролла страницы. Рекомендации по использованию этого пакета были найдены также на хабре в tutorial Создаем интернет-магазин на Nuxt.js, за что автору AntonMoskalchenko хочу выразить отдельную благодарность. В его статье были достигнуты показатели Performance в Lighthouse Chrome равные 100%.
bruian
Много опечаток в тексте. Если такое небрежное отношение к своей публикации, то и в остальных деталях оно будет проявляться. В том числе и по предметной области. Кстати говоря, по существу вопроса, ничего особо нового. Можно было не переводить тексты, а просто сбросить ссылку на википедию или документацию одного из фреймворков. Более того это уже мода какая-то прятаться за переводами, что-то вроде, — Если перевести любой текст, то и претензий нет. Не я же писал. Это он, я лишь перевёл. Вот и рвутся все переводить, что попало. Но среди иностранщины более чем много посредственного материала.
sattvadigit Автор
Спасибо за замечания насчёт ошибок! Исправил, а в итоге, установил расширение LanguageTool для хрома, отличная штука. Если обратите внимание на время публикации статьи, думаю ситуация немного прояснится.
Прошу прощения у всех читателей за этого, учёл.