Senarai Semak Produksi Praktikal untuk Next.js 16 App Router
Senarai semak produksi Next.js 16 kami untuk App Router. Fahami bila untuk guna Server vs. Client Component, default caching baharu, dan ISR atas permintaan.
Next.js App Router merupakan satu anjakan paradigma yang signifikan berbanding Pages Router. Ia memperkenalkan konsep-konsep hebat seperti React Server Components (RSC) dan kawalan caching yang terperinci. Walaupun alatan ini membolehkan kita membina aplikasi yang lebih pantas dan efisien, ia juga datang dengan set peraturan dan potensi masalah yang baharu.
Di JRV Systems, kami telah banyak membina sistem untuk klien menggunakan App Router, daripada platform e-dagang sehinggalah ke papan pemuka dalaman. Artikel ini ialah senarai semak praktikal kami untuk melancarkan aplikasi Next.js 16+ ke persekitaran produksi, dengan fokus pada isu-isu paling lazim yang telah kami hadapi dan selesaikan.
Senarai Semak Produksi Next.js 16 Anda
Beralih kepada App Router memerlukan perubahan cara berfikir. Tetapan defaultnya berbeza, dan apa yang dahulunya perlu dinyatakan secara eksplisit kini menjadi implisit (dan sebaliknya). Senarai semak produksi Next.js 16 kami memberi tumpuan kepada empat bidang kritikal: strategi komponen, caching data, revalidation kandungan, dan perangkap pembangunan yang biasa berlaku.
Server vs. Client Components: Server Kini Pilihan Default
Perubahan paling asas ialah semua komponen di dalam direktori app adalah React Server Components (RSC) secara default. Komponen ini di-render di server dan menghantar HTML yang tidak interaktif kepada klien. Ini sangat bagus untuk prestasi kerana ia mengurangkan jumlah JavaScript yang perlu dimuat turun oleh pelayar.
Untuk mencipta komponen interaktif tradisional, anda mesti memilih untuk masuk secara eksplisit dengan meletakkan arahan 'use client' di bahagian paling atas fail. Ini menandakan fail tersebut dan semua komponen anak yang diimportnya sebagai Client Components.
Berikut adalah panduan mudah:
-
Gunakan Server Components (default) untuk:
- Mengambil data terus dari pangkalan data atau API.
- Mengakses sumber backend dan environment variable dengan selamat.
- Mengelakkan pakej JavaScript yang besar daripada dihantar ke pelayar. Contohnya, pakej pemformatan tarikh yang hanya digunakan untuk memaparkan cap masa boleh dikekalkan di server.
-
Gunakan Client Components (
'use client') untuk:- Mengendalikan interaksi pengguna seperti klik, input borang, dan event lain (
onClick,onChange). - Menggunakan state dan lifecycle hooks (
useState,useEffect,useContext). - Mengakses API khusus pelayar seperti
windowataulocalStorage.
- Mengendalikan interaksi pengguna seperti klik, input borang, dan event lain (
Dalam satu projek kami untuk sebuah syarikat logistik di Negeri Sembilan, kami menggunakan Server Components untuk mengambil dan memaparkan jadual data yang besar dan kompleks. Hanya elemen interaktif seperti butang susun dan penapis carian dibina sebagai Client Components yang kecil dan terasing. Strategi ini memastikan masa muat halaman awal kekal pantas sambil menyediakan pengalaman interaktif sepenuhnya.
Caching: Fahami Default Baharu yang Agresif
Di dalam App Router, API fetch telah diperluaskan oleh Next.js untuk mengendalikan caching data secara automatik. Ini adalah punca kekeliruan utama bagi pembangun yang beralih dari Pages Router atau kerangka kerja lain. Secara default, setiap permintaan fetch akan di-cache secara agresif.
fetch('https://api.example.com/data')
Panggilan ini kini setara dengan fetch(..., { cache: 'force-cache' }). Hasilnya akan di-cache selama-lamanya sehingga anda melakukan revalidation secara manual. Ini sangat berkuasa untuk data yang benar-benar statik tetapi boleh menyebabkan kandungan lapuk di produksi jika tidak diurus dengan betul.
Untuk mengawal tingkah laku ini, anda mempunyai dua pilihan utama:
-
cache: 'no-store': Ini akan mematikan caching sepenuhnya untuk permintaan tersebut. Data akan diambil semula pada setiap permintaan, sama sepertigetServerSidePropsdalam Pages Router. Gunakan ini untuk data yang sangat dinamik, seperti troli beli-belah pengguna atau maklumat stok masa nyata. -
next: { revalidate: seconds }: Ini mengaktifkan Incremental Static Regeneration (ISR). Data diambil dan di-cache, tetapi selepas beberapa saat yang ditetapkan, permintaan seterusnya akan mencetuskan revalidation di latar belakang. Contohnya,revalidate: 3600akan menyimpan cache data selama satu jam. Ini sesuai untuk kandungan yang dikemas kini secara berkala tetapi tidak perlu masa nyata, seperti artikel blog atau senarai produk.
Revalidation Atas Permintaan (On-Demand): Mengemas Kini Kandungan Serta-merta
Revalidation berasaskan masa (ISR) memang berguna, tetapi bagaimana jika anda perlu mengemas kini kandungan sebaik sahaja ia berubah dalam Headless CMS atau pangkalan data anda? Di sinilah revalidation atas permintaan (on-demand) memainkan peranan.
Next.js menyediakan dua fungsi untuk ini: revalidatePath dan revalidateTag. Pendekatan berasaskan tag selalunya lebih mantap. Pertama, anda 'tag' permintaan fetch anda:
fetch('https://my-cms/api/posts', { next: { tags: ['posts'] } })
Kemudian, anda cipta satu API route yang selamat (cth: /api/revalidate) yang boleh dipanggil oleh CMS anda melalui webhook setiap kali artikel dikemas kini. Route ini akan melaksanakan fungsi revalidateTag:
revalidateTag('posts')
Apabila API route ini dicetuskan, Next.js akan membersihkan cache untuk semua permintaan fetch yang ditandakan dengan 'posts'. Apabila pengguna melawat halaman yang menggunakan data ini pada kali seterusnya, mereka akan menerima kandungan yang segar. Kami menggunakan corak ini secara meluas dalam produk SaaS kami, seperti sistem pengurusan klinik, untuk memastikan pengumuman awam dikemas kini serta-merta tanpa memerlukan pembinaan semula keseluruhan laman web.
Empat Perangkap Produksi Lazim App Router
Berdasarkan sesi nyahpepijat dan semakan kod kami, berikut adalah empat isu paling biasa yang dihadapi oleh pembangun semasa melancarkan projek App Router.
-
Terlupa
'use client'untuk Komponen Interaktif. Pembangun menambah pengendalionClickatau hookuseStatepada komponen, tetapi ia tidak berfungsi di produksi. Puncanya hampir selalu adalah arahan'use client'yang tertinggal. Komponen tersebut di-render di server, di mana interaktiviti tidak wujud. -
Menghantar Props yang Tidak Boleh Disiri (Non-Serializable) kepada Client Components. Anda tidak boleh menghantar objek kompleks seperti fungsi, objek Date, atau instance kelas sebagai props dari Server Component ke Client Component. Data yang dihantar merentasi sempadan ini mestilah boleh disiri (boleh ditukar kepada rentetan, seperti JSON). Jika tidak, ia boleh menyebabkan kegagalan senyap atau ralat hydration dalam pelayar.
-
Memilih Rendering Dinamik Secara Tidak Sengaja. Menggunakan fungsi seperti
headers()ataucookies(), atau mengaksessearchParamsdalam komponen halaman, akan memaksa keseluruhan route itu untuk di-render secara dinamik pada masa permintaan. Ini akan memintas semua penjanaan statik dan caching untuk route tersebut. Jika anda hanya memerlukansearchParamsuntuk penapisan di sisi klien, pertimbangkan untuk menghantarnya ke Client Component untuk dikendalikan, bukannya membacanya dalam fail halaman Server Component. -
Kebocoran Environment Variable Khusus Server. Mudah untuk menganggap semua kod dalam satu fail berjalan di server. Namun, jika anda mengimport fungsi utiliti yang menggunakan environment variable khusus server (cth:
process.env.DATABASE_URL) ke dalam Client Component, Next.js mungkin secara tidak sengaja memasukkan pembolehubah itu ke dalam JavaScript sisi klien. Sentiasa mulakan environment variable yang dimaksudkan untuk pelayar dengan awalanNEXT_PUBLIC_untuk lebih selamat.
Dengan mengingati perkara-perkara ini, anda boleh memanfaatkan kuasa penuh App Router sambil mengelakkan masalah produksi yang biasa. Ia adalah satu anjakan dalam pemikiran, tetapi ia menghasilkan aplikasi yang lebih baik dan pantas untuk pengguna di seluruh Malaysia dan serata dunia.