spinny:~/writing $ vim nextjs-16-cache-components.md
1~2वर्षों से Next.js में सबसे कष्टप्रद प्रश्नों में से एक यह रहा है: "क्या यह पृष्ठ स्थिर या गतिशील है?"। यह एक साधारण प्रश्न प्रतीत होता है, जब तक कि आप `cookies()` में एक कॉल, विभिन्न विकल्पों के साथ एक `fetch`, एक डेटाबेस क्लाइंट, एक CMS, एक शॉपिंग कार्ट, या कस्टम सामग्री का एक टुकड़ा नहीं जोड़ते।3~4Next.js 16 दिलचस्प है क्योंकि यह इस बातचीत को कम रहस्यमय बनाने की कोशिश करता है। यह जटिलता को खत्म नहीं करता है, लेकिन यह मानसिक मॉडल को बदल देता है: मार्ग डिफ़ॉल्ट रूप से गतिशील होते हैं, कैश जहां आवश्यक हो वहां खुद को घोषित करता है, और `Suspense` ताजा रहने वाले हिस्सों के साथ तेज शेल बनाने का प्राकृतिक तरीका बन जाता है।5~6समझने की सुविधा कैश कंपोनेंट्स है। स्थिर टर्बोपैक, रिएक्ट कंपाइलर, `proxy.ts`, और नए अमान्यकरण एपीआई महत्वपूर्ण हैं, लेकिन वे एक ही समस्या के इर्द-गिर्द घूमते हैं: पर्दे के पीछे फ्रेमवर्क ने क्या निर्णय लिया, इसका अनुमान लगाए बिना तेज़ ऐप्स बनाना।7~8## क्योंकि ये बात मायने रखती है9~10एक वास्तविक ऐप में आपके पास केवल "स्थैतिक पृष्ठ" और "गतिशील पृष्ठ" नहीं होते हैं। आपके पास अलग-अलग ज़रूरतों वाले अलग-अलग टुकड़े हैं।11~12उत्पाद शीट दिन में कुछ बार बदल सकती है। कीमत अधिक बार बदल सकती है. उपलब्धता लगभग लाइव होनी चाहिए. उपयोक्तानाम व्यक्तिगत है. समीक्षाएं स्ट्रीम की जा सकती हैं. साइडबार स्थिर हो सकता है. गाड़ी नहीं है.13~14यदि आप हर चीज़ को एक इकाई के रूप में मानते हैं, तो आप हमेशा दो चरम सीमाओं में से एक में पहुँचते हैं:15~16- आक्रामक कैशिंग और पुराने डेटा को देखने का जोखिम;17- हर जगह गतिशील प्रतिपादन और प्रदर्शन आवश्यकता से अधिक खराब।18~19कैश कंपोनेंट्स इस गलत विकल्प से बचने के लिए सटीक रूप से कार्य करता है।20~21## व्यवहार में मॉडल22~23`cacheComponents: true` के साथ, आप `"use cache"` का उपयोग करके घोषित कर सकते हैं कि कैश करने योग्य क्या है। फिर आप अवधि और टैग को `cacheLife()` और `cacheTag()` के साथ जोड़ सकते हैं। गतिशील हिस्से गतिशील रहते हैं और `Suspense` से अलग किए जा सकते हैं।24~25```mermaid26flowchart TD27 Request[उपयोगकर्ता का अनुरोध] --> Shell[संचित खोल]28 Request --> Dynamic[गतिशील अनुभाग]29 Shell --> FirstPaint[पहली त्वरित सामग्री]30 Dynamic --> Stream[सस्पेंस के अंदर स्ट्रीमिंग]31 Stream --> Complete[पूरा पेज]32```33~34सेटअप छोटा है:35~36```typescript37// next.config.ts38import type { NextConfig } from 'next';39~40const nextConfig: NextConfig = {41 cacheComponents: true,42};43~44export default nextConfig;45```46~47बड़ा बदलाव कॉन्फ़िगरेशन में नहीं है. यह इस पर निर्भर करता है कि आप घटकों को कैसे लिखना शुरू करते हैं।48~49```tsx50// app/products/[slug]/page.tsx51import { Suspense } from 'react';52import { cacheLife, cacheTag } from 'next/cache';53~54async function getProduct(slug: string) {55 'use cache';56~57 cacheLife('hours');58 cacheTag(`product:${slug}`);59~60 return db.product.findUnique({ where: { slug } });61}62~63async function ProductDetails({ slug }: { slug: string }) {64 const product = await getProduct(slug);65~66 return (67 <section>68 <h1>{product.name}</h1>69 <p>{product.description}</p>70 </section>71 );72}73~74async function LiveInventory({ slug }: { slug: string }) {75 const inventory = await db.inventory.findFirst({ where: { slug } });76 return <p>{inventory.quantity} pezzi disponibili</p>;77}78~79export default async function ProductPage({ params }: { params: Promise<{ slug: string }> }) {80 const { slug } = await params;81~82 return (83 <>84 <ProductDetails slug={slug} />85 <Suspense fallback={<p>Controllo disponibilità...</p>}>86 <LiveInventory slug={slug} />87 </Suspense>88 </>89 );90}91```92~93पेज को पूरी तरह से कैश्ड या पूरी तरह से गतिशील होना जरूरी नहीं है। उत्पाद शीट तेज़ और पुन: प्रयोज्य हो सकती है। इन्वेंट्री ताज़ा रह सकती है. उपयोगकर्ता सबसे धीमे हिस्से की प्रतीक्षा किए बिना, तुरंत कुछ देखता है।94~95## `use cache` निष्पादन योग्य दस्तावेज़ है96~97मुझे `"use cache"` के बारे में जो बात पसंद है वह यह है कि यह आपको अपना इरादा स्पष्ट करने के लिए मजबूर करती है। जब आप कोई फ़ंक्शन पढ़ते हैं, तो आप तुरंत समझ जाते हैं कि किसी ने निर्णय लिया है: "इस डेटा का पुन: उपयोग किया जा सकता है"।98~99यह विशेष रूप से तब उपयोगी होता है जब आप `fetch` का उपयोग नहीं कर रहे हों। कई ऐप्स प्रिज्मा, ड्रिज़ल, आंतरिक एसडीके, सीएमएस क्लाइंट या सेवा कार्यों से डेटा पढ़ते हैं। उन मामलों में केवल `fetch` विकल्पों पर आधारित पुराना तर्क पर्याप्त नहीं था।100~101अंगूठे का एक नियम:102~103- कैशिया सामग्री अपेक्षाकृत स्थिर;104- दानेदार टैग का उपयोग करें;105- गतिशील अनुमतियाँ, सत्र, कार्ट, सूचनाएँ और लेन-देन संबंधी स्थितियाँ छोड़ता है;106- धीमे भागों को `Suspense` के अंदर रखें;107- "हमने प्रदर्शन में सुधार किया" कहने से पहले मापें।108~109## सब कुछ फेंके बिना अमान्य करें110~111कैश तभी उपयोगी है जब आप इसे सटीक रूप से अपडेट कर सकें। यहां `cacheTag`, `revalidateTag` और `updateTag` महत्वपूर्ण हो जाते हैं।112~113उदाहरण:114~115```typescript116'use server';117~118import { updateTag } from 'next/cache';119~120export async function updateProductName(productId: string, name: string) {121 await db.product.update({122 where: { id: productId },123 data: { name },124 });125~126 updateTag(`product:${productId}`);127}128```129~130महत्वपूर्ण विवरण टैग है. `product:${productId}` एक सटीक सीमा बताता है। `products` एक बड़ी बाल्टी बताता है। सबसे पहले बड़ी बाल्टी आरामदायक होती है; कुछ महीनों के बाद यह कारण बन जाता है कि आप किसी शीर्षक को बदलने के लिए आधे ऐप को अमान्य कर देते हैं।131~132## स्थिर टर्बोपैक: वह हिस्सा जो आप हर दिन सुनते हैं133~134Next.js 16 विकास और निर्माण के लिए टर्बोपैक को केंद्र में लाता है। यह सबसे काव्यात्मक विशेषता नहीं है, लेकिन यह वह है जिसे आप काम करते समय महसूस करते हैं: सर्वर जो पहले शुरू होता है, तेजी से ताज़ा होता है, ऐसा बनाता है जो एक मजबूर कॉफी ब्रेक की तरह महसूस करना बंद कर देता है।135~136जैसा कि कहा गया है, मैं अपनी आंखें बंद करके कस्टम प्लगइन्स से भरे कोडबेस को माइग्रेट नहीं करूंगा। मैं जाँच करूँगा:137~138- स्थानीय निर्माण;139- गैर-मानक आयात;140- एमडीएक्स, एसवीजी और सीएसएस;141- वेबपैक प्लगइन्स बचे;142- महत्वपूर्ण पृष्ठ;143- निर्माण समय में अंतर.144~145नई परियोजनाओं के लिए, मैं डिफ़ॉल्ट से शुरू करूँगा। परिपक्व लोगों के लिए, मैं एक मापा प्रवासन करूँगा।146~147## रिएक्ट कंपाइलर: शोर हटाएं, विचार नहीं148~149रिएक्ट कंपाइलर 1.0 स्थिर है और Next.js 16 इसे `reactCompiler` के साथ सपोर्ट करता है। वादा यह है कि बहुत सारे मैन्युअल संस्मरण को कम किया जाए: कम `memo`, कम `useMemo`, कम `useCallback` का उपयोग "सुरक्षा के लिए"।150~151```typescript152// next.config.ts153import type { NextConfig } from 'next';154~155const nextConfig: NextConfig = {156 reactCompiler: true,157};158~159export default nextConfig;160```161~162मैं इसे जादुई धूल की तरह नहीं मानूंगा। जब कोड रिएक्ट नियमों का अच्छी तरह से पालन करता है तो कंपाइलर मदद करता है। यदि घटकों में अजीब दुष्प्रभाव, छिपे हुए उत्परिवर्तन या बुरी तरह से उपयोग किए गए हुक हैं, तो पहले इसे ठीक करने की आवश्यकता है।163~164इसे आज़माने का स्वस्थ तरीका:165~1661. अद्यतन `eslint-plugin-react-hooks`;1672. वास्तविक उल्लंघनों को ठीक करें;1683. इसे नियंत्रित क्षेत्र पर सक्षम करें;1694. निर्माण समय और व्यवहार को मापें;1705. मैन्युअल संस्मरण तभी हटाएँ जब इसकी आवश्यकता न रह जाए।171~172लक्ष्य प्रत्येक `useMemo` को मिटाना नहीं है। लक्ष्य निवारक संस्मरण लिखना बंद करना है क्योंकि हम प्रतिपादन से डरते हैं।173~174## `proxy.ts` और नेटवर्क सीमा175~176पुराना `middleware.ts` `proxy.ts` बन जाता है। यह एक नाम परिवर्तन है, लेकिन यह समझ में आता है: वह फ़ाइल अनुरोध सीमा पर बैठती है, यह पारंपरिक बैकएंड-शैली जेनेरिक मिडलवेयर नहीं है।177~178```typescript179// proxy.ts180import { NextRequest, NextResponse } from 'next/server';181~182export default function proxy(request: NextRequest) {183 const isLoggedIn = Boolean(request.cookies.get('session'));184~185 if (!isLoggedIn && request.nextUrl.pathname.startsWith('/dashboard')) {186 return NextResponse.redirect(new URL('/login', request.url));187 }188~189 return NextResponse.next();190}191```192~193यहां नियम सरल है: इसे छोटा रखें। रीडायरेक्ट, ऑथ रूटिंग, हेडर, आवश्यक पुनर्लेखन। यदि यह दूसरे बैकएंड की तरह महसूस होने लगे, तो संभवतः यह बहुत अधिक काम कर रहा है।194~195## मैं वास्तव में कैसे प्रवास करूंगा196~197मैं सभी सुविधाएं एक साथ चालू नहीं करूंगा. मैं यह करूँगा:198~1991. मैं नेक्स्ट, रिएक्ट और रिएक्ट डोम को अपडेट करता हूं;2002. मैं आधिकारिक कोडमॉड लॉन्च करता हूं;2013. मैं `params`, `searchParams`, `cookies()`, `headers()` और `draftMode()` पर ब्रेकिंग परिवर्तन ठीक करता हूं;2024. मैं `middleware.ts` को `proxy.ts` में स्थानांतरित करता हूँ;2035. मैं बिल्ड और महत्वपूर्ण पृष्ठों की जाँच करता हूँ;2046. मैं उस अनुभाग पर कैश घटकों को सक्षम करता हूं जहां कैश वर्तमान में घर्षण पैदा करता है;2057. मैं टैग और अमान्यकरण के लिए सम्मेलनों को परिभाषित करता हूं;2068. मैं रिएक्ट कंपाइलर को अलग से आज़माता हूँ;2079. पहले और बाद के मेट्रिक्स की तुलना।208~209अच्छा माइग्रेशन वह नहीं है जो सभी नई सुविधाओं का उपयोग करता है। यह ऐप के व्यवहार को अधिक पठनीय बनाता है।210~211## सोचने के तरीके में क्या बदलाव आता है212~213Next.js 16 के बारे में सबसे उपयोगी बात यह है कि यह आपको इरादों को बेहतर नाम देने के लिए मजबूर करता है। एक फ़ंक्शन केवल "डेटाबेस से उत्पाद प्राप्त करना" नहीं है। यह "उत्पाद प्राप्त करें, मैं इसे घंटों तक कैश कर सकता हूं, मैं इसे इस टैग के साथ अमान्य कर देता हूं"। एक घटक केवल "पेज प्रस्तुत करना" नहीं है। यह "यह तेज़ शेल है, यह टुकड़ा व्यक्तिगत है, यह स्ट्रीमिंग के लिए आता है।"214~215प्रथम दृष्टया यह अधिक काम जैसा लगता है। तब वह शांति का स्वरूप बन जाता है। प्रदर्शन निर्णय अब डिफ़ॉल्ट, अनुमान और जनजातीय स्मृति के संयोजन में छिपे नहीं हैं। वे कोड में हैं.216~217## उपयोगी स्रोत218~219- [Next.js 16 रिलीज़ नोट्स](https://nextjs.org/blog/next-16)220- [कैश घटक - Next.js दस्तावेज़](https://nextjs.org/docs/app/getting-started/cache-components)221- [कैश का उपयोग करें - Next.js डॉक्स](https://nextjs.org/docs/app/api-reference/directives/use-cache)222- [रिएक्ट कंपाइलर v1.0](https://react.dev/blog/2025/10/07/react-compiler-1)223~
NORMAL · nextjs-16-cache-components.md [readonly]223 lines · :q to close