Лучшие новые функции в Next.js 13

автор vadim


Next.js похож на React с преимуществами, поскольку он предоставляет все функции React с простыми в использовании соглашениями и четко определенным стеком клиент-сервер. Next.js 13 — это новейшая версия, выпущенная Vercel на конференции Next.js в октябре 2022 года. Она содержит множество новых функций, в том числе сборщик под названием Turbopack и поддержку нескольких оптимизаций, разработанных React, таких как React Server Components и потоковый рендеринг. .

В целом, Next.js 13 — это важная веха, объединяющая достижения React и самого Next в приятном и удобном пакете для разработчиков. Этот выпуск также содержит значительную внутреннюю оптимизацию. Давайте рассмотрим, что нового в Next.js 13.

Новый упаковщик Turbopack

Turbopack — это новый сборщик JavaScript общего назначения и основная функция Next.js 13. Он задуман как замена Webpack, и хотя он выпущен в виде альфа-версии, теперь вы можете использовать Turbopack в качестве сборщика режима разработки из Next.js 13. вперед. Turbopack — новый участник конкурса сборщиков, где несколько претендентов боролись за то, чтобы преодолеть доминирование Webpack.

Turbopack написан на Rust, который в наши дни кажется лучшим выбором для системно-ориентированных инструментов. Присущая Rust скорость является одной из причин, лежащих в основе производительности Turborepo по сравнению с другими инструментами сборки. (Rust чем-то похож на C++, но с большей безопасностью памяти.) Интересно, что пространство сборщиков в последнее время было очень активным, а инструмент сборки Vite стал преемником Webpack. Vite написан на Go, языке, похожем на Rust. Но Rust, похоже, имеет преимущество в эффективности.

Turbopack также имеет архитектурные изменения, такие как разумное использование кэширования, которое оптимизирует обработку изменений исходного кода. Основная предпосылка заключается в том, что Turbopack содержит детализированную модель уже созданных изменений и создает только те изменения, которые необходимы для отражения текущих изменений.

С тех пор, как Webpack впервые познакомил мир JavaScript с концепцией конвейера сборки «все-в-одном», основанного на соглашениях по сравнению с конфигурацией, существовало соревнование, кто сможет разработать лучший инструмент для связывания JavaScript. Разработчикам нужен самый быстрый и многофункциональный инструмент, который они могут найти, способный справляться с крайними случаями и обрабатывать оптимальные пути с минимальными усилиями.

Использование Turbopack в Next.js 13

Создать новое приложение Next.js легко с помощью create-next-app и используйте Турбопак. Вы используете --example переключиться и дать ему with-turbopack аргумент, как показано в листинге 1.

Листинг 1. Запуск нового приложения Next, созданного с помощью Turbopack


npx create-next-app --example with-turbopack

Если вы посмотрите на package.jsonвы увидите, что это отражено в небольшом изменении в том, как dev скрипт работает:

Листинг 2. Скрипт режима разработки с турбо


"dev": "next dev --turbo"

На данный момент Turbopack работает как альтернативная замена серверу режима разработки Next.js, но на горизонте большие планы, включая фреймворки помимо React. Svelte и Vue были упомянуты по имени. Предположительно, Turbopack станет инструментом devmode по умолчанию, а также инструментом производственной сборки в какой-то момент в будущем.

Когда вы бежите npm run devвы увидите экран, подобный приведенному ниже.

Экран приветствия режима разработки Next.js 13 turbopack. IDG

Экран приветствия режима разработки Next.js 13 Turbopack. В меню слева показано несколько примеров новых функций в Next.js 13.

Хотя влияние Turbopack на производительность больше всего заметно в крупномасштабных приложениях, небольшой забавный эксперимент показывает разницу. Попробуйте запустить dev с --turbo включено, а не выключено, как показано в листинге 3. Как вы можете видеть, даже для скромного начального приложения время запуска сокращается с более чем 1000 миллисекунд до примерно 8.

Листинг 3. Время запуска Turbopack devmode


// with --turbo
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
event - initial compilation 7.216ms

// without --turbo
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
event - compiled client and server successfully in 1118 ms (198 modules)

Новый каталог /app

Теперь давайте посмотрим на наш макет каталога, где вы заметите новый /app каталог. Это новая функция Next.js 13. По сути, все в /app каталог участвует в функциях React и Next.js следующего поколения.

