Чому React Server Components — майбутнє веброзробки

Усім привіт. Мене звати Максим, і я займаюсь веброзробкою вже понад 10 років. Розпочинав працювати ще на PHP, потім Angular перший, а останні пʼять років — React.

Пишу собі на React і щасливий: робота нескладна, тому що вся бізнес-логіка практично завжди робиться на back-end, а я лише вивожу дані та реалізовую взаємодію з користувачем. До чого ж сильно я здивувався, коли побачив концепцію React Server Components. Аби було зрозуміло, про що я, додам скриншот коду з демо на цій презентації:

React Server Component — демо

У статті ми познайомимося з доволі новою концепцією — React Server Components. Проаналізуємо плюси та мінуси цього підходу, дізнаємося, для чого він був створений та побачимо, як на практиці можна його застосовувати. Матеріал розрахований на досвідчених розробників, які вже працюють з React і знайомі з базовою термінологією.

Я вже писав, що займаюсь розробкою понад 10 років, тому бачив і використовував різні архітектури та технології. І після всіх років розвитку технологій ми повернулися на початок — PHP. Хто писав цією мовою, то повинен впізнати код.

Ну й звісно, для тих, хто більше любить відеоформат, ознайомитися з концепцією можна у відео на моєму YouTube каналі.

Що таке серверні компоненти

Якщо узагальнено, то React Server Components — це нова архітектура розробки на React, що дозволяє створювати компоненти, які будуть виконуватися лише на сервері. Це дозволяє нам, наприклад, писати запити безпосередньо в базу даних.

Ви можете поцікавитися, як за допомогою JavaScript бібліотеки на клієнтській стороні, яка буде створена для полегшення розробки UI, можна робити запити в базу даних на сервері? До цього ми дійдемо в практичній частині.

Що реалізовують серверні компоненти:

  • Performance — рендеринг компонента або цілих сторінок відбувається на сервері, й клієнту повертається готовий HTML (а якщо бути точним, то не HTML). На цьому кроці треба розрізняти Server Side Rendering (SSR) і React Server Components (RSC).
  • Bundle size — зменшується розмір білда, оскільки компоненти та залежності не потрібно відправляти клієнту. Достатньо відправити лише результат його роботи.
  • Data fetch — всі дані отримуються на сервері, форматуються, і готовий результат повертається клієнту. Рішення CORS — як бонус.

Покращення продуктивності

Щоб зрозуміти, як покращується продуктивність під час використання React Server Components, потрібно розібратися, як працює серверний рендеринг. У мене є окрема стаття на DOU з порівнянням методів рендерингу в React.

Під час завантаження сторінки, створеної за допомогою React, за замовчуванням ми отримуємо практично порожню сторінку. Далі браузер виконує JS, запускається React, і він уже будує сторінку та за потреби витягує дані з сервера.

Приклад сторінки, створеної за допомогою React

Скрипт bundle.js містить усе необхідне для збірки та запуску застосунку, зокрема React, інші сторонні залежності та весь код, який ми написали.

Проблема цього підходу полягає в тому, що на виконання всіх операцій потрібен час. І поки це відбувається, користувач дивиться на порожній білий екран. Ця проблема погіршується з часом: кожна нова функція, яку ми написали, та кожна нова залежність додають ще більше кілобайт до нашого JavaScript пакету, збільшуючи час, за який користувач повинен сидіти та чекати.

Коли застосунок запустився і відрендерив щось користувачу, частіше за все додатково потрібні ще якісь дані з сервера. Ми вибираємо підхід до отримання цих даних, а точніше бібліотеку: Axios, React Query, SWR або Apollo. Клієнт робить запит на back-end, і ми знову очікуємо дані.

Візуалізувати можна це так:

Джерело

Покращити ситуацію може серверний рендеринг. Навіщо нам рендерити шаблон сторінки на клієнті після завантаження сторінки, якщо це можна зробити на сервері, що є потужнішим і зробить це швидше? Десь на цьому моменті заплакали розробники, які популяризували Single Page Applications (SPA), де основним бенефітом було розвантаження сервера завдяки перенесенню важкої роботи на клієнтів.

Сервер поверне готовий HTML, і користувач уже побачить сторінку. Паралельно браузер завантажує JS і виконує цікаву процедуру, яка називається hydration.

Після завантаження JavaScript-пакету React швидко пройде весь наш застосунок, будуючи віртуальний макет інтерфейсу та «вписуючи» його в реальний DOM, додаючи обробники подій, запускаючи будь-які ефекти й так далі. Тобто додаємо живої води в сухий HTML-шаблон.

Покращений підхід виглядає так:

Джерело

Ситуація вже краща, сторінка завантажується швидше, але ж користувачі приходять на сайт не заради порожнього шаблону — потрібні дані. То чому б отримання даних не перенести також на сервер?

Джерело

Оскільки сервер потужніший, дані лежать «ближче», та й кеш налаштований повинен бути — відповідь набагато швидша, користувач бачить готову сторінку. Разом із цим, у нас покращуються три вебметрики:

  • First Paint. Користувач більше не дивиться на порожній білий екран. Загальна структура сторінки вже відобразилася, але контент ще відсутній. Іноді це називається FCP (Перший Візуальний Зміст).
  • Content Paint. Тепер сторінка містить те, що цікавить користувача. Ми витягли дані з бази даних і відобразили їх у інтерфейсі. Іноді це називається LCP (Найбільший Змістовий Візуальний Зміст).
  • Page Interactive. React завантажений, і наш застосунок відображений або активований. Інтерактивні елементи тепер повністю реагують на дії користувача. Іноді це називається TTI (Час До Інтерактивності).

Ми уникнули «стрибків туди-сюди», коли сервер повертає JS, браузер рендерить застосунок і цей застосунок знову робить запит на бекенд, щоб отримати необхідні дані. Але як ми цього досягли? React із коробки цього не дозволяє. Потрібно використовувати додаткові фреймворки, типу Next.js, Gatsby, Remix або їм подібні. Додатково змінюється архітектура застосунку, оскільки ми прив’язуємось до реалізації фреймворку.

Недоліки підходу:

  • Ця стратегія працює лише на рівні адреси для компонентів, розташованих у самому верхньому рівні дерева компонентів, тобто сторінки. Ми не можемо використовувати цей підхід в будь-якому компоненті.
  • Кожний метафреймворк розробив свій власний підхід. У Next.js є свій спосіб, у Gatsby — інший, у Remix — ще один. Немає стандартизації.
  • Усі наші компоненти React завжди будуть гідратуватися (hydrate) на клієнтському боці, навіть коли цього не потрібно.

Команда розробників React роками працювала над розв’язання цього питання і прийшла до єдиного, офіційного, стандартизованого підходу під назвою React Server Components.

Зменшуємо розмір білда — bundle size

Робимо це після всіх оптимізацій із серверним рендерингом. Єдине що не змінилось — це етап Download JavaScript. Нам усе ще потрібно завантажити увесь JS, що потрібний і не потрібний на сторінці, аби користувач міг розпочати взаємодію із сайтом. Якщо нам не потрібен якийсь код або складна логіка компонента, а лише результат його роботи, чи маємо ми завантажувати цей код? У цьому випадку розбиття бандла на чанки за допомогою того ж самого lazy() не спрацює.

Download JavaScript-етап

