# Next.js bilan resilient tizimlar qurish > Zamonaviy veb-ilovalarda yuqori mavjudlik va ishlashni ta'minlash uchun eng yaxshi amaliyotlar. > > 2024-08-22 — y7.hk ## Avval Arxitektura Next.js ko'pincha zamonaviy veb-ilovalarning umurtqa pog'onasi bo'lib xizmat qiladi. Resiliensni ta'minlash yaxshi arxitektura qarorlari va to'g'ri vositalarning aralashmasini talab qiladi. Server Components va to'g'ri error boundary'lardan foydalanib, butunlay qulash o'rniga nafis tarzda degrade bo'ladigan o'ta resilient veb-ilovalarni qurish mumkin. ### Static Generation vs SSR Iloji bo'lganda Incremental Static Regeneration (ISR) standart bo'lsin. Bu backend API'laringiz vaqtincha mavjud bo'lmasa ham foydalanuvchilar oxirgi muvaffaqiyatli qurilgan versiyani ko'rishini kafolatlaydi. Lekin tradeoff haqiqiy: ISR yangilik narxidagi resiliensni beradi. SSR yangilikni backend'ga qattiq bog'liqlik narxidagi beradi. ```tsx // app/blog/[slug]/page.tsx export const revalidate = 300; // 5 daqiqa export default async function Post({ params }) { const post = await fetchPost(params.slug); // keshlangan + revalidate qilingan return
; } ``` O'tgan yili Cloudflare hodisasi paytida origin API'm 40 daqiqa ishdan chiqqanda, y7.hk'dagi barcha ISR sahifalari eski-lekin-haqiqiy HTML'ni taqdim etishda davom etdi. Xuddi shu saytning SSR sahifalari 500 qaytardi. Bu tajriba menga oylik trafikning 4%iga tushdi — va rendering strategiyasi haqidagi fikrimni butunlay o'zgartirdi. **Qoida:** 5–60 daqiqa eskirishi mumkin bo'lgan hamma narsa uchun ISR (blog postlari, mahsulot sahifalari, marketing). Eskirganlik mahsulotni sindirgandagina SSR (jonli dashboard'lar, auth holati, real-time ma'lumot). ### Error Boundary'lar — Izolyatsiya Bulkhead'lari Boundary'siz, bitta muvaffaqiyatsiz widget butun sahifani ag'daradi. Boundary bilan har bir bo'lim mustaqil ravishda muvaffaqiyatsiz bo'ladi. ```tsx // app/components/Section.tsx 'use client'; import { Component, ReactNode } from 'react'; export class Section extends Component< { children: ReactNode; fallback?: ReactNode }, { hasError: boolean } > { state = { hasError: false }; static getDerivedStateFromError() { return { hasError: true }; } render() { if (this.state.hasError) { return this.props.fallback ??
Bo'lim mavjud emas
; } return this.props.children; } } ``` Har bir mustaqil birlikni — sidebar vidjetlari, izoh bo'limlari, analitika dashboard'lari — o'z boundary'siga o'rang. Foydalanuvchi bo'sh ekran o'rniga vidjet bo'lgan joyda kulrang quticha ko'radi. Men buni Web3 dashboard'ida og'riqli tarzda o'rgandim, bitta RPC timeout butun portfel ko'rinishini ag'dardi. Price ticker atrofidagi bitta boundary sessiyani saqlab qolardi. ### Retry'lar Backoff Talab Qiladi Ko'r-ko'rona retry'lar xatoni kuchaytiradi. Jitter'li eksponensial backoff yukni taqsimlaydi va upstream'ga tiklanish vaqti beradi. ```ts async function fetchWithRetry( fn: () => Promise, attempts = 3, baseDelay = 300 ): Promise { for (let i = 0; i < attempts; i++) { try { return await fn(); } catch (err) { if (i === attempts - 1) throw err; const jitter = Math.random() * baseDelay; await new Promise(r => setTimeout(r, baseDelay * 2 ** i + jitter)); } } throw new Error('unreachable'); } ``` Men ikki qoidaga amal qilaman: 1. **Hech qachon 4xx'ni retry qilmang.** 404 retry bilan 200 bo'lmaydi. 2. **Umumiy kutish vaqtini cheklang.** Foydalanuvchi 8+ soniyadan beri spinner'ga qarayotgan bo'lsa, fallback UI ko'rsating va davom etishga ruxsat bering. ### Circuit Breaker'lar Kaskadli Xatolarni Kesadi Retry'lar o'tkinchi xatolarni hal qiladi. Circuit breaker'lar doimiy xatolarni hal qiladi. Backend 30 soniya davomida ishlamayotgan bo'lsa, uni kaltaklashni to'xtating — circuit'ni oching va darhol degrade javoblar taqdim eting. ```ts class Breaker { private failures = 0; private openUntil = 0; constructor(private threshold = 5, private cooldown = 30_000) {} async call(fn: () => Promise): Promise { if (Date.now() < this.openUntil) throw new Error('Circuit open'); try { const result = await fn(); this.failures = 0; return result; } catch (e) { if (++this.failures >= this.threshold) { this.openUntil = Date.now() + this.cooldown; } throw e; } } } ``` Breaker'siz sekin upstream osilib qolgan Node jarayonlari flotiga aylanadi. Breaker bilan tez xatolar va upstream qaytganda darhol tiklanadigan tizim olasiz. ### stale-while-revalidate bilan Edge Caching `Cache-Control` sarlavhasi — sizda bor eng arzon resiliens qatlami. `stale-while-revalidate` edge'ga oxirgi keshlangan nusxani taqdim etishga ruxsat beradi, orqa fonda esa yangi nusxa olinadi. ``` Cache-Control: public, s-maxage=60, stale-while-revalidate=600 ``` Bu "API ishdan chiqdi — sayt ishdan chiqdi" va "API ishdan chiqdi — ba'zi foydalanuvchilar 10 daqiqagacha eski ma'lumot ko'radi" orasidagi farq. ### Fallback UI Xususiyat Sifatida Fallback'lar biror narsa buzilganda ko'rsatadigan narsangiz emas — ular dizaynning bir qismi. Har bir async bo'limda uch holat bor: - **Yuklanmoqda:** yakuniy layout'ga mos skeleton (layout shift yo'q). - **Muvaffaqiyat:** haqiqiy kontent. - **Xato:** foydalanuvchiga hali ham ishini bajarish imkonini beradigan degrade versiya. Agar narx vidjetingiz ishlamasa, qizil xato ko'rsatmang — oxirgi keshlangan narxlarni "12 daqiqa oldin yangilangan" nishoni bilan ko'rsating. Izoh tizimi ishlamasa, faqat o'qish uchun thread'ni ko'rsating va input'ni yashiring. ### Oflayn Bardoshlilik Service Worker'lar faqat PWA uchun emas. App shell va oxirgi 5 ta tashrif buyurilgan sahifani keshlaydigan minimal SW g'aroyib mehmonxona wifi'ida va 10 000 metr balandlikda haqiqiy oflayn bardoshlilik beradi — bu mening browsing'imning ahamiyatli qismi. ```ts // sw.ts — statik uchun cache-first, sahifalar uchun network-first self.addEventListener('fetch', (e) => { const url = new URL(e.request.url); if (url.pathname.startsWith('/_next/static/')) { e.respondWith(caches.match(e.request).then(r => r ?? fetch(e.request))); } }); ``` ### Duch Kelgan Haqiqiy Xatolar - **Cloudflare edge KV uzilishi:** KV'ga bog'liq har bir sahifa 500 qaytardi. ISR sahifalari omon qoldi. - **Trafik cho'qqisida upstream CMS meni rate-limit'ladi.** Breaker yo'q edi; Next.js qattiq IP ban olguncha CMS'ni kaltakladi. Endi har bir tashqi chaqiruv 30 soniyalik cooldown'li breaker orqali o'tadi. - **WebSocket uzilganda bitta `` butun dashboard'ni ag'dardi.** Boundary qo'shilgach, UI qolgan qismi tirik qoldi, ticker esa jim qayta ulandi. ## Resiliens Checklist'i - [ ] 5+ daqiqa eskirishga bardoshli kontent uchun ISR/SSG - [ ] Har bir keshlanadigan marshrutda `stale-while-revalidate` - [ ] Har bir mustaqil vidjet atrofida error boundary - [ ] Retry'larda eksponensial backoff + jitter; 4xx'ni hech qachon retry qilmang - [ ] Har bir tashqi xizmat chaqiruvida circuit breaker - [ ] Har bir async UI uchun skeleton + fallback + xato holati - [ ] App shell'ni keshlaydigan service worker - [ ] Muhim bo'lmagan xususiyatlar (analitika, tavsiyalar) uchun hujjatlashtirilgan kill-switch ## Xulosa Resiliens — oxirida murvat bilan mahkamlanadigan xususiyat emas. Bu arxitekturaning o'zidir. Har qatlam — rendering, caching, fetching, UI — boshidanoq loyihalangan failure mode'ni oladi. Ularni erta quring, va uzilish bo'lishi mumkin bo'lgan hodisalar hech kim sezmaydigan jim degrade'larga aylanadi.