/app каталог живет рядом со знакомым /pages каталог и поддерживает более продвинутые возможности маршрутизации и компоновки. Маршруты, которые совпадают в обоих /pages и /app будет идти к /appчтобы вы могли постепенно заменять существующие маршруты.

Основная маршрутизация в /app похож на /pages в том, что вложенные папки описывают путь URL, поэтому /app/foo/bar/page.js становится localhost:3000/foo/bar в нашем dev настраивать.

Включение каталога /app

/app каталог все еще является бета-функцией, поэтому для ее использования вам необходимо включить экспериментальные функции в next.config.jsвот так:

Листинг 4. Как включить экспериментальные функции


experimental: {
    appDir: true
  }

Обратите внимание, что это было сделано для нас, когда мы формировали новый проект с помощью create-next-app.

Макеты в Next.js 13

Одна из сверхспособностей /app закончился /pages поддержка сложных вложенных макетов. Каждая ветвь в вашей иерархии URL-адресов может определять макет, который используется совместно с его дочерними элементами (он же, листовые узлы). Кроме того, макеты сохраняют свое состояние между переходами, что позволяет избежать затрат на повторный рендеринг контента в общих панелях.

Каждый каталог рассматривает page.tsx/jsx файл в качестве содержимого и layout.tsx/jsx определяет шаблон как для этой страницы, так и для подкаталогов. Таким образом, создание вложенных шаблонов становится простым. Более того, фреймворк достаточно умен, чтобы не перерисовывать разделы страницы, которые не изменяются, поэтому навигация не будет перерисовывать макеты, которые не были затронуты.