Щоб бути більш наочним і зрозуміти проблему, розгляньмо наступний приклад. Вам на сторінці потрібно вивести форматовану дату та час. У JavaScript з коробки красивого рішення нема, а Intl.DateTimeFormat може не відповідати нашим вимогам. У цьому разі ми, як ліниві професійні розробники, шукаємо бібліотечку, яка це зробить. Знаходимо ідеальне рішення — Moment.js. Бібліотека актуальна, підтримується, на npmjs бачимо, що за тиждень завантажується 20.5 мільйонів разів — бінго! Додаємо в проєкт.

От усе було б ідеально, якби не її розмір. Якщо зайти на bundlephobia, можна здивуватися. Поточна версія у зжатому вигляді займає 72,1 КБ. І не факт, що tree-shaking у вашому випадку дозволить зменшити цей розмір.

Зазвичай у застосунках використовується не одна бібліотека, а десятки (якщо не сотні), і кожну з них потрібно зібрати до купи та надіслати клієнту, навіть якщо нам потрібен лише результат їхньої роботи, яким може бути одне слово чи кілька символів.

Коли однією з переваг використання React Server Components згадується зменшення Bundle size — це не про оптимізацію ваших функціональних компонентів, це про всі ці монструозні бібліотеки, які ми тягнемо в код і використовуємо у функціональних компонентах.

Отримання даних із сервера — data fetching

Щоб щось відобразити на сторінці, це щось потрібно отримати з сервера. Не завжди для запитів на бек-енд розробники використовують вбудовану функцію fetch(). Завдання зазвичай набагато складніші, тому й рішення потрібні складніші. У проєкт додаються різні Axios, SWR, React Query, Apollo або інші. Це означає додаткові кілобайти в бандл плюс свій підхід до роботи із запитами. На стороні бек-енд теж необхідні зміни, адже всі ці бібліотеки працюють з RESTfull, і їм потрібний endpoint, куди робити запит.

Якщо ми використовуємо серверні компоненти, можна робити запити в базу даних напряму! Звучить як космос, але таке вже можливо. Ось приклад такого компонента:

Водночас ніхто не забороняє в серверному компоненті використовувати будь-яку з раніше згадуваних бібліотек для отримування даних, наприклад з мікросервісу тим самим REST. Код цих бібліотек не додається в клієнтський бандл.

Оскільки код серверного компонента не повертається в браузер, то можна не хвилюватися про логіни, пароль до бази даних, вони клієнту не відправляться — лише результат.

Ну і як бонус — CORS. Обмеження на запити між різними доменами існує лише в браузері. Одним з рішень завжди було використання бек-енд як проксі. RSC вирішують це обмеження з коробки, адже вони і є цим беком.

Особливості серверних компонентів

Той, хто знайомий з React, може здивуватися синтаксису компонента зображеного вище. Функціональні компоненти не можуть бути асинхронними. Вони також не можуть опрацьовувати сайд-ефекти таким способом. А отримання даних з бази даних і є цим сайд-ефектом.

Ключова особливість RSC — вони не ререндеряться! UI згенерований на сервері один раз і відправлений клієнту, більше жодних мутацій.

Оскільки ререндерів нема, величезна частина React API недоступна на сервері. Стейт не змінюється, отже useState не можна використовувати. Ефекти також не можна використовувати, адже вони запускаються після рендера — з useEffect також прощаємось на сервері. Для багатьох це буде полегшенням, адже тепер можна працювати більше в NodeJS стилі, без хуків.

Серверні компоненти не мають доступу до APIs браузерів, наприклад LocalStorage.

Підсумуємо обмеження:

  • неможливо використовувати стейт і ефекти, ніяких useState, useEffect;
  • відсутність доступу до APIs браузера;
  • кастомні хуки, що використовують стейт або ефекти, також недоступні.

Коли використовувати серверні компоненти та нова термінологія

Використовуйте завжди та всюди, де це можливо. Не даремно ж Next.js зробив усі компоненти серверними за замовчуванням. Коли ж потрібно використовувати стейт, ефекти або APIs браузера — тоді уже клієнтські.

Ми вже знаємо про серверні компоненти, які запускаються на сервері. Як тоді називаються компоненти, що запускаються на клієнті? Ніколи не повірите — клієнтські компоненти (Client Components). Неймінг залишає бажати кращого.

Може здатися, що все просто та зрозуміло — серверні на сервері, а клієнтські в браузері на клієнті. Але ніт. Клієнтські також виконуються на сервері.

Рендериться на сервері

Рендериться на клієнті

Server Component

Так

Ні

Client Component

Так

Так

Практика

Концепція серверних компонентів звучить дуже складно. Зрозуміти її не так просто з першого разу, особливо, якщо ми все ще думаємо, що вона реалізується просто останньою версією React. Для повноцінного використання цієї архітектури нам потрібен Next.js, оскільки, згідно з офіційною документацією, саме цей фреймворк реалізовує серверні компоненти. Так, це виглядає дивно, що core-functionality React не реалізована в самому React безпосередньо.

Уточнюю: React Server Components усе ще не production-ready, тому їх використання є скоріше в навчальних цілях, щоб спільнота оцінила та протестувала. Це ж саме було свого часу зроблено й з хуками.

Хоч ця концепція і складна для розуміння, її реалізація, а точніше використання, є достатньо простою. Створімо перший серверний компонент.

  1. Створити застосунок за допомогою Next.js — npx create-next-app@latest
  2. Йдемо за пунктами, що пропонує генератор, і головне, що нам потрібно вибрати, — це пункт Would you like to use App Router? (recommended). Вказуємо yes.

В принципі й все. Тепер у нас є програма, згенерована за допомогою Next.js, де всі компоненти, за замовчуванням, є серверними.

Звісно, для повноцінної роботи з серверними компонентами треба ще вивчити фреймворк Next.js, а з ним і TypeScript бажано, але це вже можна вважати приємним бонусом.

Відкриємо файл src/app/page.tsx, викинемо з нього весь контент за замовчуванням і додамо лише Hello world. На цьому моменті я б рекомендував переглянути моє відео на YouTube про Серверні компоненти, там робота з кодом буде наочніша.

Цей компонент уже є серверним, і він не буде доданим в бандл. Тоді виникає питання: а як він додасться на сторінку? Якщо відкрити код сторінки в браузері, після запуску застосунку на 3000 порті, ми побачимо приблизно такий код (частину коду для наочності я видалив):

Окрім звичайного серверного рендерингу, в коді зʼявляється дещо новеньке — скрипти за викликом self.__next_f.push. Цього коду немає під час звичайного серверного рендерингу. Це і є тим результатом роботи React-компоненту, який нам потрібен. Усю решту React робить під капотом. Ми не повинні задумуватись над цим синтаксисом.

А як тепер створити Клієнтські компоненти? Для цього потрібно використати директиву `use client`, яка чимось схожа на уже нам знайому «use strict». Тобто створюємо звичайний компонент, але з додатковим рядком зверху:

Без директиви ми отримаємо таку помилку:

Оскільки пам’ятаємо, що всі компоненти за замовчуванням серверні та в них не можна використовувати стейт.

Додамо до проєкту moment.js і зіставимо розмір білда. Для порівняння створимо два ідентичних проєкти на Next.js, але один на основі App Router, тобто серверних компонентів, інший на основі Pages Router, тобто стандартні компоненти з SRR в обох випадках. Розмір фінальних JS-файлів візьмемо з поля First Load JS, що показує Next.js виконавши команду yarn build.

App Router, kb

Pages Router, kb

Порожній проєкт

80.5

79.6

З доданим Moment.js

80.5

99

