Script tegi — defer, async, type="module" — farqlari
Muammodan boshlaylik
JavaScript faylni ulaysiz:
<head>
<script src="app.js"></script>
</head>
<body>
<button id="saqlash">Saqlash</button>
</body>
// app.js
document.getElementById('saqlash').addEventListener('click', ...);
Konsolda xato: Cannot read properties of null. Tugma bor-ku! Yana bir muammo: katta skript yuklanayotganda sahifa bir necha soniya bo'sh oq turadi.
Ikkalasining sababi — brauzer <script> ni qanday o'qishida. Uni boshqarish uchun defer, async va type="module" atributlari bor.
Oddiy script — sahifani to'xtatadi
Brauzer HTML ni yuqoridan pastga o'qiydi. Oddiy <script> ga duch kelganda:
HTML o'qish ──────■ to'xtadi ──────────────────────────■ davom ─────▶
│ │
└─ skriptni yuklash ── bajarish ─────┘
- HTML o'qishni to'xtatadi
- Faylni yuklaydi (sekin internetda — soniyalar)
- Bajaradi
- Shundan keyingina HTML ni davom ettiradi
Natijalar:
- Skript bajarilayotganda pastdagi HTML hali yo'q —
getElementById('saqlash')→null(1-muammo) - Yuklash paytida sahifa chizilmaydi — bo'sh ekran (2-muammo)
Bu xatti-harakat "render-blocking" (chizishni bloklovchi) deb ataladi.
Eski yechim — body oxirida
<body>
<button id="saqlash">Saqlash</button>
<script src="app.js"></script> <!-- eng oxirida -->
</body>
HTML allaqachon o'qilgan, tugma mavjud. Ishlaydi — lekin brauzer skriptni yuklashni faqat HTML oxiriga yetgandagina boshlaydi, vaqt yo'qotiladi. Zamonaviy yechim — defer.
defer — keyinga qoldirish
<head>
<script src="app.js" defer></script>
</head>
HTML o'qish ──────────────────────────────────────■ tugadi ── bajarish
│
└─ skriptni yuklash (parallel) ─┘
- Skript parallel yuklanadi — HTML o'qish to'xtamaydi, sahifa chiziladi
- HTML to'liq o'qilgandan keyin bajariladi (
DOMContentLoadeddan oldin) — barcha elementlar mavjud - Bir nechta
deferskript — HTML dagi tartibda bajariladi
<script src="kutubxona.js" defer></script>
<script src="app.js" defer></script> <!-- har doim kutubxona.js dan keyin -->
Ikkala muammo hal, va skript <head> da tursa ham, eng erta yuklanadi.
[!TIP] Sahifa elementlari bilan ishlaydigan skriptlar uchun —
defer,<head>ichida. Bu bugungi standart yondashuv. DevDocs saytida ham kod rangini beruvchi (highlight.js) skriptlar shunday ulangan.
async — tayyor bo'lishi bilan
<script src="analytics.js" async></script>
HTML o'qish ──────────────■ to'xtadi ■ davom ─────────────────▶
│ │ │
└─ yuklash ─ bajarish (yuklanishi bilan)
- Parallel yuklanadi
- Yuklanishi bilan darhol bajariladi — HTML o'qishni qisqa to'xtatib
- Tartib kafolatlanmaydi — qaysi biri oldin yuklansa, o'sha oldin bajariladi
- Bajarilganda sahifa to'liq tayyor bo'lmasligi mumkin
Qachon: sahifaga va boshqa skriptlarga bog'liq bo'lmagan mustaqil skriptlar — analitika (Google Analytics, Yandex Metrika), reklama, chat vidjetlari.
Uchalasini taqqoslash
| Oddiy | defer |
async |
|
|---|---|---|---|
| HTML o'qishni to'xtatadimi | ✅ Ha (yuklash + bajarish) | ❌ Yo'q | Faqat bajarish paytida |
| Qachon bajariladi | Darhol | HTML to'liq o'qilgandan keyin | Yuklanishi bilan |
| Tartib | HTML tartibida | HTML tartibida | Tasodifiy |
| DOM tayyormi | Faqat yuqoridagi qismi | ✅ To'liq | Kafolat yo'q |
| Qachon | Kamdan-kam | Asosiy ilova kodi | Mustaqil: analitika, reklama |
type="module" — zamonaviy JavaScript
<script type="module" src="main.js"></script>
Fayl ES modul sifatida yuklanadi:
// main.js
import { hisobla } from './utils.js';
import { marked } from 'https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js';
hisobla();
Modul skriptlari:
- Avtomatik
deferxatti-harakatida —deferyozish shart emas import/exportishlatish mumkin- O'z qamrovida — modul ichidagi o'zgaruvchilar global emas (
windowga tushmaydi) - Har doim strict mode da
- Faqat server orqali ishlaydi (
file://dan to'g'ridan-to'g'ri ochilganda — CORS xatosi;npx viteyoki VS Code Live Server ishlating)
Vite, Next.js kabi zamonaviy vositalar aynan type="module" ga asoslangan — DevDocs ham: <script type="module" src="/src/main.js">.
Modulni async ham qilish mumkin: <script type="module" async> — yuklanishi bilan bajariladi.
nomodule — eski brauzerlar uchun
<script type="module" src="app.modern.js"></script>
<script nomodule src="app.legacy.js"></script>
Modullarni tushunmaydigan juda eski brauzerlar faqat nomodule ni yuklaydi, zamonaviylari — uni e'tiborsiz qoldiradi. Bugun kamdan-kam kerak.
Ichki (inline) skript
<script>
document.documentElement.dataset.theme = localStorage.getItem('theme') || 'light';
</script>
defervaasyncichki skriptlarda ishlamaydi (faqatsrcbilan)- Kichik, sahifa chizilishidan oldin bajarilishi kerak bo'lgan kod uchun: masalan, qorong'i rejimni sahifa "miltillamasdan" o'rnatish
Katta kodni ichki skriptga yozmang — u keshlanmaydi va HTML ni og'irlashtiradi.
Tavsiyalar
<head>
<meta charset="UTF-8">
<title>...</title>
<link rel="stylesheet" href="style.css">
<!-- Ilova kodi -->
<script type="module" src="main.js"></script>
<!-- Yoki oddiy skript -->
<script src="app.js" defer></script>
<!-- Mustaqil uchinchi tomon skriptlari -->
<script src="https://analytics.example.com/script.js" async></script>
</head>
Nima uchun shunday?
Nima uchun oddiy <script> standart holatda HTML o'qishni to'xtatadi — bu sahifani sekinlashtirishi aniq-ku?
Chunki skript HTML ni o'zgartirishi mumkin. Eski document.write() funksiyasi skript turgan joyga to'g'ridan-to'g'ri yangi HTML yozardi — va brauzer skriptni bajarmasdan turib keyingi HTML qanday bo'lishini bila olmasdi. Shuning uchun xavfsiz yo'l — to'xtab kutish edi. Zamonaviy kodda document.write() deyarli ishlatilmaydi, lekin orqaga moslik uchun standart xatti-harakat o'zgartirilmadi — buzilib qoladigan millionlab eski saytlar bor. Buning o'rniga defer va async qo'shildi: siz brauzerga "bu skript HTML ni yozmaydi, kutish shart emas" deb aytasiz va sahifa tezlashadi.
Xulosa
Eslab qoling:
- Oddiy
<script>— HTML o'qishni to'xtatadi; pastdagi elementlar hali yo'q, sahifa bo'sh turadi defer— parallel yuklash, HTML to'liq o'qilgandan keyin, tartibda bajarish — asosiy kod uchunasync— parallel yuklash, yuklanishi bilan bajarish, tartibsiz — analitika, reklamatype="module"— avtomatik defer,import/export, o'z qamrovi; server orqali ishlaydi- Ichki skriptda
defer/asyncishlamaydi - Tavsiya: skriptlar
<head>da,deferyokitype="module"bilan
Keyingi dars
13-dars: Semantik HTML va SEO — qanday bog'liq