Next.js w wersji 13 wprowadza fundamentalne zmiany w swojej architekturze dodając możliwość renderowania części komponentów po stronie serwera – React Server Components – które zmniejszają obciążenia klienta JavaScriptem i przyspieszają działanie aplikacji. W 13. wersji zmianie ulega również struktura katalogów folder `pages` zostaje zastąpiony`app`. Czy są to zmiany na tyle znaczące, aby nazwać je rewolucją?! Prześledźmy historię React.js i Next.js, aby poszukać odpowiedzi na to pytanie.
Zapraszamy do gościnnego artykułu Michała Miszczyszyna i Jakuba “Zaiste” Neandera, twórców kursu NEXT MASTERS. Dla czytelników Just Geek IT przygotowaliśmy zniżkę w wysokości 200 zł.
Next.js to jedno z najpopularniejszych narzędzi do budowania aplikacji internetowych. Od swojego debiutu w 2016 roku, framework nieustannie ewoluuje, a jego twórcy, firma Vercel, koncentrują się na ulepszaniu sposobu budowania aplikacji webowych i ich wydajności. Zmiany w architekturze otwierają drogę do innych innowacji, takich jak asynchroniczne komponenty, streaming HTTP czy możliwość wywołania akcji na serwerze bezpośrednio z klienta (Server Actions). tzw. Server Actions.
Krótka Historia Next.js
Next.js przeszedł serię znaczących transformacji. Z każdą kolejną wersją twórcy wprowadzają nowości, które wpływają na cały ekosystem React.js. Początkowe wersje frameworka koncentrowały się na renderowaniu po stronie serwera i automatycznym dzieleniu kodu. Ewolucja przyspieszyła z wydaniem Next.js 2.0, 3.0 i 4.0, w których wprowadzono między innymi Programmatic API, Prefetching, dynamiczne importowanie i wsparcie dla komponentów CSS. W wersji 5 pojawiło się oficjalne wsparcie dla TypeScripta. Wersja 6 z 2018 roku dodała wbudowany router i dostosowywanie konfiguracji Webpacka. W Next.js 9.0 wprowadzono jedną z większych innowacji: routing bazujący na systemie plików oraz API Routes. Natomiast wersja 9.3 wprowadziła metody `getStaticProps` i `getStaticPaths` służące do statycznego renderowania podstron.
Jednak to Next.js 13 rozpoczął zupełnie nową erę tego frameworka, wprowadzając wsparcie dla React Server Components oraz nowy App Router. Zmiany te nie tylko upraszczają zarządzanie stronami, ale też uspójniają budowanie i utrzymywanie aplikacji webowych poprzez jasny podział funkcyjny elementów składowych poprzez zagnieżdżanie layoutów, dedykowane strony do wyświetlania informacji o ładowaniu treści, czy routy do budowania API zgodne z WebAPI.
App Router w Next.js 13 jest znacząco różny od Pages Router w poprzednich wersjach, a z perspektywy architekturalnej może być uznany za (nie)małą rewolucję. Zwłaszcza w kontekście historii frameworka, który często preferował budowanie swoich własnych (tzw. home-grown) rozwiązań, niekoniecznie związanych z ogólnie przyjętymi standardami.
Rozwój React Server Components (RSC) i Next.js zachodził w dużym stopniu równolegle, a obie technologie wprowadzają nowe rozwiązania i standardy dla całego ekosystemu React. RSC zyskiwały na znaczeniu jako eksperymentalny sposób renderowania treści od swojego ogłoszenia w 2020 roku, aż do oficjalnego uruchomienia jako nieudokumentowana część React 18 w 2022 roku. Seria uaktualnień przyniosła wsparcie dla asynchronicznych komponentów, ulepszone interfejsy API i znacznie poprawiony Developer Experience.
Next.js był pierwszym frameworkiem, który dodał wsparcie dla React Server Components już w maju 2023 roku. W tym samym czasie Dan Abramov, czyli twarz zespołu React.js, aktywnie zachęcał twórców innych frameworków, aby eksperymentowali z RSC, chcąc tym samym zminimalizować postrzeganie, iż Next.js to jedyna droga do użycia React Server Components.
Firma Vercel zademonstrowała proaktywność i odwagę, będąc pierwszą firmą, która pokazała działająca implementację React Server Components. Aktywny udział pracowników Vercel w procesie Request For Comments (RFC) dla React Server Components świadczy o wysokim stopniu ścisłej współpracy z zespołem React.js – zespół Next.js był de facto siłą napędową rozwoju całego Reacta! Takie działania sprzyjają ekosystemowi i w efekcie dają społeczności deweloperów narzędzia, które są nie tylko zaawansowane, ale też stabilne i efektywne. Vercel przetarł szlak i pokazał, jak efektywnie wdrażać innowacyjne rozwiązania do istniejących produkcyjnych narzędzi.
Nie można jednak pominąć faktu, iż Vercel zatrudnia osoby, które wcześniej pracowały w zespole React.js. Powoduje to pewne obawy w społeczności i skłania do zadania strategicznych pytań o potencjalne zawłaszczenie Reacta. Takie działania zdaniem niektórych mogą prowadzić do sytuacji, w której Vercel może mieć nieproporcjonalnie duży wpływ na kierunek rozwoju React.js. Pomimo iż firma wprowadziła pozytywne zmiany, istnieje ryzyko centralizacji decyzyjnej i rozwój narzędzia zgodnie z potrzebami firmy Vercel, a nie całej społeczności.
Next.js 13 idzie w standardy
Next.js w wersji 13. po raz pierwszy stara się maksymalizować wsparcie dla standardów webowych. Dla przykładu, w tej wersji zmieniono sygnaturę handlerów API z historycznie używanej w Node.js na taką, która jest zgodna z proponowanymi standardami: Request -> Response. Dodatkowo w wersji 13 można korzystać z HTTP streaming, który polega na wysyłaniu fragmentów dokumentu HTML do przeglądarki w miarę ich generowania przez serwer, zamiast czekania na wygenerowanie kompletnej strony.
Umożliwia to szybsze renderowanie i interakcję ze stroną, ponieważ przeglądarka może zacząć przetwarzanie i wyświetlanie treści jeszcze zanim cały dokument zostanie odebrany. Jest to szczególnie korzystne w kontekście wydajności i percepcji szybkości przez użytkownika, a dzięki sposobowi, w jaki zostało to zaimplementowane, korzystanie ze streamingu nie wprowadza dodatkowej złożoności dla osób budujących aplikacje w Next.js.
Pójście w kierunku Web API przez zespół Next.js stanowi znaczący krok ku uproszczeniu i stabilizacji frameworka, redukując prawdopodobieństwo potrzeby przyszłych, znaczących zmian. Web API są szeroko przyjętym standardem w branży, co sprawia, iż każda decyzja o ich zastąpieniu lub modyfikacji przez Next.js stanowiłaby ryzykowny i mało prawdopodobny manewr. Dlatego też, decyzja o przyjęciu Web API w Next.js działa jako forma ubezpieczenia stabilności. Next.js buduje na solidnych, sprawdzonych fundamentach, co minimalizuje ryzyko przyszłych, kosztownych zmian. Zresztą do podobnego wniosku doszły też inne firmy: m.in. Google, Cloudflare, Deno etc, które razem pracują nad standardami sieciowymi.
Dobrym przykładem standardów w praktyce są Server Actions, które pozwalają bezpośrednio z frontendu wywołać zdalny kod i obsłużyć odpowiedź. Przypomina to podejście Remote Procedure Call (RPC). Jednak korzystanie z Server Actions wymaga od programistów i programistek w zasadzie wyłącznie stworzenia poprawnego klasycznego formularza HTML. Next.js stosuje progressive enhancement i dba o to, aby taki formularz przede wszystkim działał choćby przy wyłączonym lub niezaładowanym JavaScripcie, a dopiero później dodaje do niego „fajerwerki” przy pomocy JS.
Next.js ewoluuje w zgodzie ze standardami branżowymi, zmierzając w kierunku bardziej efektywnych rozwiązań i redukując potrzebę poznawania abstrakcji specyficznych tylko dla jednego narzędzia. Uwzględnia to zarówno dojrzałość technologii, jak i standardy wbudowane w przeglądarki, Node.js i Deno. Funkcje wprowadzone w wersji 13, takie jak React Server Components, API Routes czy Server Actions, podkreślają tę tendencję i są świadectwem rosnącej dojrzałości całego ekosystemu.
Next.js 13 jako framework fullstack
Warto zwrócić uwagę na jeszcze jeden aspekt zmian w Next.js 13.Next.js ewoluował w kierunku pełnoprawnego frameworka fullstack. Otwiera to zupełnie nowe możliwości dla deweloperów i pozwala na budowę zaawansowanych stron internetowych, aplikacji internetowych, jak i backendów, w tymREST API,GraphQL czy tRPC. Użycie JavaScriptu na frontendzie i backendzie – znane jako izomorficzny lub uniwersalny JavaScript – upraszcza utrzymanie aplikacji przez zwiększenie reużywalności kodu, a także jednolitości kompetencji zespołu programistów. Transformacja ta ma potencjał do istotnej zmiany sposobu, w jaki społeczność i rynek postrzegają Next.js – nie tylko jako narzędzie do frontendu czy SPA, ale jako wszechstronny zestaw narzędzi do tworzenia kompleksowych aplikacji webowych fullstack.
Z innej perspektywy, Next.js jest przez cały czas powszechnie uznawany za narzędzie skoncentrowane wyłącznie na frontendzie. Będzie to wymagało wysiłku i czasu, by przełamać ten stereotyp i wypromować nowe funkcje. To oznacza również potrzebę inwestowania w materiały edukacyjne i działania marketingowe. Ostatecznie, zmiana tej percepcji jest kluczowa dla maksymalizacji potencjału, który Next.js w tej chwili oferuje.
Cache jako centralna idea – nowe podejście
Cache w Next.js 13 stał się nie tylko jednym z narzędzi, ale kluczową, centralną ideą architektoniczną całego frameworka. Jest to znaczący krok naprzód, który diametralnie zmienia sposób myślenia o budowaniu i zarządzaniu aplikacjami w tym środowisku. Wcześniejsze wersje Next.js oferowały pewne mechanizmy cache’owania, ale nie kładły na nie aż tak dużego nacisku. Teraz, z wersją 13, mamy do czynienia z niemal całkowicie nowym frameworkiem, który pod starą nazwą kryje zupełnie odmienne koncepcje i architekturę, a cache jest centralną ideą tych zmian.
Next.js 13 optymalizuje wydajność i obniża koszty utrzymania aplikacji poprzez cztery warstwy cache’owania. Request Memoization służy do ponownego użycia danych w drzewie komponentów React na poziomie serwera. Data Cache przechowuje dane między różnymi zapytaniami użytkowników i jest trwały. Full Route Cache zapisuje gotowy HTML i payload RSC, również na poziomie serwera. Router Cache działa na poziomie klienta, zmniejszając liczbę zapytań do serwera podczas nawigacji.
Memoizacja w kontekście zapytań HTTP działa tylko dla metod GET i jest związana z drzewem komponentów React. Next.js rozszerza natywną funkcję `fetch` będącą częścią Web API i pozwala na indywidualną konfigurację zachowań cache’owania. Wszystkie te funkcje dają deweloperom niezwykle elastyczną kontrolę nad tym, jak dane są przechowywane i ponownie używane, co ma wpływ na zarówno wydajność, jak i koszty.
W efekcie, podejście do cache’owania w Next.js 13 idealnie dopełnia React Server Components i wsparcie dla standardów webowych. Jest to istotne zwłaszcza w kontekście budowania aplikacji o dużej skali, gdzie każda optymalizacja ma realny wpływ na wydajność i koszty. Daje to również deweloperom dużą elastyczność w zarządzaniu zasobami. Ta zmiana paradygmatu sprawia, iż choćby doświadczeni użytkownicy Next.js będą musieli na nowo przemyśleć swoje strategie, praktyki i przyzwyczajenia deweloperskie.
Kiedy ewolucja jest rewolucją?
Aby zmiana została zaadoptowana w sposób efektywny, musi ona być znacząca i diametralna. React Server Components, asynchroniczne komponenty, centralna rola cache’a i akcje serwerowe to całkowicie nowy model mentalny. Te zasadnicze zmiany w Next.js 13 mają potencjał do zdefiniowania nowej ery w budowaniu aplikacji webowych. Zmiany, które wprowadzają nowe elementy bez oferowania znaczących usprawnień, są problematyczne – to raczej sztuka dla sztuki.
Nowości muszą generować widoczny i znaczący skok jakościowy i/lub efektywnościowy, aby zrekompensować koszty wdrożenia, szkoleń i adaptacji. Użytkownicy, którzy są zaznajomieni z poprzednimi wersjami narzędzia, mogą być oporni na te nowości jeżeli nie przedstawimy im konkretnych korzyści płynących ze zmian.
Jest to klasyczny problem innowacji: jak zbalansować potrzebę rewolucyjnych zmian z utrzymaniem bieżącej bazy użytkowników? W tym kontekście, upowszechnienie takich transformacji może wymagać równie rewolucyjnych strategii edukacyjnych i marketingowych. Ostatecznym testem będzie adaptacja rynkowa.
Jeśli wszystkie te zmiany będą postrzegane jako przynoszące zasadnicze korzyści, wówczas Next.js 13 będzie przykładem rewolucji.
Przypominamy o zniżce dla czytelników na 5-cio tygodniowy kurs NEXT MASTERS prowadzony przez Jakuba „Zaiste” Neandera i Michała Miszczyszyna. Zniżkę znajdziecie pod tym adresem.