Результат доволі наочний, хоч і додано було лише одну бібліотеку. На щастя, tree shaking зменшив фінальний розмір moment.js, але різниця все ще суттєва.

Висновки

Пункти, що не розглянуті в цій статті, але варті уваги:

  • Взаємодія клієнтських та серверних компонентів — згідно з документацією, можна в серверних використовувати клієнтські та навпаки. Тоді виникає питання: якщо серверні не ререндеряться, то що робити, коли вони є елементами клієнтських компонентів, де є стейт, і під час зміни якого викликається рендер?
  • Як дебажити серверні компоненти? console.log() у цьому випадку не допоможе, та й місце зупинки дебагера ніде поставити, адже компонента нема на клієнті, лише результат роботи.
  • Suspense та Streaming SSR архітектура — ідеальне доповнення до React Server Components.

Й до підсумків:

  • React Server Components (RSC) — це нова архітектура та підхід до розробки вебзастосунків за допомогою React.
  • Для використання всіх передових можливостей бібліотеки React потрібно вивчити та використовувати фреймворк Next.js;
  • Зʼявляється кардинально нова можливість — писати код для сервера. Отже, замовники зможуть перекласти частину роботи з back-end розробників front-end, тобто реалізацію частини бізнес-логіки. Чи будуть нам більше за це платити? Сумніваюсь. Але роботи буде більше однозначно.

React Server Components разом з Next.js дозволяють реалізувати інноваційні та потужні рішення для веброзробки. Хоча ця технологія ще не є готовою для використання в продуктивних проєктах, вона вже зараз відкриває нові можливості та розширює горизонти для майбутнього веброзробки.

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось6
До обраногоВ обраному1
LinkedIn

Найкращі коментарі пропустити

рендеринг компонента або цілих сторінок відбувається на сервері, й клієнту повертається готовий HTML

Вау. Ніфіга собі.

В мене вже давно складається враження що фронтенд рухається кудись не туди, коли появились SPA — це був як ковток свіжого повітря, vue/react/angular — прекрасний user та developer experience, бекенд розвантажений від зайвої нагрузки, можна плюватись жсонами. Команди розділились на фронт і бек, кожен знає свою область відповідальності. Чому ми тепер йдемо на сервер знову?

Невже не легше було вирішити ті проблеми які є в SPA, а по суті їх лише 3 — SEO, дублікація логіки валідації даних на фронтенді і бекенді та time to first meaningful paint?

Чи є ще якісь проблеми про які я не здогадуюсь, можливо хтось з фронтенд світу мені пояснить логіку цих змін?

Честно кажучи не зрозумів яку проблему це вирішує, здається що надуману. Як це взагалі до цього дійти якимі міркуваннями що «а давай я буду писати в реакт запити пряму в базу данних». WTF

Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Найбільше мені муляє розмазування відповідальності — тепер за базу не тільки бек відповідальний буде, а цілих 2 команди.

Це найбільший ризик: якщо не відповідальний хтось конкретно то не відповідальний ніхто.

Це значно важче в управлінні. Ну хіба що вести всю розробку на React і не мати розмазаної відповідальності.

А, і ще: в обов’язки FE інженерів не входить робота з БД і її розуміння. А тепер їм з неба звалиться можливість прямо використовувати БД, а вміння — не звалиться.

Я зараз звучу як дід що топить за дизельний пасат на механіці, але шось мені страшно.

Звісно, є розумники, які впораються. Та знаючи середню температуру по палаті, вважаю що мій скепсис доречний.

з бд навалювати прямо в компоненти? мабуть ж буде якийсь прошарок сервісів, які може розробляти людина з відповідними скілами...

Хочеться сказати, так це ж було вже, PHP 2.0. Хоча мені здається що сучасні фронти більше підготовлені до роботи з БД аніж ті люди які тоді тикали пальцями в PHP.

Я бачив купу бекенд сіньорів які в базах не мали дуже розуміння. Але висячі квері і оптимізація їх наше все.

Особливості серверних компонентів

Я б сказав не особливості, а обмеження.
Реакт: ми зробили вам контекст, провайдери і хуки useShoZavhodno, щоб було зручно!
Теж Реакт: ми додали вам серверні компоненти, щоб ви там не могли використовувати вище перелічене.

Працюю з Next-ом. На ділі це виливається у складнощі, типу: робота з локалізацією Lingui — пішов нафіг, ApolloProvider чи useQuery для GraphQL — пішов нафіг. Якщо перемикаєшся на ’use client’, то функцію generateMetadata() вже не може використовувати. Як додати title сторінки? Ставити Helmet. Так це і без серверних можна було.

Коротше, для розробника купа незручностей, а переваги для мене не очевидні. І це вже взагалі не про фронтенд. Які, дідько, запити в базу?

Я канєш вибачаюсь, але це все звучить як:
— ура, за допомогою нашої викрутки ми навчились ковирятись в зубах!

Розпочинав працювати ще на PHP

Лол, написав, начебто на паскалі починав. Я хз, що ти цим хотів сказати

І на паскалі писав) Але то уже навчання було.

Трохи занятно спостерігати, як Реакт наче сліпе котеня, намацує правильний шлях.
Може через 10-15 років буде там де Фрактал вже зараз.
1. Фронт рендерінг
2. Сервер рендерінг
==> Ви знаходитись з Реактом тут <==
3. Сервер та клієнт мають майже однакові БД та спілкуються діфами, замість велосипедування рест апі. Результат: Зменшився обєм коду, зменшився трафік, зросла швидкодія в рази.
4. Оскільки сервер та клієнт повністю знайшли спільну мову, тепер працюють магічні технології, коли база данних відслідковує зміни данних від яких залежать рендерені веб сторінки. Це дає змогу випльовувати вже готові рендерені сторінки за мілісекунди, якщо данні на них не змінились або змінились частково в базі.
5. Енжин навчився генерувати готові веб сторінки використовуючи лише модель данних в базі, що скоростило обєм роботи для круд аплікацій в десятки разів.

В підсумку, що реакт девелопери тільки не видумують, щоб захистити своє право писати в 10-100 разів більше коду, який значно гірше підтримується та повільніше працює. Вони вже інтуітивно розуміють, що там де вони зараз сидять, всидіти довго не зможуть. Але нормально подумати та скласти той весь пазл з фронт-бек-та базою разом не можуть.
Заважає інерційність, "а какжє так"© А вот так.

база данних відслідковує зміни данних від яких залежать рендерені веб сторінки.
Це дає змогу випльовувати вже готові рендерені сторінки за мілісекунди, якщо данні на них не змінились або змінились частково в базі.

Тобто на сервері ми тримаємо мільйони pre-rendered _user_view.html, мільярди умовних _transacton_row.html і ще сотні компонентів які можуть виглядати по різному в залежності від того хто їх переглядає та які параметри передані і робимо компайлинг цих темплейтів підписуючись на зміни в бд, можна посилання на проект з таким рендерингом?)

Тобто на сервері ми тримаємо мільйони pre-rendered _user_view.html, мільярди умовних _transacton_row.html і ще сотні компонентів які можуть виглядати по різному в залежності від того хто їх переглядає та які параметри передані

Звідки взялись мільйони та мільярди строрінок ? Можна конкретний а не сферичний приклад сайту ? Там точно не можна нічого оптимізувати ? Наприклад на доу буде макс 500 найбільш переглядаємих сторінок в данний момент, які поновлюються в кеші.

можна посилання на проект з таким рендерингом

Так, можна посилання,
dou.ua/forums/topic/44975

