Сегодня поговорим про Next, а именно про его 13 версию. Первый релиз Next 13 был в октябре прошлого года. На данный момент ее активно дорабатывают. 13 версия привнесла очень много нового в Next и она довольно сильно отличается от 12 версии.
На выпуск Next 13 повлиял фреймворк Remix, который вышел в 2021 году. В Remix есть удобные фичи, которые упрощают разработку. Next 13 закрывает все пробелы образовавшиеся после выхода Remix. Также В next 13 добавилось много фич из коробки.
Что нового в Next 13?
- Появилась директория app. Она пришла на замену директории pages.
- Был упрощен запрос к данным. Отказались от таких функции как getServerSideProps и getStaticProps.
- Добавился Streaming. Это по сути отображения состояния загрузки. Эта фича основана на компоненте Suspense из React 18.
- Была упрощена работа с обработкой ошибок.
- Произошло разделение на серверные и клиентские компоненты.
- Новый механизм кэширования данных.
- Добавлен Turbopack — собственный сборщик Next.
Директория app
Чтобы мы имели возможность работать с директорией app мы должны создать проект Next c помощью npx и указать опцию —experimental-app. В этом случае у нас добавится настройка appDir в next.config.js.
Директория app по сути заменяет директорию pages. Здесь можно увидеть как отличаются между собой эти папки.
Теперь за компонент страницы отвечает не index файлик или файлик с названием вложенного роута, а файл page.js
Добавилась гибкая поддержка лэйаутов . Файлик layout.js призван заменить не удобную функцию getLayout. Лэйауты могут быть вложенныe. Те. layout из роута page-a будет вложен в layout который находится на уровень выше. Это как раз позаимствовано у Remix.
Так же появился файлик head.js — в нем хранится метаинформация страницы. те тэги title description и тд. По сути это просто React компонент с метатэгами. Раньше за это отвечал компонент Head, только его сейчас вынесли в отдельный файл.
Запрос данных
Запрос за данными сильно упростился. Теперь не нужно использовать специальные функции getserverSideProps или getStaticProps. Мы просто создаем функцию с запросом за данными, используем эту функцию в компоненте страницы и отрисовываем результат. В этом случае также поддерживается SSR — то есть запрос выполнится на сервере и страница вернется с уже отрисованными данными.
Streaming
Это ничто иное как отрисовка состояния загрузки при рендеринге компонента. За компонент, который будет отображаться как компонент загрузки отвечает файл loading.js. Это тоже по сути обычный React компонент. Есть один ньюанс — при использовании файла loading.js у нас не будет поддержки SSR. При первичной загрузке с сервера придет разметка которая будет указана в файле loading.js.
Под капотом streaming реализуется при помощи специального компонента Suspense, который представили в React 18. Компоненты, обёрнутые в теги Suspense, во время загрузки данных загружают и выводят то, что указано в свойстве fallback.
Обработка ошибок
Обработка ошибок стала проще и гибче. Для того чтобы сообщить юзеру о том, что у нас произошла ошибка при загрузке данных нужно создать файл not-found.js рядом с файлом страницы page.js. Это тоже обычный компонент React, который будет возвращать html разметку, в которой мы укажем, что произошла ошибка загрузки данных. Далее на самой странице мы должны использовать специальную функцию notFound из next/navigation. Проверяем что при запросе данных произошла ошибка и вызваем эту функцию. Функция сообщит Next, что нужно отобразить компонент ошибки.
Разделение на серверные и клиентские компоненты
В Next 13 произошло разделение на серверные и клиентские компоненты. По умолчанию когда мы создаем компонент в Next 13 он является server-first компонентом. То есть серверным компонентом. Чтобы сделать его клиентским компонентом нужно использовать директиву ‘use client’.
Как вообще понять когда использовать серверные компоненты, а когда клиентские.
В документации есть вот такая таблица, которая поможет определить какой компонент стоит использовать. Например клиентские компоненты используются когда мы применяем обработчики onClick или onChange, так же когда мы используем хуки useState, useReducer или useEffect, когда мы используем браузерные API или работаем с классовыми компонентами. Серверные компоненты же используются в основном для загрузки данных.
Кэширование
В Next 13 реализован достаточно удобный механизм кэширования данных. Кэширование может происходить на двух уровнях на уровне страницы и на уровне запроса. Чтобы реализовать кэширование на уровне страницы мы должны экспортировать константу revalidate.
Например мы хотим чтобы данные обновлялись каждые 60 секунд тогда экспортируем константу revalidate со значением 60.
Чтобы реализовать кэширование на уровне запроса то мы должны дописать опцию revalidate в опциях для fetch в поле next.
Если эта опция присутствует и на странице и в запросе, то кэширование будет происходить по наименьшему времени. Если посмотрим на этот пример, то время кэширования составит 10 секунд потому что это время меньше чем указано глобально для всей страницы.
Также стоит отметить что если при повторном запросе произойдет ошибка то будут отображены старые данные.
Turbopack
В Next 13 появился собственный сборщик Turbopack. Он написан на Rust. Кстати писали его те же ребята, которые занимались разработкой Webpack.
Обновление проекта на Turbopack происходит в 10 раз быстрее чем на Vite и в 700 раз быстрее чем при использовании Webpack.
Проводились тесты по производительности. Тут 4 примера старта приложения. Количество модулей у каждого приложения 3000. Как можно видеть Next 13 с Turbopack побеждает с большим отрывом.