Мне по большей части нравится новое кэширование и фокус на нём. Да, оно не лишено недостатков, но так как это одна из ключевых фичей нового App Router, думаю в будущем нас ждут только улучшения.
Ух, next v15 вас удивит, но практически все кеширования будут отключены по умолчанию. Лично я этому рад, потому что мы кешировали достаточно много информации, а реализации next-а оказалась хуже нашей, но при этом мешала и просто работала поверх (ещё и сборка в несколько процессов портила идеальное кеширование нашей реализацией, посмотрим как они это обойдут в новой версии). Кеширование ломает гибкость и специфики, поэтому это должно быть решением команд (хотя бы обычный флаг).
Они как я понимаю откажутся от сильного кеширования и скажут, что PPR решит все ваши проблемы.
Проблема серверных компонентов на мой взгляд только в том, что у них сильно отличается ментальная модель от того, к чему привыкло большинство разработчиков
Я бы главным назвал необходимость использовать prop drilling. Когда у тебя десятки уровней вложенности - это ужас (а то как извращаются библиотеки переводов чтоб найти решения - ух... [но я и сам в обходе немного так наделал]).
сломана вставка CSS стилей ... Они починили это только в 14.2.
Я в 14.3.1 поймал... Когда компонент рендерится только на клиенте. Ну а в первых версиях вообще часто ломалось, да.
Да, есть cache из Реакт, но это работает только как аналог Memoization из Next.js. Есть аналог для Data Cache в виде функции unstable_cache
cache реакта отлично себя показывает. unstable_cache лучше тем, что он кеширует поверх процессов, ещё и сохраняет инфу между пересборками (как и fetch, это в целом под капотом одна функция, которую можно реализовать по-своему - cacheHandler)
И вот здесь publishAction станет API роутом, а в form передастся url этого API. Соответственно при отправке формы не нужно будет ждать пока загрузится её логика
А что в изменениях next.js нравится и упростило написание кода (именно next.js, т.е. навигация в app router, новые роуты и абстракции, кеширование и т.п.)?
Всё ещё испытываю очень спорные эмоции и хочу понять в чём улучшило жизнь другим (или ухудшило, тоже очень интересно, особенно если решу писать по нему ещё статьи).
Можно сказать, что nextjs исполняется в четырёх средах: сервер, клиент, edge и сборка. Сам он для конфигурации предлагает использовать env файлы и два вида переменок - серверные и публичные (начинаются с NEXT_PUBLIC_ и будут встроены в код во время сборки).
Для edge рантайма и клиента приходится использовать публичные переменные. А это в свою очередь означает, что приложение будет полностью зафиксировано под окружение в момент сборки.
Пакет же даёт возможность настроить файлы конфигураций в стиле, схожем с пакетом config, под каждую среду и использовать их в нужных местах в нужном окружении.
Layout просто совсем непрактичная штука и подходит для очень ограниченного списка проектов.
Мои взгляды, что на layout нужно забивать и, если там используются контексты/получение пути/разных данных страницы - кидать ошибку. Применение контекстов можно посмотреть в библиотеке next-translation, где я рекомендую инициализировать провайдер на каждой странице.
Тоже плохо с неймингом у команды реакта получилось, что серверные компоненты назвали серверными. Безумное количество раз слышал странные выводы исходя из этого деления (серверные/клиентские). По факту это скорее static components/assembler components.
Что-то вроде "Вся динамика должна быть на клиенте. Клиентские компоненты не хуже серверных и с ними не будет потерь в оптимизации". Не знаю, зачем с такими взглядами вообще их завезли.
Ещё есть проблема с Layout-ом, которую я в PR не решил - он не ререндерится и если использовать этот геттер внутри лайаута - он не обновится при переходе между страниц. Тут нужно просто блочить всю динамику внутри лайаута, но пока next.js так не умеет.
В такой ситуации думаю лучше создать провайдер с клиентским и серверным контекстом и передавать в него пользователя.
Серверные компоненты конечно создали поле для костылей ?
Но этот набор, как я вижу, переключает приложение на SSR. Так как локаль читает для каждого запроса из созданных в мидлваре кукисов. Но интересная связка, спасибо, что поделились!
P.S. Грустно конечно, что команда реакта сказала что не будет заниматься серверными контекстами и это будет ответственность фреймворков, а команда некста, что не видит в них смысла.
Вот это поделился решением ? Спасибо, что написали, добавил ссылку в конец статьи!
Да, он только для App Router. Если точнее, то по подходам он под серверные компоненты реакта, просто насколько я знаю сейчас их полноценно поддерживает только Next.js.
Вероятно с релизом 19й версии подтянутся Remix и остальные, возможно тогда решение адаптирую и под другие фреймворки.
В случае дефолтного обработчика кеша не в Vercel - всё сохраняется в файловой системе (насколько знаю без лимитов);
В случае дефолтного в Vercel - общий лимит не знаю (скорее всего его нет), но есть лимит в 2мБ на запрос. Весьма вероятно в будущем кеширование в Vercel сделают платным;
Да. Обычно так делают чтобы разделить логику - бывают компоненты только меняют состояние и им не важно какое состояние сейчас, а другие наоборот только читают.
Первым вообще не нужно ререндериться, поэтому им не нужно зависеть от UserDeviceContext.
А вторым не нужно знать логику смены состояния - небольшой бонус в виде деления ответственности.
А чем Вам не нравится режим серверного рендеринга?
Маркетинговый сервис, где в общем-то учитываем потери даже на доли секунды. Ну и следствие маркетингового - нет критической завязки на конкретного клиента, мобильная и десктопная версия делаются одинаковые (чтоб лишний раз роботов не пугать).
На самом деле по скорости, особенно с серверными компонентами - показывает себя хорошо. Ещё в новой версии ISR работает достаточно удобно и задача обновить 1000 страниц звучит как вполне простая - вместо ревалидации массива из 1000 страниц, вызывая метод для каждой, можно сказать - пересобери все страницы, которые использовали таг posts-javascript и он это в фоне сделает (https://nextjs.org/docs/app/api-reference/functions/revalidateTag).
Спасибо за подробный ответ!
Ух, next v15 вас удивит, но практически все кеширования будут отключены по умолчанию. Лично я этому рад, потому что мы кешировали достаточно много информации, а реализации next-а оказалась хуже нашей, но при этом мешала и просто работала поверх (ещё и сборка в несколько процессов портила идеальное кеширование нашей реализацией, посмотрим как они это обойдут в новой версии). Кеширование ломает гибкость и специфики, поэтому это должно быть решением команд (хотя бы обычный флаг).
Они как я понимаю откажутся от сильного кеширования и скажут, что PPR решит все ваши проблемы.
Я бы главным назвал необходимость использовать prop drilling. Когда у тебя десятки уровней вложенности - это ужас (а то как извращаются библиотеки переводов чтоб найти решения - ух... [но я и сам в обходе немного так наделал]).
Я в 14.3.1 поймал... Когда компонент рендерится только на клиенте. Ну а в первых версиях вообще часто ломалось, да.
cache реакта отлично себя показывает. unstable_cache лучше тем, что он кеширует поверх процессов, ещё и сохраняет инфу между пересборками (как и fetch, это в целом под капотом одна функция, которую можно реализовать по-своему - cacheHandler)
Server action (решал здесь, кстати, стоит переводить или нет). Честно говоря под катом этого не разбирался, но в целом это про:
const publishAction = (data) => {
"use server"
// ...
}
// ...
<form action={publishAction}>
// ...
И вот здесь
publishAction
станет API роутом, а в form передастся url этого API. Соответственно при отправке формы не нужно будет ждать пока загрузится её логикаПо второму дню статьи уже не будет, поэтому просто оставлю это здесь (для тебя, мой дорогой редкий читатель! ?)
Часть Windows построена на React Native!
После настройки:
const config = useRuntimeConfig();
Есть вполне достаточный пример - https://github.com/vordgi/nimpl-config/blob/main/example. Ну и дока, конечно, тоже есть - https://nimpl.tech/config/usage)
А что в изменениях next.js нравится и упростило написание кода (именно next.js, т.е. навигация в app router, новые роуты и абстракции, кеширование и т.п.)?
Всё ещё испытываю очень спорные эмоции и хочу понять в чём улучшило жизнь другим (или ухудшило, тоже очень интересно, особенно если решу писать по нему ещё статьи).
(О своих итогах писал в первую очередь в статье про App Router и статье про кеширование в next.js)
Можно сказать, что nextjs исполняется в четырёх средах: сервер, клиент, edge и сборка. Сам он для конфигурации предлагает использовать env файлы и два вида переменок - серверные и публичные (начинаются с NEXT_PUBLIC_ и будут встроены в код во время сборки).
Для edge рантайма и клиента приходится использовать публичные переменные. А это в свою очередь означает, что приложение будет полностью зафиксировано под окружение в момент сборки.
Пакет же даёт возможность настроить файлы конфигураций в стиле, схожем с пакетом config, под каждую среду и использовать их в нужных местах в нужном окружении.
В общем интересный эксперимент как можно иначе конфигурировать fullstack приложение.
(Думаю [когда-нибудь, [надеюсь [и мне хочется верить]]], что я допишу по нему статью)
По идее, именно в плане настройки, между pages и app роутерами отличий в настройке кеширования нет (https://nextjs.org/docs/pages/building-your-application/deploying#configuring-caching). То есть пакет должен работать и с pages router.
Единственное, что в версиях до 13 эта настройка была под другими ключами, в experimental
Наконец дошли руки доделать пример с таким провайдером
https://github.com/vordgi/next-impl-getters/tree/main/examples/isomorphic-context
Layout просто совсем непрактичная штука и подходит для очень ограниченного списка проектов.
Мои взгляды, что на layout нужно забивать и, если там используются контексты/получение пути/разных данных страницы - кидать ошибку. Применение контекстов можно посмотреть в библиотеке next-translation, где я рекомендую инициализировать провайдер на каждой странице.
А вообще Next.js собирает страницу сверху вниз, он проходит сегмент за сегментом собирая абстракции на текущем уровне, но слои собираются отдельно от страниц. Там страшная логика, но основное лежит здесь: https://github.com/vercel/next.js/blob/79b7cb5f075c26698bc2cb8a569cda8a6e3b49bd/packages/next/src/server/app-render/create-component-tree.tsx#L433
Там вероятно есть клиентское кеширование темплейта. Спасибо за случай, обдумаю.
А работать такое [как я написал выше] должно, попробую на днях добавить пример.
Тоже плохо с неймингом у команды реакта получилось, что серверные компоненты назвали серверными. Безумное количество раз слышал странные выводы исходя из этого деления (серверные/клиентские). По факту это скорее static components/assembler components.
Ну с переводами сложно, да. Для них я по итогу сделал своё решение и об этом следующая статья)
Больше библиотек богу библиотек или как я переосмыслил i18n [next.js v14]
Позиция команды Next.js.
Что-то вроде "Вся динамика должна быть на клиенте. Клиентские компоненты не хуже серверных и с ними не будет потерь в оптимизации". Не знаю, зачем с такими взглядами вообще их завезли.
Ещё есть проблема с Layout-ом, которую я в PR не решил - он не ререндерится и если использовать этот геттер внутри лайаута - он не обновится при переходе между страниц. Тут нужно просто блочить всю динамику внутри лайаута, но пока next.js так не умеет.
В такой ситуации думаю лучше создать провайдер с клиентским и серверным контекстом и передавать в него пользователя.
Серверные компоненты конечно создали поле для костылей ?
Но этот набор, как я вижу, переключает приложение на SSR. Так как локаль читает для каждого запроса из созданных в мидлваре кукисов. Но интересная связка, спасибо, что поделились!
P.S. Грустно конечно, что команда реакта сказала что не будет заниматься серверными контекстами и это будет ответственность фреймворков, а команда некста, что не видит в них смысла.
Вот это поделился решением ?
Спасибо, что написали, добавил ссылку в конец статьи!
Да, он только для App Router. Если точнее, то по подходам он под серверные компоненты реакта, просто насколько я знаю сейчас их полноценно поддерживает только Next.js.
Вероятно с релизом 19й версии подтянутся Remix и остальные, возможно тогда решение адаптирую и под другие фреймворки.
Что ж, период активного чтения статьи только завершился, как ко мне пришла идея как реализовать то, чего так не хватало.
Так что, теперь пакет содержит Серверные Контексты!
https://github.com/vordgi/next-impl-getters?tab=readme-ov-file#server-contexts-beta
Быть может, дойдут руки до ещё одной статьи по next.js, давно планирую собрать статью как оно там устроено...
Подробно кеширование описали сами next.js - https://nextjs.org/docs/app/building-your-application/caching;
По разворачивания тоже у них есть инструкция с примерами - https://nextjs.org/docs/app/building-your-application/deploying#self-hosting;
По ресурсам:
in memory - 50мБ (можно поменять в конфиге)
В случае дефолтного обработчика кеша не в Vercel - всё сохраняется в файловой системе (насколько знаю без лимитов);
В случае дефолтного в Vercel - общий лимит не знаю (скорее всего его нет), но есть лимит в 2мБ на запрос. Весьма вероятно в будущем кеширование в Vercel сделают платным;
В случае кастомного - как настроете
Да. Обычно так делают чтобы разделить логику - бывают компоненты только меняют состояние и им не важно какое состояние сейчас, а другие наоборот только читают.
Первым вообще не нужно ререндериться, поэтому им не нужно зависеть от UserDeviceContext.
А вторым не нужно знать логику смены состояния - небольшой бонус в виде деления ответственности.
Маркетинговый сервис, где в общем-то учитываем потери даже на доли секунды. Ну и следствие маркетингового - нет критической завязки на конкретного клиента, мобильная и десктопная версия делаются одинаковые (чтоб лишний раз роботов не пугать).
Но я бы при такой ситуации сделал что-то вроде:
А больше нет компонента Head ?
Вместо него generateMetadata - https://nextjs.org/docs/app/api-reference/functions/generate-metadata (работает похожим образом как getInitialProps, но возвращает не пропсы, а объект метаданных, которые некст сам соберёт - тоже сомнительное на самом деле)
На самом деле по скорости, особенно с серверными компонентами - показывает себя хорошо. Ещё в новой версии ISR работает достаточно удобно и задача обновить 1000 страниц звучит как вполне простая - вместо ревалидации массива из 1000 страниц, вызывая метод для каждой, можно сказать - пересобери все страницы, которые использовали таг posts-javascript и он это в фоне сделает (https://nextjs.org/docs/app/api-reference/functions/revalidateTag).