Але є один проєкт, який я вважаю доволі «дорослим». Це портал Fractal Platform. На сьогодні він моделює функціональність Jira, Slack, має свій блог. У нього інтегровані засоби для деплою та моніторингу програм Fractal Cloud, а також безліч звітів, портал для навчання та проходження іспитів студентами. Усе це навантажує складну систему прав на 12 розділів. Весь UI перекладено 7 мовами. Загальна доменна модель, за оцінками, перевищує 300-350 реляційних таблиць.
Із якою швидкістю має працювати такий застосунок? На це питання складно відповісти, але сьогодні це близько 100 мс на завантаження будь-якої сторінки. А на розігрітому кеші час падає до 12-15 мс.

Скрін i.imgur.com/uWqzZbx.jpg

Ну і як виглядає «Реакт майбутнього», а точніше його заміна.
В 450 рядків коду виписаний майже весь фронт-бекенд функціонал на сайт схожий на ютуб
(реєстрація канали підписки лайки коментарі завантаження відео)

fraplat.com/jupiter/UTube

І так, там теж є запити до бази данних прямо з коду, майже як зараз хочуть зробити в Реакт
github.com/...​UTube/UTubeApplication.cs

Але є ньюанс, не лише це має бути зроблено. А коли буде зроблено через 10-15 років все що потрібно, то нарешті застосунки будуть мати не 20 тис рядків коду на подібний сайт, а в ті самі 400 рядків коду. Та латенсі буде не 500 мс, а в районі 100-150 мс навіть без кешування сторінок. А з кешуванням 14 мс як на скріні вище.

Звідки взялись мільйони та мільярди строрінок ? Можна конкретний а не сферичний приклад сайту ?

Я це з нашого робочого проекту (myminifactory.com) взяв, мільйони користувачів, повідомлень між ними, сотні тисяч товарів які вони продають, сторінки виглядають по різному в залежності від ролей користувача (user/designer/maker/admin etc.), та від ще деяких факторів таких як чи юзер має підписку на того чи іншого дизайнера, чи має юзер підписку на сайт і т.п.

Виходить мені потрібно було б ці всі варіацій сторінок тримати на сервері? Скільки б це місця займало? x3-x5 від розміру бази данних? Скільки б процесорного часу тратилось на перерендеринг цього всього?

Так, можна посилання,

Потестував UTube проект — лайки не ставить, коментарі не відправляються, UX жахливий — немає клієнтської валідації, пробує відправити пустий коментар від чого збивається scroll position і вже невідомо що сталось поки не пролистаєш в низ, проте віддає сторінки дійсно швидко :)

Я це з нашого робочого проекту (myminifactory.com) взяв, мільйони користувачів

От з вашого робочого проєкту. Перша ж сторінка в анонімній вкладці. Відкрив раз, відкрив два, візуально вони однакові. (чи майже однакові?) То чому цей кейс, коли сторінка відкривається перший раз не кешувати?

мільйони користувачів, повідомлень між ними

З тих мільйонів 10% активні, 90% заходять може раз в тиждень, чи раз в місяць. То чому сторінки для 10% самих активних не кешувати? Далі повідомлення. Чому не кешувати повідомлення користувачів? Навіщо то все кожен раз перераховувати.
Тим паче, в связці фронт-бек база автоматично вміє відслідковувати що змінилося в реактивному стилі, це не коштує в розробці — нічого.

лайки не ставить, коментарі не відправляються

Тому що треба зареєструватися та залогінитися.
Гості не можуть лайкати відео. Коли реєструєшся там відкривається купа функціоналу.

немає клієнтської валідації

Тому що вона не потрібна на клієнті. Кейс коли юзер намагається відправити пустий коментар, це скільки таких випадків серед реальних користувачі ? 0,1% ?
Нехай в цьому випадку нагружає сервер валідацією, то не є проблема.

збивається scroll position

Це не важко зробити, ця задача є в беклозі та буде працювати не на рівні коду, а на рівні платформи.

UX жахливий

А цей myminifactory.com який обвішаний банерами та вспливаючими модальними вікнами наче сайт для дорослих з 90х це не жахливий UX ? )

То чому цей кейс, коли сторінка відкривається перший раз не кешувати?

там клієнтський рендеринг, а дані на бекенді закешовані

З тих мільйонів 10% активні, 90% заходять може раз в тиждень, чи раз в місяць. То чому сторінки для 10% самих активних не кешувати?

Дякую звичайно за аналіз нашої аудиторії та бази даних, але чому тоді 10% самих активних, чому не 90% самих пасивних які не міняються? Получається якщо самих активних закешувати то і ре-рендеринг в кеш потрібно буде часто робити)
Це я до того що кеш це добре, але лише там де він потрібний, якщо в нас немає проблеми з швидкістю відкриття аккаунта користувача то для чого його кешувати?

Тому що треба зареєструватися та залогінитися.

Я це зробив, аккаунт «Testing»

Кейс коли юзер намагається відправити пустий коментар, це скільки таких випадків серед реальних користувачі ? 0,1% ?

А кейс коли людина відправляє коментар більше ніж 255 символів теж ігноруємо? Пароль до 6 символів чи до 8? Писав би я веб апп для програмістів то можливо б і закрив на це очі, але ми пишемо сайти для людей яким потрібний хороший UX, моментальне реагування на введені дані та підказки.

А цей myminifactory.com який обвішаний банерами та вспливаючими модальними вікнами наче сайт для дорослих з 90х це не жахливий UX ? )

Тут згідний, але я до фронтенду відношення не маю)

Це я до того що кеш це добре, але лише там де він потрібний, якщо в нас немає проблеми з швидкістю відкриття аккаунта користувача то для чого його кешувати?

Там весь сайт, наче мене зновую підєднали до модему dial up який пакети передає через аналоговий телефон зі швідкістю 33,6 кбіт/сек. Ні одна сторінка не відкривається швидко.

Майже 3 секунди на завантаження сторінки. Мабуть ми маємо на увазі якісь різні кеші.
fraplat.com/...​143a1bce64d2ef2001029.png
Ваш кеш бігає на Плутон і назад, схоже.

Дякую звичайно за аналіз нашої аудиторії та бази даних, але чому тоді 10% самих активних, чому не 90% самих пасивних які не міняються?

То треба трохи в Computer Science, чому саме так. Теорія ймовірності.
Розподіл Парето. І оце ось все.

А кейс коли людина відправляє коментар більше ніж 255 символів теж ігноруємо? Пароль до 6 символів чи до 8? Писав би я веб апп для програмістів то можливо б і закрив на це очі, але ми пишемо сайти для людей яким потрібний хороший UX, моментальне реагування на введені дані та підказки.

Я все ще не бачу проблеми провалідувати це на сервері. Тим паче по секуріті, фронт валідація нічого не вартує, все одно потрібно дані всі перевіряти на сервері повторно.

Я це зробив, аккаунт «Testing»

Добре, я протестую. Але треба розуміти, що кількість рядків в проєкті, а саме 450 майже на все — суттєво не зміниться після виправлення багу. Тобто ми зараз більше займаємося QA тестуванням, а не парадигмою правильної зрозумілої архітектури.
UTube майже весь колись був написаний за добу з купою функціоналу
dou.ua/...​rums/topic/44975/#2694913

450 рядків в сучасному Реакт в вашому проєкті, мабуть тільки код одного банера більше займає. Звідси і читаємость коду, гнучкість коду, кількість багів в коді, щоб це не означало.

