tgoop.com/super_oleg_dev/133
Last Update:
Теперь фреймворк умеет в потоковый рендеринг, появились deferred экшены, и Await компонент для использования этих экшенов вместе с Suspense.
Большая часть работы сделана, проблемы как всегда в деталях.
Тут очередная хвала React Working Group, а именно гайду по миграции для авторов библиотек - https://github.com/reactwg/react-18/discussions/114 - этот гайд так или иначе затрагивает все проблемы с которыми я столкнулся.
Первое, tramvai использует defer
скрипты в head теге - в обычном случае как мне кажется они имеют все преимущества перед async
скриптами.
Но у нас потоковый рендер, и полная загрузка страницы откладывается до завершения стрима - это значит что и defer
скрипты не будут выполнены до этого момента!
А это полностью ломает преимущества Selective Hydration - новое API hydrateRoot
умеет гидрировать полученную разметку по частям, по мере поступления в потоке.
Стриминговый рендеринг я уже закрыл за флагом, за этим же флагом изменил добавление скриптов с параметром async
вместо defer
.
Следующее, мы не можем запускать гидрацию до того как Реакт отдал application shell, то есть если наши скрипты будут выполнены и запустят гидрацию пока <APP />
пустой, очевидно получим ошибку.
Это решается с помощью bootstrapScriptContent
/ bootstrapScripts
опций у метода renderToPipeableStream
, код для инициализации гидрации будет добавлен ровно в тот момент, когда на клиент передали основную часть разметки и можем начать гидрацию.
Далее, у нас могут быть lazy компоненты (loadable) внутри Suspense и Await.
Для корректной гидрации этих компонентов, их JS и CSS файлы надо инжектить в стрим, и делать это до инжекта разметки соответствующих компонентов, и эти ресурсы должны быть загружены блокирующим браузер образом.
CSS через link и так загружается синхронно, JS скрипт должен также быть загружен синхронно, без async
или defer
атрибутов.
В принципе с помощью ChunkExtractor
от loadable это решается без проблем, главное не задублировать уже отправленные ассеты. Добавил эту логику в стрим HtmlWritable
из пары постов выше.
Итоговый HTML для наглядности в отдельном посте.
Также еще нужно учесть SPA-переходы, сериализацию объекта Error, дедупликацию работы с Deferred объектами и другие небольшие нюансы.
BY SuperOleg dev notes

Share with your friend now:
tgoop.com/super_oleg_dev/133