Comments 18
Метод hydrate учитывает, что данные для рендера могут подгружаться асинхронно? С этим будет из коробки работать Redux?
Понятно. prerender.io по прежнему в фаворитах. Он готовит страницу как браузер и может передавать её nginx прокси например для кеширования.
Это избавляет от жонглирования датастором и решает проблемы индексации. Google кстати в нём не нуждается и сам исполняет JS о чём prerender.io знает и ему лишний трафик не отдаёт.
Иначе двойной трафик получается. Вёрстку загрузи с датастором, потом бандл загрузи, датастор снова загрузи. И всё это время вместо favicon — кругляш загрузки.
Конечно время до показа первого экрана важная метрика, но велика плата за неё в виде дополнительного трафика который по сути не нужен клиенту.
Ок. Из api можно и правда дважды не грузить. Дважды загрузится только вёрстка. Вернее результат и бандл по которому он построен. Возможно это совсем крохотная разница, а излишки вёрстки в виде датастора в конце страницы можно удалять после его восстановления в redux. А может так статься, что вёрстка превысит размеры бандла, тогда это всё будет иметь смысл только на крайне медленных девайсах, на которых время JS рендера страницы критично.
Моя позиция связана скорее с той болью которая возникает когда приходится постоянно перезагружать дев сервер из-за застрявшего в серверном рендере чего-то и попутно следить, чтобы на сервере загрузились все данные из десятка методов API, а потом решать экзотические проблемы возникающие из-за того, что у тебя серверный рендер вообще есть, тем более дебажится он не так просто (я знаю про --inspect, но не панацея).
В общем мы были рады переходу на prerender.io, вдоволь налюбившись с рендером на сервере.
Идея рендера на сервере мне импонирует, но мне кажется она далека от своего завершения. Вместо того чтобы плеваться целиком страницей, стоит выделять важные части за которыми пришёл пользователь.
Я думаю врятли ему интересен в первую очередь хедер и подвал, а пришёл он скорее за конкретным контентом, будь то список товаров или статья. Так показав ему основной контент можно дальше загружать всё остальное. На это время пользователь занят поглощением контента за которым пришёл.
Вопросом магии и ловкости рук остаётся положение контента на странице, чтобы он не скаканул и не изменился после загрузки. А также особое меню для тех у кого отключен JS. Но это совсем другая история.
Зато мы получаем настоящую доступность и сокращение трафика даже для тех девайсов которые будут читать HTML в чистом виде. Ведь ради доступности всё, да?
Всем любви
P.S. разметка заранее сгенерированной странички занимает столько же места, сколько разметка, выплюнутая серверным рендером. Подскажите пожалуйста, где здесь дополнительный трафик в случае SSR?
index.html 1Mb
+bundle.js 1Mb
‣ CSR (SSR выключен)
index.html 10 kb
+bundle.js 1 Mb
Prerender.io следит за клиентом, и если рендер ему не нужен отдаёт только коротенький index.html и несколько js/css файлов для самостоятельного рендера на клиенте.
Возможно я чего то не понимаю и у вас есть LiveView на которых от рендера на сервере количество трафика не увеличилось, а скорость загрузки и работы сайта возросла.
Я бы посмотрел
Расскажите, в чём причина разных объёмов для index.html в вашем случае?
В моём случае серверный рендер прибавляет к весу страницы вёрстку. Эти +400кб прилетели конечно почти мгновенно, но похоже было больше на бутафорию.
Не всё жмётся (кликается) и не всё отображено так как должно быть (некоторые штуки хотят window. Так сложилось).
А потом прилетели 512кб ДжаваСкрипта и всё встало на свои места, но осадочек остался.
Я понимаю это мой частный случай и в ином пришлось бы ждать нескольких мегабайт скриптов, но это ещё более оттянуло бы момент нормальной работы кнопок.
И вот вся эта бутафория стоит батхерта синхронизации стора? Мне кажется штука крутая конечно, но требует доработки. В первую очередь Promise Midleware
, а во вторых акцента на <main></main>
/ <article></article>
секциях.
Нужно быть готовым к тому, что исходник будут читать читалки, боты или программисты c собакой, которые знают где ты живёшь, в терминале через cat
.
Не всё жмётся (кликается) и не всё отображено так как должно быть (некоторые штуки хотят window. Так сложилось).То есть у вас неконсистентность рендеринга между клиентом и сервером из-за неправильной реализации или технического долга.
И вот вся эта бутафория стоит батхерта синхронизации стора? Мне кажется штука крутая конечно, но требует доработки. В первую очередь Promise Midleware, а во вторых акцента наНе очень понял, что вы имеете ввиду про main/article. А про доработку: вам наверно подойдёт redux-saga вместе с redux-wait-for-action.
main / article секциях.
И я по-прежнему не понял, почему у вас отличается размер, и что же такого добавляет серверный рендер по сравнению со статической генерацией. Зачем отправлять лишнее, если это не нужно. Возможно проблема опять же из-за неправильной реализации? Ну тогда нет никакого смысла грешить на другие библиотеки.
Погорячился с двойными походами на API. Но вёрстку таки дважды загрузить придётся (+1 раз в качестве внутренностей bundle.js).
А favicon какой не отдавай, все равно такой будет пока бандлы грузятся.
window.initialState мы конечно сохраняли. И данные на сервере загружали. Но это сопряжено с временными затратами. После ещё одного потерянного дня на отлов багов серверного рендера, которые сложнее дебажить, мы перешли на prerender.io и довольны.
Возможно мы опять вернёмся к рендеру на сервере, но когда прогресс пройдётся кремниевыми сапогами по этому раздолью для деятельности. И он идёт, прогресс этот. Шаг ему на встречу React 16 и эта статья. Я верю в то, что сейчас является примером рутины через некоторое время сократится до единого флага в настройках.
Мне нравится, как это реализовано в ASP.NET Core: все фетчи, от которых зависит рендер страницы, добавляются с помощью addTask в общий список, и, по завершении выполнения всех записанных задач выполняется повторный рендеринг в строку и сохранение стора (и других сторонних переменных, если нужно).
Правда, чтобы работали методы, требующие авторизации, необходимо пробрасывать куки из запроса в фетч, использующийся при серверрендеринге, но зато благодаря этому полностью переиспользуется клиентский код, не надо думать о том, что надо запихнуть в стор.
К сожалению, ничего толковее https://github.com/aspnet/JavaScriptServices/blob/dev/README.md и шаблонного примера не знаю. Хоть самому писать :)
Имеются ввиду фетчи, загружающие данные для отрисовки страницы. Если просто использовать renderToString, то везде зарендерится, что данные загружаются, и всё. Обычно, чтобы такого не было, в стор принудительно заливают нужные данные. SpaServices же предлагает все такие фетчи в клиентском коде сохранить в отдельный список с помощью функции addTask, и, во время сервер-рендеринга, по выполнении всех этих фетчей renderToString выполняется повторно. Благодаря тому, что стор уже заполнен фетчами, второй вызов рендера уже генерирует страницу с данными. При этом, фактически, никакого специального серверного кода для подстановки данных писать не надо, просто надо не забывать кидать в общий список нужные фетчи.
Более того, с помощью пары обходных манёвров, таким же образом можно рендерить и данные, требующие авторизации (этого стандартный шаблон, к сожалению, не показывает).
Новшества серверного рендеринга в React 16