
Server Components στην παραγωγή: μοτίβα ανάκτησης δεδομένων που αντέχουν πραγματικό φόρτο στο Next.js 15
Δοκιμασμένα στην παραγωγή μοτίβα ανάκτησης δεδομένων για React Server Components στο Next.js 15: απομνημόνευση ανά αίτημα, παράλληλα await, σταδιακή αποστολή με Suspense, η νέα οδηγία `use cache` και οι περιπτώσεις όπου τα Server Actions υπερέχουν πραγματικά των Route Handlers.
- Συντάκτης
- Από το DevLume
- Δημοσίευση
- Δημοσιεύτηκε στις 3 Οκτωβρίου 2026
Βασικά συμπεράσματα
- Η γενική διάθεση του Next.js 15 (21 Οκτωβρίου 2024) αντέστρεψε την προεπιλογή: τα
fetch, ταGETRoute Handlers και το Client Router Cache «δεν αποθηκεύονται πλέον προσωρινά από προεπιλογή» — το αντίθετο από το Next.js 14 (Next.js Blog, 2024).- Το
cache()του React είναι απομνημόνευση ανά αίτημα, όχι προσωρινή μνήμη μεταξύ αιτημάτων. Η τεκμηρίωση είναι σαφής: «Το React ακυρώνει την προσωρινή μνήμη όλων των απομνημονευμένων συναρτήσεων σε κάθε αίτημα διακομιστή» (React Docs).- Το επίσημο μοτίβο παραλληλισμού ξεκινά τις υποσχέσεις πριν τις αναμείνει και κατόπιν χρησιμοποιεί
await Promise.all(...)· η τεκμηρίωση προειδοποιεί ότι «πολλά αιτήματαasync/awaitμπορούν και πάλι να εκτελούνται διαδοχικά όταν τοποθετούνται το ένα μετά το άλλο» (Next.js Docs).- Το
loading.jsδεν σας προστατεύει από διάταξη που καλείcookies(),headers()ήfetchχωρίς προσωρινή αποθήκευση — αυτός ο συνδυασμός «μπλοκάρει την πλοήγηση μέχρι να ολοκληρωθεί η απόδοση της διάταξης» (Next.js Docs).- Η ίδια η Vercel προτείνει για νέα έργα ένα Data Access Layer, όχι κλήσεις βάσης δεδομένων μέσα στα components — η πρόσβαση σε επίπεδο component είναι «κατάλληλη μόνο για γρήγορες επαναλήψεις ανάπτυξης και πρωτότυπα» (Vercel Blog, 2023).
Συνοπτικά
Η ανάκτηση δεδομένων του App Router μοιάζει παραπλανητικά με όσα είχατε στο μυαλό σας το 2023. Όμως έχει αλλάξει. Το Next.js 15 αντέστρεψε τις προεπιλογές προσωρινής αποθήκευσης· το React 19 άλλαξε τον τρόπο με τον οποίο ο πελάτης καταναλώνει την εργασία του διακομιστή· το use cache αντικατέστησε το σύνολο επιλογών του fetch που έλεγχε την προσωρινή αποθήκευση· και τα cookies(), headers(), params και searchParams έγιναν ασύγχρονα. Τα μοτίβα που αντέχουν στην παραγωγή μιας εταιρείας B2B 50-300 ατόμων είναι όσα σέβονται αυτές τις νέες προεπιλογές. Το άρθρο συγκεντρώνει τις πρακτικές που χρησιμοποιούμε: τοποθετήστε την ανάκτηση δίπλα στη χρήση της και αφήστε το React να απομνημονεύει, παραλληλίστε συνειδητά, στείλτε σταδιακά την εργασία που δεν αποθηκεύεται προσωρινά πίσω από Suspense, χρησιμοποιήστε σκόπιμα το use cache και μην καταφεύγετε σε Server Actions όταν χρειάζεστε Route Handler.
Η επανεκκίνηση της προσωρινής αποθήκευσης στο Next.js 15: γιατί το παλιό σας μοντέλο δεν ισχύει
Αν γράφατε κώδικα App Router το 2023 ή το 2024, τα αντανακλαστικά σας χρειάζονται αλλαγή. Η ανακοίνωση του Next.js 15 είναι άμεση: τα αιτήματα fetch, τα GET Route Handlers και το Client Router Cache «δεν αποθηκεύονται πλέον προσωρινά από προεπιλογή» (Next.js Blog, 2024). Το staleTime του Client Router Cache για τμήματα Page έχει προεπιλογή 0, ώστε «ο πελάτης να αντικατοπτρίζει πάντα τα πιο πρόσφατα δεδομένα των Page components που ενεργοποιούνται κατά την πλοήγηση» — μόνο το loading.js διατηρεί προσωρινή μνήμη 5 λεπτών.
Δύο ακόμη ασύμβατες αλλαγές θα σας απασχολήσουν μέσα στην πρώτη εβδομάδα της αναβάθμισης. Πρώτον, τα cookies(), headers(), draftMode(), params και searchParams είναι πλέον ασύγχρονα· το σκεπτικό είναι ότι αυτά τα API «βασίζονται σε δεδομένα συγκεκριμένου αιτήματος» και η υποχρεωτική χρήση await επιτρέπει στον διακομιστή να «προετοιμάζει όσο το δυνατόν περισσότερα πριν φτάσει ένα αίτημα» (Next.js Blog, 2024). Δεύτερον, το force-dynamic ορίζει πλέον το no-store ως προεπιλεγμένη πολιτική του fetch — αν βασιζόσασταν στο ότι οι δυναμικές διαδρομές χρησιμοποιούσαν ακόμη την προσωρινή μνήμη δεδομένων, αυτό δεν ισχύει πια.
Ο πρακτικός αντίκτυπος στον κώδικα παραγωγής είναι μεγαλύτερος από όσο υποδηλώνει ο κατάλογος αλλαγών. Κώδικας που λειτουργούσε χάρη σε έμμεση προσωρινή αποθήκευση καλεί πλέον την ανάντη υπηρεσία σε κάθε αίτημα. Υποβαθμίσεις του TTFB εμφανίζονται σε διαδρομές που δεν αγγίξατε. Η λύση είναι να ορίζετε ρητά το προφίλ προσωρινής αποθήκευσης κάθε ανάκτησης, όχι να αναδημιουργείτε τις παλιές προεπιλογές. Αυτό πραγματεύεται το υπόλοιπο άρθρο.
Μοτίβο 1 — Τοποθετήστε την ανάκτηση εκεί που χρειάζεται και αφήστε το React να απομνημονεύει ανά αίτημα
Το πρώτο ένστικτο των ομάδων που έρχονται από το Pages Router είναι να συγκεντρώνουν την ανάκτηση δεδομένων σε έναν φορτωτή ανώτατου επιπέδου και να περνούν τα αποτελέσματα προς τα κάτω ως props. Αντισταθείτε σε αυτό. Το App Router σχεδιάστηκε για τοπική συνύπαρξη: κάθε Server Component ανακτά απευθείας τα δεδομένα που χρειάζεται.
Ο λόγος που αυτή η προσέγγιση κλιμακώνεται είναι ότι οι ίδιες κλήσεις fetch σε ένα δέντρο Server Components αποδιπλοποιούνται αυτόματα. Η τεκμηρίωση του Next.js το λέει καθαρά: «Τα πανομοιότυπα αιτήματα fetch σε ένα δέντρο React components απομνημονεύονται από προεπιλογή, ώστε να ανακτάτε δεδομένα στο component που τα χρειάζεται αντί να περνάτε props σε διαδοχικά επίπεδα» (Next.js Docs). Για εργασία εκτός fetch — ερωτήματα βάσης, κλήσεις RPC — το React παρέχει το cache(), διαθέσιμο μόνο σε Server Components, με τη διευκρίνιση ότι «το React ακυρώνει την προσωρινή μνήμη όλων των απομνημονευμένων συναρτήσεων σε κάθε αίτημα διακομιστή» (React Docs).
Δύο κανόνες κάνουν αυτό το μοτίβο ασφαλές:
- Τυλίξτε κάθε συνάρτηση πρόσβασης δεδομένων εκτός
fetchσεcache(). Αν τοgetUser(id)καλείται από τρία components στο ίδιο δέντρο, θέλετε μία πρόσβαση στη βάση. Χωρίςcache(), θα γίνουν τρεις. - Αντιμετωπίστε την απομνημόνευση ως περιορισμένη στο αίτημα, όχι στην εφαρμογή. Η προσωρινή μνήμη ακυρώνεται στο όριο του αιτήματος. Μην αποθηκεύετε τιμές περιμένοντας επαναχρησιμοποίηση μεταξύ αιτημάτων — γι' αυτό υπάρχει το
use cache, που θα δούμε παρακάτω.
Το όφελος είναι συγκεκριμένο: σταματάτε να συντηρείτε ένα παράλληλο επίπεδο προώθησης props που υπάρχει μόνο για να τροφοδοτεί βαθύτερα components, και ο κώδικας παραγωγής αρχίζει να μοιάζει με την τεκμηρίωση.
Μοτίβο 2 — Κάντε συνειδητά παράλληλο τον διαδοχικό κώδικα
Το συνηθέστερο σφάλμα απόδοσης σε κώδικα παραγωγής App Router είναι τα διαδοχικά await. Δεν μοιάζει με σφάλμα. Μοιάζει με συνηθισμένο ασύγχρονο κώδικα:
const user = await getUser()
const team = await getTeam()
const billing = await getBilling()Η συνολική καθυστέρηση είναι το άθροισμα τριών κύκλων αιτήματος και απόκρισης. Η τεκμηρίωση του Next.js προειδοποιεί ακριβώς γι' αυτό: «μέσα σε οποιοδήποτε component, πολλά αιτήματα async/await μπορούν και πάλι να είναι διαδοχικά αν τοποθετούνται το ένα μετά το άλλο» (Next.js Docs). Η διόρθωση είναι μηχανική — ξεκινήστε τις υποσχέσεις πριν τις αναμείνετε:
const userPromise = getUser()
const teamPromise = getTeam()
const billingPromise = getBilling()
const [user, team, billing] = await Promise.all([
userPromise, teamPromise, billingPromise,
])Τώρα η συνολική καθυστέρηση ισούται με την πιο αργή από τις τρεις. Η τεκμηρίωση επισημαίνει ειλικρινά τον συμβιβασμό: το Promise.all απορρίπτει ολόκληρη την ομάδα με μία μόνο αποτυχία και προτείνει το Promise.allSettled όταν είναι αποδεκτή η μερική αποτυχία (Next.js Docs). Σε πίνακα ελέγχου B2B όπου η πλοήγηση μπορεί να αποδοθεί χωρίς το στοιχείο χρεώσεων, το allSettled με χειρισμό σφαλμάτων ανά ενότητα είναι η σωστή επιλογή. Σε σελίδα όπου η απουσία δεδομένων χρήστη καθιστά άχρηστη όλη τη διαδρομή, το Promise.all αποτυπώνει πιστά τον τρόπο αποτυχίας.
Ο κανόνας μας στα έργα: κάθε Server Component με τρεις ή περισσότερες ανεξάρτητες εξαρτήσεις δεδομένων πρέπει να χρησιμοποιεί Promise.all ή Promise.allSettled. Οτιδήποτε άλλο αντιμετωπίζεται ως υποβάθμιση TTFB στην ανασκόπηση κώδικα.
Μοτίβο 3 — Στείλτε σταδιακά την εργασία χωρίς προσωρινή αποθήκευση πίσω από Suspense, ποτέ από loading.tsx
Το loading.tsx είναι χρήσιμο, αλλά αποτυγχάνει ακριβώς στην περίπτωση όπου οι ομάδες το αναζητούν: όταν η ίδια η διάταξη προσπελαύνει δεδομένα χρόνου εκτέλεσης. Η επίσημη τεκμηρίωση είναι σαφής: «μια διάταξη που προσπελαύνει δεδομένα χωρίς προσωρινή αποθήκευση ή δεδομένα χρόνου εκτέλεσης (π.χ. cookies(), headers() ή ανακτήσεις χωρίς προσωρινή αποθήκευση) δεν καταφεύγει στο loading.js του ίδιου τμήματος διαδρομής. Μπλοκάρει την πλοήγηση μέχρι να ολοκληρώσει την απόδοσή της» (Next.js Docs).
Η συνέπεια: κάθε διάταξη που διαβάζει τον τρέχοντα χρήστη από cookies() μπλοκάρει όλες τις υποκείμενες πλοηγήσεις για όσο διαρκεί αυτή η ανάγνωση, ανεξάρτητα από το loading.js που τοποθετείτε στη διαδρομή. Οι περισσότερες εφαρμογές χρειάζονται τον τρέχοντα χρήστη στη διάταξη, οπότε η λύση είναι να τυλίξετε την πρόσβαση χωρίς προσωρινή αποθήκευση σε όριο <Suspense>, ώστε η υπόλοιπη διάταξη να αποστέλλεται σταδιακά χωρίς αυτήν:
// app/(dashboard)/layout.tsx
export default function DashboardLayout({ children }) {
return (
<div>
<Suspense fallback={<NavSkeleton />}>
<CurrentUserNav />
</Suspense>
{children}
</div>
)
}Το ίδιο μοτίβο ισχύει μέσα στις σελίδες. Οτιδήποτε αργό — κλήση API τρίτου, συγκέντρωση δεδομένων στη βάση, απομακρυσμένο αναλυτικό ερώτημα — μπαίνει πίσω από δικό του όριο Suspense. Ο βασικός σκελετός αποστέλλεται πρώτος· οι αργές περιοχές φτάνουν όταν είναι έτοιμες. Το Next.js Commerce της Vercel κωδικοποιεί αυτό το μοτίβο: διάταξη, κεφαλίδα σελίδας και φίλτρα αναζήτησης αποδίδονται αρχικά στον διακομιστή, ενώ καλάθι, κατηγορίες αναζήτησης, προϊόντα και υποσέλιδο «χρησιμοποιούν Suspense για να φορτώνονται ανεξάρτητα όταν κάθε τμήμα είναι έτοιμο» (Vercel Blog) — ώστε ρητά «ο ιστότοπος να μην είναι πλέον τόσο αργός όσο το πιο αργό backend του».
Αυτό έχει μεγαλύτερη σημασία από παλαιότερα. Το Web Almanac 2024 του HTTP Archive εντόπισε το Next.js ως το framework που επηρεάστηκε πιο αρνητικά από τη μετάβαση από FID σε INP, με «πτώση 10 ποσοστιαίων μονάδων στους ιστοτόπους που επιτυγχάνουν καλές βαθμολογίες CWV» όταν το INP αντικατέστησε το FID (Web Almanac 2024). Το ποσοστό καλού INP σε κινητά ήταν 74%, έναντι 97% σε υπολογιστές. Η σταδιακή αποστολή είναι ο τρόπος να διατηρείτε την αίσθηση απόκρισης σε πίνακες B2B όσο ολοκληρώνεται η πιο αργή ανάκτηση.
Μοτίβο 4 — Χρησιμοποιήστε use cache για αργά, κοινόχρηστα, μη προσωπικά δεδομένα
Οι επιλογές προσωρινής αποθήκευσης στο επίπεδο fetch έχουν φύγει από το ίδιο το fetch στην προεπιλεγμένη λειτουργία του 15. Τις αντικαθιστά η οδηγία use cache, που εισήχθη πειραματικά στο 15.0 και ενεργοποιείται με τη λειτουργία Cache Components στο v16 (Next.js Docs). Η μορφή είναι καθαρή:
async function getPricingPlans() {
'use cache'
cacheLife('hours')
cacheTag('pricing-plans')
return db.pricingPlans.findMany()
}Τρία πράγματα πρέπει να γνωρίζετε πριν το χρησιμοποιήσετε στην παραγωγή. Το προεπιλεγμένο προφίλ είναι «5 λεπτά παλαιότητας στον πελάτη / επανεπικύρωση στον διακομιστή ανά 15 λεπτά / χωρίς λήξη» — κατάλληλο για δεδομένα αναφοράς που αλλάζουν αργά, επικίνδυνο για προσωπικά δεδομένα. Το cacheLife() ελέγχει την απομάκρυνση βάσει χρόνου· το cacheTag() μαζί με revalidateTag()/updateTag() παρέχουν ακύρωση κατ' απαίτηση που «ενοποιείται στα επίπεδα προσωρινής αποθήκευσης πελάτη και διακομιστή». Δεύτερον, οι αποθηκευμένες συναρτήσεις «δεν μπορούν να προσπελάσουν απευθείας API χρόνου εκτέλεσης όπως cookies(), headers() ή searchParams» — διαβάστε τα εκτός της συνάρτησης και περάστε τις τιμές ως ορίσματα, διαφορετικά η μεταγλώττιση θα λήξει λόγω υπέρβασης χρόνου μετά από 50 δευτερόλεπτα. Τρίτον, το "use cache" παραμένει beta στην έκδοση 15.2 (26 Φεβρουαρίου 2025), άρα ενδείκνυται για μη κρίσιμες διαδρομές, όχι για σημεία όπου η αλλοίωση της προσωρινής μνήμης μπορεί να προκαλέσει περιστατικό ασφάλειας.
Ο κανόνας απόφασής μας: αποθηκεύστε προσωρινά μόνο δεδομένα που (1) υπολογίζονται ή ανακτώνται αργά, (2) είναι ίδια για πολλούς χρήστες και (3) αντέχουν παλαιότητα για το ρυθμισμένο διάστημα. Προγράμματα τιμολόγησης, δημόσια δεδομένα καταλόγου, ορισμοί σημαιών λειτουργιών, κείμενα μάρκετινγκ. Ποτέ δεδομένα συγκεκριμένου χρήστη, ποτέ δεδομένα που καθορίζουν εξουσιοδότηση, ποτέ δεδομένα των οποίων η παλαιότητα συνιστά σφάλμα ορθότητας.
Μοτίβο 5 — Server Actions για εγγραφές, Route Handlers για όλα τα υπόλοιπα
Τα Server Actions παρουσιάζονται ως αντικατάσταση των διαδρομών API. Αυτή η αντιμετώπιση δημιουργεί προβλήματα. Είναι συγκεκριμένα ένας μηχανισμός εγγραφής για φόρμες και μεταβολές που προέρχονται από το δικό σας δέντρο React. Το άρθρο ασφάλειας της Vercel αποτελεί τη βασική αναφορά και διευκρινίζει το μοντέλο: «Τα Server Actions υλοποιούνται πάντα με POST και μόνο αυτή η μέθοδος HTTP επιτρέπεται να τα καλέσει», ενώ το Next.js «συγκρίνει την κεφαλίδα Origin με την κεφαλίδα Host… Αν δεν ταιριάζουν, το Action απορρίπτεται» (Vercel Blog, 2023). Οι μεταβλητές που δεσμεύονται σε closure κρυπτογραφούνται με ιδιωτικό κλειδί που παράγεται κατά τη μεταγλώττιση.
Αυτό το μοντέλο είναι εξαιρετικό για την περίπτωση που καλύπτει — ένα κουμπί που καλεί συνάρτηση στον διακομιστή — και ακατάλληλο για άλλες χρήσεις. Αν χρειάζεστε σημασιολογία GET, ιδιοδύναμο τελικό σημείο, δημόσιο παραλήπτη webhook, επιστροφές κλήσης τρίτων, διασυνδέσεις μεταξύ μηχανών ή οτιδήποτε καταναλώνεται από πελάτη εκτός Next.js, χρησιμοποιήστε Route Handler. Η απόφαση δεν είναι θέμα ύφους· οι περιορισμοί των Server Actions (μόνο POST, επιβολή ίδιας προέλευσης, κρυπτογράφηση δεδομένων, απουσία εγγενούς προσωρινής αποθήκευσης) αντανακλούν τον προορισμό τους.
Το μοτίβο που εφαρμόζουμε στα έργα:
- Server Actions για υποβολές φορμών, αισιόδοξες ενημερώσεις και μεταβολές που ενεργοποιούνται από React components.
- Route Handlers (
app/api/.../route.ts) για webhook, επιστροφές κλήσης τρίτων, δημόσια API, μεταφορτώσεις αρχείων από πελάτες εκτός React και οτιδήποτε χρειάζεται ρητές κεφαλίδες προσωρινής αποθήκευσης.
Αυτός ο διαχωρισμός κρατά κάθε μηχανισμό στον σχεδιασμένο ρόλο του και αποτρέπει την προσπάθεια προσαρμογής τελικών σημείων διασύνδεσης σε ακατάλληλο εργαλείο.
Το μοτίβο Data Access Layer (η πραγματική σύσταση της Vercel)
Το μοτίβο που δεν θα βρείτε στα περισσότερα μαθήματα, αλλά πρέπει να υιοθετήσετε πριν από την πρώτη διάθεση στην παραγωγή, είναι το Data Access Layer. Η σύσταση της Vercel είναι σαφής: «Η προτεινόμενη προσέγγισή μας για νέα έργα είναι η δημιουργία ξεχωριστού Data Access Layer… Αυτή η προσέγγιση εξασφαλίζει συνεπή πρόσβαση δεδομένων και μειώνει την πιθανότητα σφαλμάτων εξουσιοδότησης». Η πρόσβαση δεδομένων σε επίπεδο component «είναι κατάλληλη μόνο για γρήγορες επαναλήψεις ανάπτυξης και πρωτότυπα» (Vercel Blog, 2023).
Στην πράξη πρόκειται για έναν φάκελο data/ ή dal/ με μία συνάρτηση ανά ερώτημα, καθεμία με δικό της έλεγχο εξουσιοδότησης βάσει της τρέχουσας συνεδρίας και επιστροφή αποτελέσματος με καθορισμένο τύπο. Αυτές τις συναρτήσεις καλούν τα Server Components και τα Server Actions· τίποτε άλλο. Τα οφέλη συσσωρεύονται:
- Οι αποφάσεις εξουσιοδότησης βρίσκονται σε ένα σημείο, αντί να διασπείρονται σε κάθε Server Component.
- Η ίδια συνάρτηση καλείται από ροή μεταβολής Server Action και ροή ανάγνωσης Server Component χωρίς διπλούς ελέγχους εξουσιοδότησης.
- Η προσωρινή αποθήκευση μέσω
cache()(ανά αίτημα) καιuse cache(μεταξύ αιτημάτων) συνδέεται φυσικά με τις συναρτήσεις DAL. - Το όριο μεταξύ κώδικα framework και επιχειρησιακής λογικής μένει καθαρό, διευκολύνοντας τη μελλοντική μετάβαση σε άλλο περιβάλλον εκτέλεσης — ή εκτός Next.js συνολικά.
Η επένδυση είναι μικρή. Το όφελος φαίνεται την πρώτη φορά που εντοπίζετε κενό εξουσιοδότησης ή χρειάζεστε προσωρινή αποθήκευση σε συχνά εκτελούμενη διαδρομή χωρίς να ελέγξετε κάθε component που την καλεί.
Τρόποι αποτυχίας στην παραγωγή για τους οποίους κανείς δεν σας προειδοποιεί
Μια σύντομη λίστα επαναλαμβανόμενων αστοχιών που συναντάμε σε ελέγχους παραγωγής:
- Το
cookies()στο επίπεδο διάταξης μπλοκάρει την πλοήγηση. Καλύφθηκε παραπάνω. Το σύμπτωμα είναι «υπάρχει loading.tsx αλλά δεν εμφανίζεται ποτέ» — επειδή αργεί η διάταξη, όχι η σελίδα. - Συχνά προσπελαζόμενοι πίνακες ανακτώνται χωρίς
cache(). Ένα δέντρο Server Components που καλείgetUser(currentUserId)από πλοήγηση, κεφαλίδα και πλευρική στήλη εκτελεί το ερώτημα τρεις φορές ανά αίτημα, εκτός αν τοgetUserτυλιχτεί σεcache(). Ο πολλαπλασιασμός κλήσεων ανά αίτημα μένει αόρατος μέχρι να διαβάσετε τις καταγραφές της βάσης. - Έμμεση δυναμική απόδοση. Η ανάγνωση
cookies(),headers()ή η πρόσβαση στοsearchParamsοπουδήποτε σε διαδρομή την μετατρέπει σε δυναμική. Διαδρομές που έπρεπε να παράγονται στατικά αποδίδονται σιωπηρά ανά αίτημα. Ελέγχετε τις ενδείξειςƒ (Dynamic)στην έξοδο μεταγλώττισης και αν συμφωνούν με την πρόθεσή σας. Promise.allμε μία υποχρεωτική και τρεις προαιρετικές ανακτήσεις. Μία προαιρετική αποτυχία καταρρίπτει ολόκληρη τη διαδρομή. Η λύση είναιPromise.allSettledμε χειρισμό σφαλμάτων ανά αποτέλεσμα, όπως αναγνωρίζει και η τεκμηρίωση.- Σύγχυση γύρω από το PPR. Το Partial Prerendering παραμένει πειραματικό στη σταθερή έκδοση 15 — διατίθεται μόνο στο canary και απαιτεί
experimental.ppr: 'incremental'μαζί με εξαγωγήexperimental_pprανά διαδρομή (Next.js Docs, Issue #71587). Σχεδιάστε με βάση τις σταθερές λειτουργίες· μη θεμελιώνετε την αρχιτεκτονική σε μια πειραματική σημαία.
Σύντομος έλεγχος πριν από τη διάθεση
Εφαρμόστε αυτή τη λίστα σε κάθε διαδρομή App Router που εξυπηρετεί πραγματική κίνηση:
- Κάθε ασύγχρονη συνάρτηση πρόσβασης δεδομένων που δεν είναι
fetchτυλίγεται σεcache(). - Τα components με τρεις ή περισσότερες ανεξάρτητες εξαρτήσεις δεδομένων χρησιμοποιούν
Promise.allήPromise.allSettled— ποτέ σκέτα διαδοχικά await. - Κάθε διάταξη που καλεί
cookies(),headers()ήfetchχωρίς προσωρινή αποθήκευση τοποθετεί την πρόσβαση μέσα σε όριο<Suspense>. - Το
use cacheεφαρμόζεται μόνο σε μη προσωπικά δεδομένα, με καθορισμένοcacheLifeκαι τουλάχιστον έναcacheTagγια ακύρωση. - Κάθε πρόσβαση βάσης περνά από Data Access Layer με ελέγχους εξουσιοδότησης δίπλα στη συνάρτηση ερωτήματος.
- Τα Server Actions χρησιμοποιούνται για εγγραφές ίδιας προέλευσης· όλα τα υπόλοιπα χρησιμοποιούν Route Handlers.
- Η έξοδος μεταγλώττισης ελέγχεται για απροσδόκητες δυναμικές διαδρομές μετά από κάθε PR που αγγίζει διάταξη ή σελίδα.
Αυτούς τους κανόνες εφαρμόζουμε στις ανασκοπήσεις κώδικα των έργων μας· εντοπίζουν περίπου το 80% των υποβαθμίσεων που εμφανίζονται μετά τη διάθεση.
Αν αναβαθμίζετε υπάρχον έργο App Router σε Next.js 15 και θέλετε δεύτερη γνώμη για το σχέδιο μετάβασης, η DevLume συμβουλεύει ομάδες μηχανικών B2B ακριβώς σε τέτοιες εργασίες.