лайки не ставить, коментарі не відправляються
Я це зробив, аккаунт «Testing»

Доречі, цей баг щойно виправив.

Мене все частіше дивує платформа. Буває за звичкою ниряєш десь під капот, дебажити складну внутрішню логіку платформи, думаєш що там щось зламали останні коміти, а потім розумієш, що все що потрібно було .... підправити джисон.
Сказати що юзер з ролю User, має право писати в масив Likes в Security dimension.
І це все.

"Likes": {
        "Allow": {
          "Write": [
            "User"
          ]
        },

github.com/...​adc167074bf0cff457e6eb28e

Схоже саме і так буде виглядати справжнє програмування майбутнього.
Кілька сотень рядків красивого функціонального коду, плюс конфігурація бд в джисонах і складний сайт працює.

від чого збивається scroll position

Це я виправив, скрол тепер не збивається.
Доречі дякую за фідбек, цю штуку давно хотів виправити,
тож фідбек був гарний аргумент зробити це зараз.
Код мінявся на рівні платформи, тож всі існуючи проєкти на платформі
отримали це виправлення автоматично.

БубенДБ запахло. Глянув на скрін, схоже, то він і є

Честно кажучи не зрозумів яку проблему це вирішує, здається що надуману. Як це взагалі до цього дійти якимі міркуваннями що «а давай я буду писати в реакт запити пряму в базу данних». WTF

Коли Реакт появився, всі плювалися від того що в один файл знову запихнули CSS, HTML та JS. Я теж плювався. Всі роки і практики до цього розповідали як потрібно все розділяти. Але нічого, все чудово працює зараз.

Запити в БД пишуться і виконуються на сервері. Просто тепер не треба створювати напряму окремо сервіс який робитиме запити. По суті до CSS, HTML, JS додали ще і запити в БД, але так додали що цей код завжди виконується і залишається на сервері.

Рішення це все ще «canary» в Реакті, тому цікаво буде поспостерігати за розвитком.

Коли Реакт появився, всі плювалися від того що в один файл знову запихнули CSS, HTML та JS. Я теж плювався. Всі роки і практики до цього розповідали як потрібно все розділяти. Але нічого, все чудово працює зараз.

Запити в БД пишуться і виконуються на сервері. Просто тепер не треба створювати напряму окремо сервіс який робитиме запити. По суті до CSS, HTML, JS додали ще і запити в БД, але так додали що цей код завжди виконується і залишається на сервері.

Це погане рішення, яке згодом знову перепишуть.

щось таке уже було, років так 10 тому здається..

рендеринг компонента або цілих сторінок відбувається на сервері, й клієнту повертається готовий HTML

Вау. Ніфіга собі.

Господи, як же я вже стомився від реакту і цього всього... Але треба терпіти, бо ринок вакансій.

P.S. почав вивчати мобільну розробку (не React Native :D)

Можу сказати свій погляд зі сторони як затятого бекендера, який іноді щось пише на фронт для себе та продакшена та просто цікавиться різними технологіями для загального розвидку
— Vue 2 це найкраще що могло статися із фронтом. Так є деякі ідіотські штуки, але як на мене простіше та зрозуміліше то краще. От vue я засвоїв за 3 години до здачі проекту де було потрібно дуже швидко написати одну фронтендну фішку. React досі зрозуміти не можу хоча підлазив до нього із багатьох сторін.

React досі зрозуміти не можу хоча підлазив до нього із багатьох сторін.

Ті ж яйця, тільки в профіль, та з грьобаним JSX

От саме після JSX я послав його нафіг (благо фронт не мій хліб і в основному пишу адмін панельки щоб щось налаштувати).
Настільки спірна штука що в інеті вже дофіга статей написали щоб це виправдати і то декілька перечитав — не переконали

Завжди подобався Vue, але важко з роботою. Під час ковіду вдалось знайти, але якщо зараз щось шукати — буде важче ніж з реактом (хоча і конкуренція має бути менша).

На первом же скриншоте отличная возможность для sql инъекций. Что-то мне подсказывает, что среднестатистический фронтендер так и будет писать код доступа к бд, а другой среднестатистический фронтендер будет это ревьювить, не видеть проблемы и аппрувить

Проблеми з sql інʼєкціями в цьому підході нема. Думаєте у Facebook сидять ідіоти і не врахували це коли розробляли дану технологію. На цю тему в YouTube уже є багато відео.

Что будет если я вызову эту функцию вот таким образом?

export default function NoteList ({searchText}) {
const notes = db.query(
’SELECT * FROM notes WHERE title ilike $1 order by update_ad des’, [’%’ + searchText + ’%’]).rows;

....
}

Я вызываю вот так:

NoteList(’huita%; DELETE * FROM notes; DELETE * from users; DELETE * from everywhere; SELECT * FROM notes WHERE something like %test’)

Другими словами если пользователь введёт в searchText поле на ui ’huita%; DELETE * FROM notes; DELETE * from users; DELETE * from everywhere; SELECT * FROM notes WHERE something like %test’

Суть в том что в функции простая конкатенация строк делается и можно дописать в запрос все что хочешь. Или же db.query умеет это хендлить?

Там скоріш всього параметр проганяється через escape, тобто екранує спец символи.
Це не спрацює, або в фейсбуці дійсно сидять трейні.

Там все продумано, і проблем не буде — по перше. По друге, це лише приклад коли пишеться запит чисто на SQL. Зазвичай використовуєтсья якась ORM, та ж SupaBase все робить через сдк і працює норм.

Не знаю де ви там побачили можливість інєкції. Я там бачу хардкод юзернейму та паралю в коді, та ’select * from products’, тобто security та потенційно performance проблему. Та власне ніхто не заважає заюзати Kubernetes sicret-и, считати значення зі зіминних оточення або приперті файлу та нормальний модерновий ORM типу Sequelize де воно стане чимось типу const products = await Product.findAll(); Єдиний недолік, часто починаючи копіюють з таких статей як з туторіалів і воно просачується в бойовий код.

В мене вже давно складається враження що фронтенд рухається кудись не туди, коли появились SPA — це був як ковток свіжого повітря, vue/react/angular — прекрасний user та developer experience, бекенд розвантажений від зайвої нагрузки, можна плюватись жсонами. Команди розділились на фронт і бек, кожен знає свою область відповідальності. Чому ми тепер йдемо на сервер знову?

Невже не легше було вирішити ті проблеми які є в SPA, а по суті їх лише 3 — SEO, дублікація логіки валідації даних на фронтенді і бекенді та time to first meaningful paint?

Чи є ще якісь проблеми про які я не здогадуюсь, можливо хтось з фронтенд світу мені пояснить логіку цих змін?

Javascript дуже швидко працює на сервері, але повільно працює в браузері

Чого б це платформи на однакових рушіях працювали по різному? Сервер обслуговує явно не одного клієнта, а серверні ресурси не безкоштовні, на відміну від клієнтських, тому єдиний кейс — треба костиль, бо наляпали таке, що ресурси пересічного клієнта вже не справляються.

Команди розділились на фронт і бек, кожен знає свою область відповідальності. Чому ми тепер йдемо на сервер знову

Тому що це політичні лозунги для роздування штату, а не сухий виважений розрахунок.
В багатьох додатках цей поділ штучний. Ще можна зрозуміти, що бекендер ніколи не зможе гарно малювати дизайн, але коли бекенд і фронтенд все що роблять, перепаковують та валідують одній й тіж самі моделі данних до та після рест апішечки, дублюючи логіку — в цьому немає ніякої доцільності, крім ускладнення проєкту.

Невже не легше було вирішити ті проблеми які є в SPA, а по суті їх лише 3 — SEO, дублікація логіки валідації даних на фронтенді і бекенді та time to first meaningful paint?

Їх не можна вирішити.

— SEO, дублікація логіки валідації даних на фронтенді і бекенді та time to first meaningful paint?

Це все фігня, порівняно з тим що на кліент летить здоровенний бандл зі всім кодом апки та npm модулів, як пощастить, розбитий костилями на декілька чанків. Кожен сайт тащить свій бадл з повторюваним кодом, який ніяк не шариться між різними сайтами і кеш по суті не працює, бо навіть для свого SPA змінили один байт, збілдився бандл і кеш на клієнті вилетів в трубу.
Як на мене браузери мали з появою npm імплементувати підтримку завантаження npm модулів з пропріетарних CDN дзеркал з транспортом через вебсокети/http2 з пушем і підтримкою semver. На умовних 100мб кешу браузера, можна було б закешувати в gzip десятки тисяч npm модулів, при достатньо розумному алгоритмі який би враховував хоч би розмір і частоту запитів до модуля можна було б значно порізати запити до CDN. + якщо зберігати не всі версії модуля, а деякі + патчі як в гіті, то можна порізати і розмір необхідного кешу.

Як на мене браузери мали з появою npm імплементувати підтримку завантаження npm модулів з пропріетарних CDN дзеркал з транспортом через вебсокети/http2 з пушем і підтримкою semver.

Я прям от зараз прикидаю, як це класно було б відлагоджувати, коли у тебе працює, а у клієнта — ні, бо у нього не дотягує потрібний пакет або застаріла версія, або якийся локальний проксі, або фаза місяця не та :)

