Script optimizatsiya — next/script, strategy
Muammodan boshlaylik
Marketing bo'limi so'radi: Google Analytics, Yandex Metrika, Facebook Pixel, onlayn chat vidjeti va reklama skripti. Hammasini <head> ga qo'shdingiz:
<script src="https://mc.yandex.ru/metrika/tag.js"></script>
<script src="https://chat-vidjet.uz/widget.js"></script>
Lighthouse: Performance 95 → 58. Sahifa ko'rinishidan oldin brauzer begona serverlardan yuzlab kilobayt JavaScript yuklab, bajarishi kerak. Chat serveri sekin javob bersa — butun sahifa kutadi.
Hayotiy o'xshatma
Do'kon ochilishi. Avval eshik ochiladi va mijozlar kiradi (sahifa kontenti). Musiqa, reklama ekranlari va kuzatuv kameralari (uchinchi tomon skriptlari) — keyin yoqiladi. Hammasi tayyor bo'lmaguncha eshikni yopiq tutish — mijozlarni yo'qotish.
next/script
import Script from 'next/script'
<Script src="https://example.com/vidjet.js" strategy="lazyOnload" />
Strategiyalar
strategy |
Qachon yuklanadi | Misol |
|---|---|---|
beforeInteractive |
Sahifa interaktiv bo'lishidan oldin, faqat root layout da | Cookie roziligi menejeri, bot himoyasi |
afterInteractive (standart) |
Sahifa interaktiv bo'lgandan keyin | Analitika, teg menejerlari |
lazyOnload |
Brauzer bo'sh paytda, hammasidan keyin | Chat, ijtimoiy tarmoq tugmalari |
worker (eksperimental) |
Web Worker da (Partytown) | Og'ir uchinchi tomon skriptlari |
[!TIP] Qoida: imkon qadar kechroq. Ko'p skriptlar uchun
lazyOnloadyetarli — foydalanuvchi chat tugmasini sahifa ochilgandan 2 soniya keyin ko'rsa, hech narsa yo'qotmaydi.
Analitika
// app/layout.tsx
import Script from 'next/script'
export default function RootLayout({ children }: { children: React.ReactNode }) {
const GA_ID = process.env.NEXT_PUBLIC_GA_ID
return (
<html lang="uz">
<body>
{children}
{GA_ID && (
<>
<Script src={`https://www.googletagmanager.com/gtag/js?id=${GA_ID}`} strategy="afterInteractive" />
<Script id="ga-init" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_ID}');
`}
</Script>
</>
)}
</body>
</html>
)
}
- Inline skriptga
idmajburiy — Next.js uni kuzatib, takror qo'shmaydi - Root layout da — bir marta yuklanadi va sahifalar almashganda qayta yuklanmaydi
@next/third-parties
Google xizmatlari uchun tayyor, optimallashtirilgan komponentlar:
npm install @next/third-parties
import { GoogleAnalytics, GoogleTagManager } from '@next/third-parties/google'
<GoogleAnalytics gaId="G-XXXXXXX" />
import { YouTubeEmbed } from '@next/third-parties/google'
<YouTubeEmbed videoid="dQw4w9WgXcQ" height={400} />
YouTubeEmbed — YouTube ning og'ir iframe i o'rniga yengil "fasad": video faqat bosilganda yuklanadi.
Hodisalar
'use client'
import Script from 'next/script'
export function Xarita() {
return (
<>
<Script
src="https://api-maps.yandex.ru/2.1/?lang=uz_UZ&apikey=..."
strategy="lazyOnload"
onLoad={() => {
// skript yuklandi — xaritani yaratish
window.ymaps.ready(() => { /* ... */ })
}}
onError={(e) => console.error('Xarita yuklanmadi', e)}
/>
<div id="xarita" className="h-80" />
</>
)
}
| Hodisa | Qachon |
|---|---|
onLoad |
Skript birinchi marta yuklanganda |
onReady |
Yuklanganda va har safar komponent qayta mount bo'lganda |
onError |
Yuklanmasa |
onLoad, onReady, onError — faqat Client Component da (funksiya prop).
Faqat kerakli sahifada
// app/aloqa/page.tsx — xarita skripti faqat shu sahifada
import Script from 'next/script'
export default function Aloqa() {
return (
<>
<Script src="https://xarita.example/sdk.js" strategy="lazyOnload" />
{/* ... */}
</>
)
}
Skript faqat foydalanuvchi shu sahifaga kirganda yuklanadi.
[!WARNING] Har bir uchinchi tomon skripti — sizning saytingizda to'liq huquq bilan bajariladigan begona kod: u DOM ni, cookie larni (httpOnly dan tashqari), formalardagi ma'lumotlarni ko'ra oladi. Faqat ishonchli manbalardan qo'shing, kerak bo'lmaganlarini olib tashlang va iloji bo'lsa CSP (Content-Security-Policy) bilan ruxsat etilgan domenlarni cheklang (71-dars).
Rozilik (consent)
Ba'zi mamlakatlarda (Yevropa — GDPR) analitika va reklama skriptlarini foydalanuvchi rozilik bergandan keyin yuklash talab qilinadi:
'use client'
export function Analitika() {
const [rozi, setRozi] = useState(false)
useEffect(() => setRozi(localStorage.getItem('rozilik') === 'ha'), [])
if (!rozi) return null
return <GoogleAnalytics gaId="G-XXXXXXX" />
}
Tez-tez uchraydigan xatolar
1. Oddiy <script> tegi
<script src> JSX da — Next.js uni boshqarmaydi; sahifalar almashganda takrorlanishi yoki umuman ishlamasligi mumkin. next/script.
2. Inline skriptda id yo'q
Ogohlantirish va takroriy bajarilish ehtimoli.
3. Hammasiga beforeInteractive
Sahifa barcha skriptlarni kutadi — eng sekin variant. Faqat haqiqatan sahifadan oldin kerak bo'lganlar uchun.
Xulosa
next/script — uchinchi tomon skriptlarini boshqarish
beforeInteractive — juda kam, faqat root layout
afterInteractive — analitika (standart)
lazyOnload — chat, vidjetlar; imkon qadar kechroq
Inline skript — id majburiy
@next/third-parties — GoogleAnalytics, GTM, YouTubeEmbed (fasad)
onLoad / onReady / onError — Client Component da
Faqat kerakli sahifada; ishonchli manbalar, CSP, rozilik
Keyingi dars
59-dars: Caching — Request Memoization, Data Cache, Full Route Cache
Next.js ning to'rt qatlamli keshi — nima qachon keshlanadi va qanday yangilanadi.