Например, предположим, что мы хотели иметь /foo/* каталог, где все дочерние элементы обведены белой рамкой. Мы могли бы бросить layout.tsx файл в /app/foo каталог, что-то вроде листинга 5.

Листинг 5. app/foo/layout.tsx


export default function FooLayout({ children }) {
  return <section style={{borderWidth: 1, borderColor:'white'}}>{children}</section>;
}

Обратите внимание, что в листинге 5 компонент деструктурирует свойство «дочерние элементы» и использует его для размещения содержимого внутри шаблона. Здесь макет — это просто свойство раздела со встроенным стилем, создающим белую рамку. Файл подкачки в /app/foo будет отображаться его содержимое там, где {children} токен находится в файле макета. По умолчанию файлы макета создают вложенные шаблоны, поэтому маршрут, соответствующий подкаталогу /app/foo/* также будет иметь свое содержание, размещенное в пределах {children} элемент /app/foo/layout.*.

Компоненты сервера React

По умолчанию все компоненты в /app/* являются компонентами React Server. По сути, серверные компоненты — это ответ React на постоянный вопрос о том, как улучшить гидратацию во внешних приложениях. Большая часть работы по рендерингу компонентов выполняется на сервере, а минималистичный кешируемый профиль JavaScript отправляется клиенту для обработки реактивности.

Иногда при использовании хуков на стороне клиента, таких как useState или useEffect (где сервер не может выполнить работу заранее), вам нужно сообщить React, что это клиентский компонент. Вы делаете это, добавляя ‘use client’ директиву в первую строку файла. Ранее мы использовали расширения имен файлов, такие как .client.js и .server.js для обозначения клиентского компонента, использующего хуки на стороне клиента, но теперь вы должны использовать ‘use client’ директива во главе /app компоненты.

Потоковый рендеринг и саспенс

Потоковая передача — это еще одна новая оптимизация React, реализованная благодаря новому механизму одновременного рендеринга. Это фундаментальное изменение в том, как работает движок React. Основная идея заключается в том, что пользовательский интерфейс можно разделить на разделы, а разделы, зависящие от данных, могут определять состояния загрузки при одновременной загрузке данных. При этом разделы, которые не зависят от данных, могут сразу же получать свое содержимое для немедленного отображения.

В первую очередь вы будете использовать эту функцию с <Suspense> компонент. По сути, <Suspense> говорит, отображать этот загружаемый контент, пока реальный контент находится в состоянии загрузки, а затем показывать реальный контент, управляемый данными, когда он готов. Поскольку пользовательский интерфейс не блокируется, пока это происходит, и каждый <Suspense> происходит одновременно, у разработчиков есть последовательный и простой способ определить макеты, которые оптимизированы и отзывчивы, даже со многими разделами, зависящими от данных.

Next.js 13 /app каталог означает, что вы по умолчанию можете использовать потоковую передачу и <Suspense>. Внутренний сервер Next реализует API, который управляет состояниями загрузки. Преимущества заключаются в том, что состояния загрузки могут отображаться быстро, гидратированный контент может отображаться по мере того, как он становится доступным одновременно, а пользовательский интерфейс остается отзывчивым во время загрузки сегментов.

Эти преимущества особенно заметны, когда сеть работает медленно или ненадежно, например, при использовании мобильных устройств. Эта новая функция улучшает как пользовательский опыт, так и опыт разработчиков. Разработчики заметят, что выборка данных стала более последовательной и стандартной. Принятие лучших практик не только проще, но и используется по умолчанию.

Новое соглашение о загрузке

есть новый loading.js соглашение в Next.js 13. Он находится в каталоге маршрутов /app и действует как <Suspense> на весь участок маршрута. (Под капотом Next.js фактически применяется <Suspense&gt; граница.) Итак, все, что определено в папке для loading.js будет отображаться во время рендеринга фактического контента с теми же преимуществами, что и при непосредственном использовании ожидания.

Вы можете увидеть это соглашение в действии, открыв http://локальный:3000/потоковое в нашем демо-приложении. Это отобразит app/streaming/loading.tsx файл, показанный в листинге 6, во время загрузки фактического содержимого.

Листинг 6. app/streaming/loading.tsx


import { SkeletonCard } from '@/ui/SkeletonCard';
export default function Loading() {
  return (
    <div className="space-y-4">
      <div className="grid grid-cols-3 gap-6">
        <SkeletonCard isLoading={true} />
        <SkeletonCard isLoading={true} />
        //...
    </div>
  );
}

В принципе, loading.tsx Файл в листинге 5 показывает сетку компонентов SkeletonCard. А карта скелета это пульсирующая медиа-карта, которая содержит места для реального контента, который в конечном итоге загружается по маршруту.

Улучшенная выборка данных в Next.js 13

Методы загрузки данных Next.js (getServerSideProps, getStaticProps и getInitialProps) теперь устарели в пользу более нового подхода к выборке данных.

Первое соглашение заключается в загрузке данных на сервер, что стало проще, поскольку все компоненты по умолчанию являются компонентами сервера. Это устраняет тенденцию отбрасывать запросы данных от клиента к серверу, когда вам действительно нужно только напрямую обратиться к хранилищу данных с сервера и отправить отрендеренный пользовательский интерфейс клиенту. См. документацию Next.js для получения более подробной информации о причинах предпочтения выборки данных на стороне сервера.

Получение данных в /app каталог должен работать с потоковой передачей и приостановкой. Компоненты должны делать свои собственные запросы данных, а не родители, передающие данные, даже если эти данные совместно используются компонентами. Сама структура избегает избыточных запросов и гарантирует, что только минимальные запросы будут сделаны и переданы нужным компонентам. Извлекающий API также кэширует результаты для повторного использования.

Все это упрощает архитектуру выборки данных, которая по-прежнему оптимизирована. Разработчики могут меньше думать о производительности выборки данных и просто получать данные по мере необходимости в том компоненте, который в них нуждается.

Новый подход означает, что вы можете использовать знакомый нам асинхронный Fetch API непосредственно в серверных компонентах. (React и Next расширяют API для обработки дедупликации и кэширования.) Вы также можете определить асинхронные серверные компоненты; например, export default async function Page(). Дополнительную информацию о новом API выборки см. в блоге Next.js.

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

Заключение

В Next.js 13 довольно много действий, и есть еще много того, что я не затронул. Другие новые функции включают обновления компонента next/image и новую систему загрузки шрифтов. В целом, Next.js 13 продолжает традицию предоставления универсальной среды React с преимуществами, которая упрощает использование множества функций.

Тем не менее, этот выпуск особенный из-за долгосрочных инноваций, таких как потоковая передача и серверные компоненты. В сочетании с инфраструктурой Vercel Next.js 13 обеспечивает значительную простоту развертывания и позволяет нам заглянуть в опыт реактивной разработки будущего.



Related Posts

Оставить комментарий