І це ви тільки верхівку айсбергу озвучили з того скільки проблем принесе підхід коли хтось спробує модулі білдити на клієнті. Пеший захід на сайт мабуть хвилин десять займе до того моменту як щось почне працювати не кажучи вже про типовий розмір папочки з залежностями.

коли хтось спробує модулі білдити на клієнті.

І що там білдити? TS в JS і так збілджений при публікації пакету, ніщо не заважає мати декілька точок входу в package.json і білдити в es5*. Conditional export і так зараз існує. Навіть якщо б пакет їх не мав, то можна мати окремі сервери які їх білдять під CDN по webhook з npm.

модулі білдити на клієнті

а що такє — білд проекта? чому він існує, з якої потреби?

Пеший захід на сайт мабуть хвилин десять займе

в загальному випадку — ні. бо буде тотальне lazy.
може просто не застали ті давні часи, коли масово використовувався RequireJS.

Я прям от зараз прикидаю, як це класно було б відлагоджувати, коли у тебе працює, а у клієнта — ні

Ой які ми ніжні :) Після обкурених IE і війни браузерів, де взагалі могло що завгодно не працювати на рівному місці, це все дрібниці.

ні, бо у нього не дотягує потрібний пакет

А як шрифти з гугл CDN не дотягує чи ще щось? Тоді так будь що може не дотягнути, якщо проблема в мережі, включаючи бандл апки, який 100500 раз намагається заново завантажуватись при обриві на мобільному девайсі, з’їдаючи трафік.

або застаріла версія

Чого б вона була застаріла? Те що у вас в package.json, те б браузер мав і дістати. Ми ж можемо вказати точну версію, якщо є підозри, що пакет порушує semver і має несумісність в патчі чи мінорній версії. Так само мати якийсь маніфест, де вказані версії залежностей апки, щоб не вказувати версії при імпорті в коді.

або якийся локальний проксі

Думаю там би здогадались відключити кеш для проксі, та і мова більше про пропрієтарну реалізацію чи розширення, тобто через спеціальні CDN і вони ж проксі якщо реалізувати в них upstream щоб мали ієрархічну структуру.

В мене теж склалось враження що вони не хотіли покращити розробку, а хотіли що б всі користувались їх хостингом, для цього вони і зробили RSC

React Server Components зробили люди з Facebook які і розробляють React. На скільки я знаю, вони хостинг не продають. Якщо помиляюсь то скиньте посилання на їхні тарифні плати. Next з Vercel (які і продають хостинг) перші (а може і не перші, але найпопулярніші) на практиці реалізували цей підхід.

1. Топ-3 контриб’ютори React — це три працівника Vercel (github.com/...​1-01&to=2023-11-23&type=c). І так, якщо пройтись по комітах, то саме вони розробляють серверні штуки.

2. Спеціально випускаються pinned canary релізи, що типу production-ready. Про приклад релізів із серверними компонентами і Next.js прямо пишеться у блозі — react.dev/...​2023/05/03/react-canaries.

3. І щоб заробити гроші, Next.js працює найкраще/тільки на інфраструктурі Vercel:

Next.js, unlike Remix or Astro, doesn’t have a way to self-host using serverless. You can run it as a Node application. This however doesn’t work the same way as it does on Vercel.

open-next.js.org

Так що певна закономірність між розробкою RSC і хостингом є :)

Сама по собі концепція — це повне повернення назад, та по факту PHP.

Все нове це добре забуте старе. На PHP ми не могли писати фронт. Треба було якийсь jQuery використовувати. Тут же Реакт все робить, безшовна звязка.

Сам сенс Angular, React та Vue — робити товстого клієнта, тобто максимально розвантажити сервер від того щоби він в цілому займався генерацію динамічного HTML — відповідно покращити як масштабування так і знизити кости на хостинг і т.д. ( насправді усе пішло від GWT та з рештою прийшло до Angular JS ) Це стало можливим за рахунок того, що більшість пристроїв у клієнта стали достатньо потужними щоб це робити. Та рендерінг на сервері, виглядає вже дуже дивним за концепцією, тим більше на Node. Та я розумію навіщо це потрібно — власне щоб зробити усіх full stack спеціалістами знову, тобто здешевшувати розробку та прискорювати її наскільки можливо. Більше ніяких реальних переваг нема, хоче це доволі суттєвий фактор для бізнесу, а саме він як відо і приймає рішення голосуючи по PHP — $.

Взагалі то концепція «товстого клієнта» уже відходить в минуле. Сервер то ми розвантажили, але проблеми з SEO та швидкістю відображення сторінок нікуди не ділися, а місцями тільки збільшились. Ніхто не викидає цей підхід в смітник, але для тих кому треба, щоб все було швидше і краще SEO, а вартість сервера не особливо хвилює, приходить на допомогу серверний рендеринг в усіх його реалізаціях (incremental та static).

Є купа способів по іншому зробити розкрутку на lending, ніж виїдати під генерацію HTML на сервері гігабайти пам’яті, та кіловати енергії і машинного часу на зборку сміття з усіх тих строк, обробляючи однаковим чином кожний HTTP Request. Ті самі robots.txt, CDN, кеши тощо. Точно вам скажу, рішуче ніякої переваги по швидкості динамічний контнетн на сервері не надає, зато навпаки здатен знищіти горизонтальне масштабування, швидкість завантаження окремих сторінок, та захмарно збільшити кости при великому навантаженні. Не кажучи вже про цілу низку інших проблем, чисто архітектурного характеру коли єдиний вузел в системі перевантажений саме генерацією динамічного HTML та є вузьким місцем в системі. Єдина справжня перевага server side rendering — ціна розробки, що не маловажний фактор насправді, подекуди найголовніший.

Якщо стільки мінусів, то навіщо придумали Next.js і активно розробляють його?

