Comments 37
Кажется, уже недостаточно просто оптимизировать сайт, чтобы весил меньше и быстрее работал. Теперь и сервер должен участвовать в работе js. В итоге что: пользователю с течением времени будет и этого мало, пожалуется, почему медленно грузится сайт(… Вообще, по-моему, будущее за такими проектами как Google Stadia, и пользователю будет достаточно грубо говоря одного экрана (притом еще желательно гибкого)
Полезной информации в статье минимум, по сути описание как сделать hello world, коих много.
Добавлю от себя вещи с которыми сталкивался когда делал SSR:
— нужно встроить код реакта внутрь html
пробовал взять шаблонизатор типа ejs и вставлять строку которую вернет renderToString внутрь, но это оказалось достаточно медленным при большой нагрузке, самый быстрый и простой вариант, что то типо
потом разрезаем это regexp на 2 части и храним в памяти и просто конкатим 2 с результатом renderToString
— что бы получить хороший прирост лучше юзать stream рендеринг
вариант выше работаеть и со стримами, работало примерно так
github.com/arshtepe/koa-render-view/blob/master/src/factory/PageStreamFactory.js
я юзал свой middleware для коа, но в итоге забросил это, когда сменил работу, а на новой уже мы юзаем www.gatsbyjs.org который оказался по удобнее велосипедостроения :)
P.s у нас недавно был митап на эту тему как мы юзаем gatsbyjs кому интересно могу скинуть ссылку в личку (не даю тут что бы не сказали что реклама :) )
Добавлю от себя вещи с которыми сталкивался когда делал SSR:
— нужно встроить код реакта внутрь html
пробовал взять шаблонизатор типа ejs и вставлять строку которую вернет renderToString внутрь, но это оказалось достаточно медленным при большой нагрузке, самый быстрый и простой вариант, что то типо
...
<body>
{replaceMe}
</body>
...
потом разрезаем это regexp на 2 части и храним в памяти и просто конкатим 2 с результатом renderToString
— что бы получить хороший прирост лучше юзать stream рендеринг
вариант выше работаеть и со стримами, работало примерно так
github.com/arshtepe/koa-render-view/blob/master/src/factory/PageStreamFactory.js
я юзал свой middleware для коа, но в итоге забросил это, когда сменил работу, а на новой уже мы юзаем www.gatsbyjs.org который оказался по удобнее велосипедостроения :)
P.s у нас недавно был митап на эту тему как мы юзаем gatsbyjs кому интересно могу скинуть ссылку в личку (не даю тут что бы не сказали что реклама :) )
Вы конечно молодцы, но какую пользу представляет ваша статья? Она не раскрывает вопрос рендера на стороне сервера
Зачем нужен запуск на нескольких ядрах, если все хозяйство в докере крутится? Логичнее было бы количество реплик увеличить.
Никто не мешает горизонтально масштабироваться. Почему логичнее иметь один поток, когда встроенный в ноду механизм позволяет иметь больше?
Когда читаю такие статьи, появляется чувство, что куда-то не туда пошла индустрия.
Вот у истоков были HTTP, HTML и простая понятная модель: клиент отправил запрос, сервер его обработал и отдал HTML. Клиент его отрендерил.
Потом понадобилось запускать снежинки на странице — окей, вот вам javascript. Понадобилось какие-то операции делать без перезагрузки страницы — получите XMLHttpRequest, а потом и библиотеки, которые сглаживают разницу в реализации в разных браузерах.
А потом зачем-то понадобилось все возвести в абсолют. И в итоге на клиенте появились фреймворки, которые устаревают быстрее, чем появляются, шаблонизация, слои абстракций. Стало принято кросс-компилировать код на одном языке в код на интерпретируемом(!) языке. Слой с магией переехал еще дальше от процессора — теперь это даже не браузер, а фреймворк.
И вот новая история. А давайте будем делать шаблонизацию на сервере, только не как раньше, а интерпретируемым языком, в который мы кросс-компилировали код на другом языке. И будем обрабатывать 20 запросов в секунду (40 с оптимизацией) вместо хотя бы пары тысяч. Но и на клиенте все оставим. А все ради того, чтобы показать пользователю 140 символов.
P.S. Я знаю, что под реакт на js пишут. Я больше про общее положение дел. И да, я не знаю, как ситуацию исправить.
Вот у истоков были HTTP, HTML и простая понятная модель: клиент отправил запрос, сервер его обработал и отдал HTML. Клиент его отрендерил.
Потом понадобилось запускать снежинки на странице — окей, вот вам javascript. Понадобилось какие-то операции делать без перезагрузки страницы — получите XMLHttpRequest, а потом и библиотеки, которые сглаживают разницу в реализации в разных браузерах.
А потом зачем-то понадобилось все возвести в абсолют. И в итоге на клиенте появились фреймворки, которые устаревают быстрее, чем появляются, шаблонизация, слои абстракций. Стало принято кросс-компилировать код на одном языке в код на интерпретируемом(!) языке. Слой с магией переехал еще дальше от процессора — теперь это даже не браузер, а фреймворк.
И вот новая история. А давайте будем делать шаблонизацию на сервере, только не как раньше, а интерпретируемым языком, в который мы кросс-компилировали код на другом языке. И будем обрабатывать 20 запросов в секунду (40 с оптимизацией) вместо хотя бы пары тысяч. Но и на клиенте все оставим. А все ради того, чтобы показать пользователю 140 символов.
P.S. Я знаю, что под реакт на js пишут. Я больше про общее положение дел. И да, я не знаю, как ситуацию исправить.
А потом зачем-то понадобилось все возвести в абсолют.
Так ну нет же. Просто «снежинки» стали сначала неизбежными (элементы разложить с правильными размерами — это тоже JS, особенно во времена, когда CSS объективно не мог разруливать комплексные случаи. Флексбокс не всегда с нами был), а потом и абсолютно неизбежными (из-за скорости разработки, да и «снежинки» всё так же никуда не деваются).
Потом подъехал пакетный менеджер со всеми своими свойствами пакетного менеджера (возьмите только самое-пресамое нужное, и всё равно получите зависимостей на несколько мегабайт), потом пошла борьба за 1st meaningful render, и тому подобное.
Хотите это всё выкинуть? Да пожалуйста, сайт времен web1.0 можно поднять за смешное количество времени (сильно быстрее, чем во времена web1.0). Только вот кому он будет нужен. А дальше — куда б вы не пошли, вас будет ждать либо «долго и дорого» (медленная разработка силами только тех людей, которые понимают, как без этого вашего реакта всё работает), либо же мегабайты js и борьба за первый значимый рендер. Ну и разрабатывая что-то достаточно сложное, вы неизбежно напишете свой собственный реакт или что-то подобное. С азартными играми и женщинами легкого поведения.
ЗЫ: Заметьте, кстати, что сейчас вот человек пишет про SSR, а в комментах ему тут же пишут «фу, надо было <мою любимую PWA за которую я везде топлю> брать» — это вот как раз то же самое, как если б кто-то написал про разработку без фреймворков, а ему стали бы предлагать реакт ;)
Я не против фреймворков или библиотек. Мне концепция рендеринга (тут я подразумаваю получение HTML или изменение DOM) на клиенте не нравится. Еще больше мне не нравится концепция эмуляции клиента на сервере для рендеринга на сервере кодом, который предназначен для клиента (дом, который построил Джек получается).
Я считаю, что веб мог развиваться в другом направлении. В ответ на запрос клиента сервер отдает HTML вполне функциональной страницы, которая уже содержит максимум информации, ведь большиинство страниц в вебе несут информацию, а не требуют действия от пользователя. Для действий спецификация HTML тоже содержит элементы и возможность отправить форму. А скрипты, которые загружаются на странице, постепенно улучшают её. Отправку формы могут заменить на ajax запрос и частичное обновление страницы и так далее.
И в данном случае все равно, с помощью фреймворка это сделано или без помощи. Даже лучше, если с помощью, будет и переиспользование накопленного опыта, и, возможно «дешево и быстро». А такие проблемы, как борьба за первый значимый рендер или индексация поисковиками решаются сами собой.
Я считаю, что веб мог развиваться в другом направлении. В ответ на запрос клиента сервер отдает HTML вполне функциональной страницы, которая уже содержит максимум информации, ведь большиинство страниц в вебе несут информацию, а не требуют действия от пользователя. Для действий спецификация HTML тоже содержит элементы и возможность отправить форму. А скрипты, которые загружаются на странице, постепенно улучшают её. Отправку формы могут заменить на ajax запрос и частичное обновление страницы и так далее.
И в данном случае все равно, с помощью фреймворка это сделано или без помощи. Даже лучше, если с помощью, будет и переиспользование накопленного опыта, и, возможно «дешево и быстро». А такие проблемы, как борьба за первый значимый рендер или индексация поисковиками решаются сами собой.
В ответ на запрос клиента сервер отдает HTML вполне функциональной страницы, которая уже содержит максимум информации, ведь большиинство страниц в вебе несут информацию, а не требуют действия от пользователя.
С любым комплексным отображением такой подход, возведенный в абсолют, немедленно превращается в тыкву. Надо график нарисовать? Ой, а давайте мы у клиента будем запрашивать размеры вьюпорта и прочие всякие dpi, а потом рисовать на сервере нечто под эти параметры (если кому-то стало смешно — то я такое монструозие в реальности видел, и да, работало оно очень грустно).
Вы никуда не денетесь от того, что существует масса моментов, когда легче рендерить, непосредственно располагая информацией о том, куда и как мы собственно рендерим.
И да, server-side rendering — это вот именно то, что вы и описали. Отдали HTML, подцепили к нему потом скрипты. То, что это «эмуляция клиента на сервере» (на самом деле не совсем) — избавляет от необходимости дважды писать код страницы, один раз для чисто серверной выдачи, второй раз для всяких «частичных обновлений» и т.п. И синхронизировать между собой.
С графиком хороший пример, принимается. Гугл таблицы на сервере тоже не особо отрендеришь, можно и другие примеры придумать. С другой стороны, страницу можно отрендерить на сервере, а график нарисовать на клиенте, каждой задаче свой подход.
Но в текущей ситуации я вижу две проблемы. Хорошим тоном для разработчика всегда было немного разбираться в том, что происходит на уровень ниже, чем тот уровень, с которым работаешь. Но слоев абстракции стало так много, что этот второй сверху уровень уже даже не javascript-движок, а фреймворки. В итоге получаем такие вопросы на стековерфлоу: Calculating sum of repeated elements in AngularJS ng-repeat. То есть, вопрос даже не в том, как посчитать сумму на javascript, а в том, как это сделать в ангуляре.
И вторая проблема, наверное, как следствие первой. Гмэил показывает список писем за 7 секунд, и это с ресурсами гугла. То ли на оптимизацию забили, то ли не осилили. Да, скорость разработки важнее скорости работы, но это стало нормой даже для успешных продуктов, а рендеринг на клиенте поощряет такой подход. И мне кажется, что перенос рендеринга на сервер так, как это описано в статье — это такой последний отчаянный шаг ускорить приложение не меняя концепцию.
Но в текущей ситуации я вижу две проблемы. Хорошим тоном для разработчика всегда было немного разбираться в том, что происходит на уровень ниже, чем тот уровень, с которым работаешь. Но слоев абстракции стало так много, что этот второй сверху уровень уже даже не javascript-движок, а фреймворки. В итоге получаем такие вопросы на стековерфлоу: Calculating sum of repeated elements in AngularJS ng-repeat. То есть, вопрос даже не в том, как посчитать сумму на javascript, а в том, как это сделать в ангуляре.
И вторая проблема, наверное, как следствие первой. Гмэил показывает список писем за 7 секунд, и это с ресурсами гугла. То ли на оптимизацию забили, то ли не осилили. Да, скорость разработки важнее скорости работы, но это стало нормой даже для успешных продуктов, а рендеринг на клиенте поощряет такой подход. И мне кажется, что перенос рендеринга на сервер так, как это описано в статье — это такой последний отчаянный шаг ускорить приложение не меняя концепцию.
Понадобилось какие-то операции делать без перезагрузки страницы — получите XMLHttpRequest, а потом и библиотеки, которые сглаживают разницу в реализации в разных браузерах.
Примерно в этот момент появилась необходимость дублировать серверный шаблонизатор клиентским. Причем тестировать нужно оба. Причем у них сильно разный синтаксис и это создает лишнюю ментальную нагрузку на разработчика. Потом появилась необходимость поддержки API для мобильных устройств и отдача JS/XML вместо отрендеренного HTML. И код приходилось писать уже местами не дважды, а трижды.
Возможно так будет понятнее откуда
потом зачем-то понадобилось все возвести в абсолют
и выделить в системе слои по функциональному принципу, а не по принципу «надо пользователю отдать js-файлик, значит будем писать в js-файлике».
Какая у людей интересная жизнь!!!
Простой html отдавать не круто, давайте накрутим кучу js. Js на клиенте тормозит, давайте будем выполнять js на сервере, а клиенту отдавать html. )))
Какой следующий шаг?
Простой html отдавать не круто, давайте накрутим кучу js. Js на клиенте тормозит, давайте будем выполнять js на сервере, а клиенту отдавать html. )))
Какой следующий шаг?
Чем вам не подошёл f/w Next.js с готовыми решениями?
Не могли бы поделиться вашим бойлерплейтом? Находил на гитхабе, но там староваты с устаревшими модулями и костылями
Не могли бы поделиться вашим бойлерплейтом? Находил на гитхабе, но там староваты с устаревшими модулями и костылями
Посмотрите этот, на нем несколько проектов написал github.com/hazratgs/react-app-private
PHP — php тормозит, давайте ему APC, eAcceleator и opCode под капот, и заодно давайте все повторяемые блоки в memcached засунем.
JavaScript — какой такой APC?
React — какой такой memcached?
JavaScript — какой такой APC?
React — какой такой memcached?
А зачем JS-у акселераторы, если эти решения нужны только из-за специфичности PHP. Как с memcahed связан с React?
PHP — всеми третируемый язык, который не прячет свои недостатки, и позволяет их решать дедовскими методами.
JS — заместо байткода нам выдали wasm. Спасибо конечно, но современную проблему JavaScripта, в виде бандла на 20 мегабайт, это не решает.
React — особенно хорош на сервер сайде. На клиенте он то хорош, но для серверного окружения, где надо что-то рендерить для 100 клиентов одновременно… вот как раз кеширования и не хватает. А оно примерно не возможно с текущей моделью работы Реакта. Точнее — очень даже возможно(rapscallion, hypernova), но почему-то «настоящий реакт» этого никаким образом сделать не помогает.
JS — заместо байткода нам выдали wasm. Спасибо конечно, но современную проблему JavaScripта, в виде бандла на 20 мегабайт, это не решает.
React — особенно хорош на сервер сайде. На клиенте он то хорош, но для серверного окружения, где надо что-то рендерить для 100 клиентов одновременно… вот как раз кеширования и не хватает. А оно примерно не возможно с текущей моделью работы Реакта. Точнее — очень даже возможно(rapscallion, hypernova), но почему-то «настоящий реакт» этого никаким образом сделать не помогает.
Тему совсе не раскрыли, поэтому у меня несколько вопросов :)
1) Зачем вообще использовать node.js фреймворки? Там серверного кода то один модуль, который просто в ответ на запрос отдаёт renderToString со страничкой.
2) С многопоточностью тоже непонятно. У вас же докер, можно настроить репликацию.
3) LazyLoad использовали или у вас всё в одном модуле?
4) Пробовали использовать renderToNodeStream?
5) Как добавляете мета-теги на серверной стороне (если добавляете конечно)? Helmet или вручную.
1) Зачем вообще использовать node.js фреймворки? Там серверного кода то один модуль, который просто в ответ на запрос отдаёт renderToString со страничкой.
2) С многопоточностью тоже непонятно. У вас же докер, можно настроить репликацию.
3) LazyLoad использовали или у вас всё в одном модуле?
4) Пробовали использовать renderToNodeStream?
5) Как добавляете мета-теги на серверной стороне (если добавляете конечно)? Helmet или вручную.
1) не мало кода вокруг, перформанс нода против коа почти не страдает
2) мы так и сделали, не что при этом не мешает спавнить потоки, странная история пладить тонны инстансов с 1 поток
3) использовали
4) нет, клиенту отвечает пайтон
5) обвязка пока еще старая, в ней все добавляется
2) мы так и сделали, не что при этом не мешает спавнить потоки, странная история пладить тонны инстансов с 1 поток
3) использовали
4) нет, клиенту отвечает пайтон
5) обвязка пока еще старая, в ней все добавляется
4) нет, клиенту отвечает пайтон
а вот это уже интересно. renderToNodeStream — это как renderToString, только возвращает не всё сразу, а в виде потока. У вас и renderToString делает пайтон? Или на каком он у вас этапе?
У меня есть вопрос. Что нас должно впечатлить в этой статье? Серверный рендеринг очень древняя технология. PHP, C#, Pyton, Java, Node.js. Все давно используют серверный рендеринг. В чем технический шаг вперед при изпользовании React? Как по мне, дополнительная реализация серверного рендеринга в для фронтенд библитеки это признак тупика в ее развитии.
Прелесть изоморфного реакта в том, что один и тот же код работает на клиенте и сервере и можно безболезненно SPA на реакте сделать доступной для поисковых роботов.
Зачем SPA делать доступными для поисковых роботов? Это же application… приложение, т.е. то что на других платформах скачивается и устанавливается.
Для seo и роботов делать и оптимизировать нужно страницу входа в это приложение и/или лендинг — который рекламирует это приложение и рассказывает про него.
Для seo и роботов делать и оптимизировать нужно страницу входа в это приложение и/или лендинг — который рекламирует это приложение и рассказывает про него.
А зачем промежуточное звено, которое ходит за данными, отправляет их на отрисовку и отдает клиенту? Мне кажется было бы проще сразу писать на node.js фронт сервер с SSR, который умеет ходить за данными в API.
Все страницы на реакте с SSR-ом. Но обвзяка не реактовая (хедер, футер)
Sign up to leave a comment.
Как мы пилили серверный рендеринг и что из этого вышло