Бо дешево розробляти, а це дуже суттєвий плюс, частіше за усе це аргумент який перебиває усі інші. Бізнес голосує $, а це в світі комерції головний аргумент. Придбати сервери AWS чи Azure, GCP і тому подібні при не великих навантаженнях значно дешевше, а ніж команда дорогих розробників. Один фулстек це умовно $40-45 на годину, а backend+frontedn це вже $80-90. Це аргумент в якого дуже суттєвий ваговий коефіцієнт, доки ви не єдиноріг наприклад, де вже серверна, ціна навпаки дуже кусається бо там пули з 200-300 POD-ів і має сенс оптимізувати різні Rust там чи Go Lang чи С++ 23 і т.п.

Один фулстек це умовно $40-45 на годину, а backend+frontedn це вже $80-90.

Так дві людини зроблять більше, чим одна, бо дві голови це не одна + за умови вужчої спеціалізації, вони будуть продуктивнішими в своїх задачах

Та да постоянно читаю споры front с back, какого черта твой API делает все не так как я хочу. Full stack такими спорами не занят.

Не кажучи вже про цілу низку інших проблем, чисто архітектурного характеру коли єдиний вузел в системі перевантажений саме генерацією динамічного HTML та є вузьким місцем в системі.

Але є ньюанс
1. В статті є контр приклад з Moment.js, де серверу необхідно відправити на клієнт 72 кб. При серверному рендерінгу можна самому все порахувати, та відправити кілька байт як готовий результат.
2. Сервер часто генерує однакові сторінки, та має багато можливостей для кешування та обчислення що називається "не відходячи від каси"©. Перекладати однакову одноманітну роботу на тисячу пристроїв, як мінімум не схвалюють екологи, та виробники батарей для мобільних пристроїв.

На PHP ми не могли писати фронт. Треба було якийсь jQuery використовувати.

Але з тих часів з’вилась купа пристойних лайтових фреймворків.
Якось робив на riot.js — у нього компіляція темплейтів швидка, прямо на фронтенді. А данні інжектив у сам html.
Тобто по факту вийшло що позбавився і від формування бандла для фронтенду, і від SSR.
А це ще — не використував модифікацію js темплейтів перед відсиланням, аля метапрограмування.

Звісно цей підхід можна використовувати на любій екосистемі бекенду, а не тільки PHP.

То якщо React Server Components покликаний вирішити проблеми великих бандлів для SPA та роботи з данними — не здивуюсь якщо й самі важкі фронтенд фреймворки будуть замінюватись лайтовими.
Бо — навіщо тоді оце все накручувати, коли вказаний підхід робить все набагато простішим у розробці і сапорті?

Фреймворків то багато, але хто ж їх усі буде вчити. Тут уже всіма відомий і популярний Реакт (порівняйте кількість вакансій на нього і riot.js). Величезна екосистема, кача модулів та бібліотек. React Server Components дозволяють і оптимізувати бібліотеки. Як я писав уже в статті, якщо треба бібліотеку для фоматування дат, яка важить десятки кілобайт, то замість неї ми отримаємо уже відформатований рядок.

У будь-якому випадку RSC це ще одне рішення однієї з проблем на фронті. Хочете використовуєте, хочете — ні. Головне що є вибір.

Ну от ви і надали відповідь на головне питання чому технологія має місце на існування та долю ринку. Маркетинг від Meta який достатньо добрий, щоб продвинути продукт і екосистему на ринку, рівня не гірше Google чи Microsoft або NVidea. Developers Advocate дуже добре працюють тому React суттєво переважає як Angular так і Vue. А друге, це відповідно уніфікація та певна стандартизація необхідних знань, це якраз саме те, що прагне бізнес в першу чергу, менше витрат на розробку тобто собівартість і більший власний прибуток. Таким чином, усе будуть називати React так само як свого часу був шлях перейменування : Mocha, LiveScript та з рештою комерційна назва JavaScript. Щоб маркетингово підв’язатись до бренду — Java, показуючи, що це технологія якраз добавляє динаміку в Web сторінки (хоча реально з рештою мова призвела до ще більшої революції ніж Java). Хоча між мовами програмування із загального лише С подібний синтаксис.

Погоджуюсь. Маркетинг вирішує. У будь якому випадку все крутиться навколо грошей. І ми тут теж їх заробляємо, тому яка б не було «жахлива» технологія, якщо за неї платять то на ній ми всі радісно писатимемо.

треба ще обмазати це лямбдами тоді буде, при чому не FastCGI :)

Оскільки в нас нода на сервері то grpc підтримується. Але треба не забувати, що Next.js це лише фреймворк для реакта. Тому треба дивитися чи це релевантна для нього задача.

Якщо за JS на бекенді майбутнє, чому спільнота активно переписує тулзи для білда JS проектів на Rust?

також не дуже вірю в JS на back-end. Це ж йде в розріз основній ідеї JS як single threaded мови. Рендерінг на сервері по-суті вбиває сервер, тому що блокується єдиний потік, як результат, наприклад нові запити від клієнтів B, C не опрацьовуються, поки потік не звільниться від cpu intense рендерінгу якогось важкого компоненту клієнта A.

JS на беку — це ж не прибульці, щоб вірити в них чи ні. NodeJS уже цілу вічність працює на сервері і проблем нема. Для швидкої роботи не завжди потрібна багатопоточність. Рекомендую ознайомитися з JavaScript — будете дуже здивовані як він працює і чи блокування потоків взагалі існує.

рекомендую попрацювати з JS на back-end на high load сайтах, здивуєтесь наскільки багато проблем з рендерінгом, через однопоточність. Основна ідея яка поялгає в одному потоці та async nature — працює для опрацювання великої кількості I/O операцій, але не для cpu intense операцій.

Там не зовсім єдиний потік, там єдиний потік на один запит, так само як і для PHP наприклад. Та в цілому так, Node для високо навантажених проектів зазвичай виливається або в розширення на C++/Rust або в переписування на альтернативний бекенд Java і т.п. І питання зовсім навіть не в одному потоку просто, V8 обожнює жерти пам’ять. Те що добре для скіптової браузерної мови, зовсім не добре для сервера. JS намагались використовувати для сервера від самого початку його виникнення, та до V8 і Node з того не було взагалі нічого путнего, виходило гірше за PHP.

Там не зовсім єдиний потік, там єдиний потік на один запит, так само як і для PHP наприклад.

Всё ж таки ні, різниця принципова як працює node.js і php (fpm як дефолт, а не swoole чи якась екзотика).
Single threaded event loop (node.js) vs Process per connection (php).
Коли один процесс ноди не витягує трафік, то pm2 і запускають багато процесів з event loop, але від цього все одно не можна казати що node працює як php

Вже вони доволі давно приблизно однаково і працюють, бо в PHP дуже давно весь на FastCGI. Власне Node мали можливість одразу брати добре за рекомендувавщі себе рішення з інших технологій. По факту пул потоків та черга і асинхронний ввід-вивід включно з сокетами. Звісно є нюанси, та сенс той самий. Та як на мене це усе аксіома Ескобара, тому холіварити вважаю сенсу нема.

Власне Node мали можливість одразу брати добре за рекомендувавщі себе рішення з інших технологій.

Так вони i обрали — Reactor Pattern, пiдхiд на якому побудованi Nginx, Netty, нiчого принципово нового нe придумували.

бо в PHP дуже давно весь на FastCGI

алe async IO всe одно нeма в базовому runtime, та тримати 5K+ connections на одному сeрвeрi також можливостi нeма, бо трeба стiльки ж процecciв, навiть нe потокiв, нe кажучи вжe про пiдходи с event loop чи корутинами (Go).

BTW Власне існує навіть от таке reactphp.org

ви звичайно можете запустити cluster mode на node, скажімо по потоку на ядро. Але суті — це не міняє, Apache наприклад запускає тред для кожного запиту (звичайно поважаючи max limit в конфігі). А тому один запит не впливає на інший, в ноді cpu intense в одному треді безпосередньо блокують ядро, як результат — нічого не опрацьовується (навіть відповіді від I/O запитів).

Саму тому деякі великі компанії прийшли до висновку, що потрібно робити стрімінг — і не рендерити всю сторінку, але відрендирили частину — послали чанк і тд... але це не дуже працює з SEO, коли у пошукових гігантів є бютжет на те скільки ваша сторінка має генеруватись, для того щоб проіндексувати сайт по-максимуму.

Apache наприклад запускає тред для кожного запиту

Як сконфігурувати MPM, власне є евент httpd.apache.org/docs/2.4/mod/event.html

Це ж йде в розріз основній ідеї JS як single threaded мови.

і ця проблема вже не стоїть.
Бо, multithread на беку зазвичай був потрібен для I/O, а це в JS реалізовано асинхронними можливостями.
А там де треба реальний — теж купа всього вже є.

JS на беку зливається тільки тому що виконання коду з мови з динамічною типізацією не можна довести по швидкодії до виконання коду з мови з статичною типізацією.

потік не звільниться від cpu intense рендерінгу якогось важкого компоненту клієнта A.

рендерінг у текст зазвичай — 1. не важкий 2. кешується 3. легко масштабується

А сайтів з мілліонами запитів на рендерінг — небагато, щоб відчути проблеми.

Рендерінг на сервері по-суті вбиває сервер, тому що блокується єдиний потік

Ну і на скільки ж він там блокується? На 50мс? 150мс? Який жах. Ну інший клієнт отримає відповідь на 50мс пізніше, а балансир розкидає інших.
Це взагалі не проблема, тим більше для сервера, де UI не підвисне. Будь-яку синхронну задачу в JS можна написати асинхронно, щоб не блокувався івентлуп.

білдити проект — то не розробляти проект.
JVM чимало написана на C++ — і що, у Java кепське становище на бекенді, скоро будуть бекенди писати на С++?

скоро будуть бекенди писати на С++

Так вже часто, зазвичай через плугіни до node це робиться. Також Go та Rust буває використовують. Що правда ні до PHP, Python, Java, C# чи Node це нікуди не дотягує. Маркетингово це не дуже популярно, вискоко-навантажених проектів насправді не так вже і багато. Переважна кількість проектів це про TTM, а не навантаження і т.п.

та я про

тулзи для білда JS проектів на Rust

що немає значення на чому написаний транслятор, ВМ, енжин, make і т.і.

Реляційні бази ж теж не на SQL написані, то чого ж на ньому пишуть?

та хоч нехай тулзи для JS на асемблері пишуть — як це вплине на використання JS і асемблера?

вискоко-навантажених проектів насправді не так вже і багато

та я роками про це й кажу.

Але постійно у холіварах буде наведений аргумент про highload, про проблеми твітера з фейсбуком...

як жартую не один рік — частенько такє враження що на ДОУ тусовка програмістів MAANG :)

Тут комент думав писати, та походу бачу, що інформації на цілу статтю буде. Якось в офлайні тоді. Тут ще справа така — звісно клепати CRUD на Node чи PHP це доволі затребувано, та напевно не дуже то і прибуткове. Про нативні веб фреймверки, щось таке напишу напевно, треба тільки узгодити з PR менеджером, та не думаю, що тут буде якась занадто суттєва модерація. Практичні приклади для чого крім абстрактного мега перформансу, якого насправді може і не бути, та навіть гірше за Java виходити теж наведу.

Чим все це краще ніж просто взяти будь-який фреймворк що має шаблонізатор та додати alpine або stimulus на клієнті?

єдиний плюс що я бачу — екосистема ректу. Тобто бібліотеки, готові компоненти і т.д. Ну і популярність, компанії легше найти розробника на реакт ніж php/go/c#/kotlin фулл стека з знанням alpine/stimulis/jquery. Хоча я сам вже задумуюсь щоб з nextjs перейти як мінімум на remix, або на twig + stimulus

а шо з секуріті? креденшели для бази будуть доступні на фронті і їх можна витягнути через інспектор?

Звісно ні. Все залишається на беку. На клієнт лише результат роботи.

Серверний код не доставляється в клієнт, він працює окремо в рантаймі як nodejs, він буквально і є nodejs

Повіяло фулл-стеками...
Те й діло що розповідаю на інтерв’ю що давайте кожен буде займатись своєю справою,
і тут нате: ща ми в реакт припердолимо SQL і так зразу файно стане xD

Це капець, а не майбутнє.

От усе було б ідеально, якби не її розмір.

Ідеально було б не пхати third-party модулі в бандл з апкою. Розробка навіть від кеша з CDN деградувала...

Читаю і розумію, що давно забуте старе — це сьогодні нове :) eBay вже років як 5 використовує схожий стек через іхній marko.js — marko-v4.github.io/...​cs/server-side-rendering

Як на мене такий підхід повертаю нас до часів коли був php, sql запити і рендер розмітки але в сучасній обгортці,при такому підході чим гірші laravel (livewire) або rails(hotwire)?

Цілком погоджуюсь щодо PHP — дуже схоже. Різниця з laravel (це ж PHP фреймворк) і rails (якщо це про Ruby) в тому що тут є React і зручна звʼязка з фронтом. По суті вся сила інтерактивних компонентів на Реакті плюс зручна (безшовна) інтеграція з беком. PHP і Ruby — це лише бек. З ними я працював. От за livewire і hotwire не скажу, не чув. Напевно дуже популярні рішення у веброзробці.

Wicket, jsf. Це все вже проходили.

ця битва програна коли зьявився nodejs )))

Нажаль це не бекендерам вирішувати. Хто платить гроші то й і дає доступ. Не всі хочуть платити за двох хороших бек і фронт розробників, коли можна менше заплатити за такого собі фул стека.

Взяти zustand, і зробити таким методом youtu.be/OpMAH2hzKi8

Ну тому React server component все ще «canary» в межах Реакту. І ми як розробники тільки тестуємо це все і шукає проблеми і недоліки. Тому це майбутнє, а не сьогодення.

Отже, замовники зможуть перекласти частину роботи з back-end розробників front-end, тобто реалізацію частини бізнес-логіки. Чи будуть нам більше за це платити? Сумніваюсь. Але роботи буде більше однозначно.

Сумніваюсь що цей прогноз дійсний, вчора подивився що творить tldraw — ось де майбутнє front-end розробки, і це її явно знецінить і пришвидчить

Можете сказати що вони там таке творять і де подивитися?

Та як завжди — нейрошиза, коли сайти «кодять» в Paint.

Отже, замовники зможуть перекласти частину роботи з back-end розробників front-end, тобто реалізацію частини бізнес-логіки. Чи будуть нам більше за це платити? Сумніваюсь. Але роботи буде більше однозначно.

Сумніваюсь що цей прогноз дійсний, вчора подивився що творить tldraw — ось де майбутнє front-end розробки, і це її явно знецінить і пришвидчить

Підписатись на коментарі