L Art du Pré-chargement : Éliminer le "Flash" de Thème avec JavaScript et CSS
شائع شدہ: 15 November 2025
خلاصہ
یہ تفصیلی تکنیکی مضافہ میں ہم دیکھتے ہیں کہ ธیم (light/dark) سیلیٹر کیسے ملٹی کریں، بے ضروری جھلمکاؤ کے بغیر جو صفحے کی لوڈ کے دوران پیش آتا ہے۔ ہم براؤزر کے رینڈر سائکل کا تفصیلی تجزیہ کرتے ہیں، FOUC (Flash of Unstyled Content) کے عمیق اسباب کا تجزیہ کرتے ہیں، اور ہم سائنکروس pre‑load پر مبنی مضبوط حل پیش کرتے ہیں میں۔<head>۔ یہ تکنیک ایک سموثر اور پیشہ ورانہ صارف تجربہ فراہم کرتی ہے۔
مسئلہ: یہ لعنتی ٹھیم کا جھلمکاؤ
صارف کے تجربے کے لیے ایک بُرا خواب
منظر Tasveer لیں: آپ نے اپنی ویب ایپلیکیشن کے لیے ایک خوبصورت دارك थीم ڈیزائن کرنے کے لئے گھنٹے گزار دیے۔ رنگوں مکمل طور پر متوازن ہیں، 대비 کے سطح پر بہترین ہے، اور آپ کے صارفین اس اختیار سے محبت کرتے ہیں۔ ليکن ایک شرmandeہ کن مسئلہ ہے: ہر بار صفحہ ریلوڈ ہونے پر، ایک جزوی سیکنڈ کے لیے، ڈیفالٹ ہلکا theme ظاہر ہوتا ہے، قبل کہ دارك theme اس کی جگہ لے لیتا ہے۔
یہ بصری 'فлэش'، اگرچہ مختصر ( گاهی 100ms سے کم )، انسانی آنکھ کے لیے فوراً محسوس ہوتا ہے اور ایک ناہم تجربہ بناتا ہے۔ ڈارک تھیم یا بصری آرام یا رسائی کے لیے چنے گئے استعمال کرنے والوں کے لیے، یہ جھلمل دردناک بھی ہو سکتا ہے، خاص طور پر کم روشنی والے ماحول میں۔
FOUC : ایک پرانا ویب مسئلے
یہ phenomenon ایک قسم ہے جسے "`Flash of Unstyled Content` (FOUC)" کہا جاتا ہے، ویب ڈویلپمنٹ کی ایک کلاسیکی مسئلے جو CSS کے ابتدائی اوقات سے متصالح ہے۔ FOUC اس وقت پیش آتا ہے جب براؤزر temporarily HTML کے محتوى کو CSS کے اسٹائلز لاگ किए बिना دکھاتا ہے، جس سے غیر اسٹائلڈ مواد کا فلیش پیدا ہوتا ہے۔
ہمارے مخصوص صورت حال میں، ہم پوری طرح غیر‑استائل شدہ محتوا کے بارے میں بات نہیں کر رہے ہیں، بلکہ ایک کے بارے میںغلط تھیم کی چمک(FOWT) - مواد اسٹائل کی گئی ہے، لیکن غلط थीم کے ساتھ۔ یہ خاص طور پر ناگوار ہے کیونکہ یہ دکھاتا ہے کہ ہماری ایپلیکیشن "oublie" استعمال کرنے والی کی ترجیح کو ہر صفحے کے لوڈ پر۔
معیاریت کی ادراک پر اثر
یہ مسئلا، اگرچہ ٹیکنیکل ہے، آپ کے ایپلیکیشن کی کیفیت کے ادراک پر اہم اثرات ڈالتا ہے:
صقیلگی کی کمیجھلملاہٹ سے محسوس ہوتا ہے کہ ایپلیکیشن مکمل نہیں یا بهتر طرح سے optimize نہیں کی گئی۔ صارف اکثر اس چھوٹی بصری نقصانات کو عام نقصان پیشہ ورانگی سے جوڑتے ہیں۔
اتساق میں انقطاع: لاگ لگے 'بھول' جاتی ہے استعمال کرنے والے کی ترجحات، جس سے انٹرفیس اور امیدوں کے درمیان بے synchronization کا احساس پیدا ہوتا ہے۔
بصری تھکاوٹروشَنائی کے حساس استعمال کرنے والوں یا میگرن سے جھپٹے والے افراد کے لیے، یہ چمکدار فлэش صرف ایک سادہ زیبائی‑مرتبط بے‑اراحتی سے زیادہ ہو سکتا ہے۔
محسوس کردگیآئرانیک، اگرچہ آپ کی ویب سائیٹ جلد سے لوڈ ہوتی ہے، یہ جھلملاٹ سست یا کم متجاوب application جیسا محسوس دلایا سکتا ہے۔
مسئلہ کی تکنیکی تجزیہ
آئسے مسئلے کو حل کرنے کا طریقہ سمجھنے کے لیے، پہلے اس کا سبب سمجھنا ضروری ہے۔ جھلملات تین اہم واقعات کے درمیان وقت کی انحراف کی وجہ سے ویب پیج کے زندگی چکر میں پیش آتی ہیں۔
-
HTML کا ابتدائی پارسنگبراؤزر آپ کے پیج کی ساخت پڑھتا اور تجزیہ کرتا ہے
-
CSS اسٹائلز کا استعمالبراؤزر CSS کے قاعدے لاگو کرتا ہے اور بصری rendar کا حساب لگاتا ہے
-
JavaScript کی نفيذ: آپ کا کوڈ جو theme بدلتا ہے چلتا ہے
مشکل یہ پیش آتی ہے جب واقعہ نمبر 3 (JavaScript کی execution) اس وقت آتا ہے جب براؤزر پہلے سے ہی واقعہ نمبر 2 (style کی application) کا شروع یا اختتام کر چکا ہوتا ہے۔ اس موقع پر براؤزر نے پہلے سے ہی فیصلہ کر لیوتا ہے کہ کون سا تمہ دکھانا ہے اور آپ کا کوڈ پہلا رینڈر ہونے سے پہلے اس پر اثرانداز ہونے کے لیے Bohut دیر سے پہنچتا ہے۔
کلاسیک اسکرپٹ کیوں کافی نہیں ہے؟
حدسی رویہ لیکن غیر مؤثر
ایک ڈویلپر کے لیے سب سے طبیعی انحصار یہ ہوگا کہ وہ ہمارے… کے آخر میں ایک سکرپٹ رکھے۔`<body>`جو استعمال کرنے والے کے محفوظ تمہ کی جانچ کرتا ہے اور اسے لاگو کرتا ہے۔ یہ رویہ ویب کی riwajati behteen maSLaaqon ka pAltaa hai jo script ko safah ke akhir mein load karne ki sifaarish karte hain taake render block na ho.
// À la fin de <body> - L'APPROCHE INSUFFISANTE
document.addEventListener('DOMContentLoaded', () => {
const theme = localStorage.getItem('preferred-theme');
if (theme === 'dark') {
document.documentElement.setAttribute('data-bs-theme', 'dark');
}
});
یہ طریق کار پہلے نظر میں منطقی لگتی ہے۔ ہم DOM کے تیار ہونے کا انتظار کرتے ہیں، پھر ہم ธีม لاگو کرتے ہیں۔ سادہ، نہیں؟ متاسفانه، یہ سادگی بنیادی خرابی کو چھپاتی ہے جو براؤزر کے رینڈرنگ سائیکل کے ٹائمنگ سے متعلق ہے۔
DOMContentLoaded ایونٹ کو سمجھیں
واقعہ`DOMContentLoaded`یہ جب HTML کا ابتدائی ڈॉकومینٹ مکمل طور پر لوڈ ہو کر براؤزر سے تجزیہ کر لیا جاتا ہے،فورااسٹائل شیٹس، تصاویر، اور سب فریمز کے لوڈ ہونے کا ختم ہونا۔ یہ ایک اہم نقطہ ہے جسے سمجھنا ضروری ہے۔
یہ واقعات کی نمادینی تسلسل ہے:
-
براؤزر HTML ڈاؤنلوڈ کرنے شروع کر دیتا ہے۔
-
یہ HTML کا تجزہ کرتا ہے جیسے اسے دریافت کیا جاتا ہے
-
وہ ٹیgzكشف کرتا ہے`<link>`CSS کے لیے اور انہیں ڈاؤنلوڈ کرنا شروع کریں
-
وہ ٹیگس کا دریافت کرتا ہے`<script>`اور ان کو 실행 کرتا ہے (ان کے نوع اور خصوصیات کے مطابق)
-
وہ DOM (Document Object Model) بناتا ہے
-
موقع
DOMContentLoadedواقع ہوتا ہے -
وہ اسٹائلز لاگو کرنے اور لايآؤٹ بنانے کا کام جاری رکھتا ہے
-
پہلا paint (نمائش) پیش آتا ہے
-
واقعہ`load`یہ تمام وسائل لوڈ ہونے پر چالہ ہوتا ہے
مسئلہ؟ سٹاپ 6 (DOMContentLoaded) اور سٹاپ 8 (پہلا پینٹ) کے درمیان، براؤزر پہلے سے ہی فیصلہ کر چکا ہے کہ صفحہ کیسے ڈسپلے کرنا ہے۔ اگر آپ کا ٹیم چینج سکرپٹ سٹاپ 6 پر چلتا ہے، تو پہلے سے ہی پہلے دکھاوے سے بچنے کے لیے ڈیفالٹ اسٹائلز کے ساتھ زیادہ دیر ہو چکی ہے۔
Render Blocking کا مسئلہ
واقعیت میں، ٹائمزنگ مزید پیچیدہ ہے۔ موجودہ براؤزر perceived performance کو بہتر بنانے کے لیے متقاعد اور پیچیدہ optimisation تکنیکیں استعمال کرتے ہیں۔ وہ پہلے پینٹ (First Contentful Paint) کو ممکنہ سب سے جلد کرنے کی کوشش کرتے ہیں تاکہ صارف اسکرین پر کچھ دیکھ سکے۔
CSS "render-blocking" بصورت افتراضي، جس کا مطلب ہے کہ براؤزر پہلے پیینٹ کرنے سے قبل اسٹائل شیٹس ڈاؤنلوڈ اور پرس کرنے کا انتظار کرتا ہے۔ یہ معقول ہے: ہم غیر سٹائل شدہ مواد دکھانا نہیں چاہتے۔
یہاں پھنسا یہ ہے: جب براؤزر پہلی بار یہ سی ایس ایس اسٹائلز لاگو کرتا ہے، تو وہ موجودہ ڈوم کی حالت کے مطابق عمل کرتا ہے۔ اگر صفت`data-bs-theme`ابھی تک ٹاگ پر مُعَرَّف نہیں ہے`<html>`, براؤزر ڈیفالٹ اسٹائلز لاگو کرے گا (عام طور پر ہلکا ธีม).
پھر، جب آپ کا سکرپٹ چلتا ہے اور یہ خصوصیت تبدیل کرتا ہے، براؤزر کو :
-
اس تبدیلی سے متاثرے اسٹائلز کا dubara حساب لگائیں
-
ضرورت پڑنے پر لیٹ دوبارہ بنائیں
-
متاثر ہونے والے عناصر کو دوبارہ رنگیں
یہ ری کیلکول اور رے پینٹنگ کا عمل ہے جو مرئی جھلملاہٹ پیدا کرتا ہے۔
مشکل کی ویژوالائزیشن
یہمشکل تسلسل کو سمجھنے کے لیے، ایک تفصیلی تسلسل ڈائگرام کا جائزہ لیں:
@startuml
actor Utilisateur
participant Navigateur
participant "Parser HTML" as Parser
participant "CSSOM" as CSS
participant "Script.js (fin de body)" as Script
participant "Render Engine" as Render
Utilisateur -> Navigateur: Demande la page
activate Navigateur
Navigateur -> Parser: Parse le HTML
activate Parser
Parser -> CSS: Découvre et charge les CSS
activate CSS
Parser -> Parser: Construit le DOM
Parser -> Navigateur: DOM Ready (DOMContentLoaded)
deactivate Parser
CSS -> CSS: Parse les feuilles de style
CSS -> Render: CSSOM Ready
deactivate CSS
activate Render
Render -> Render: Calcule les styles avec data-bs-theme=""
note right: Thème par défaut (light)
Render -> Navigateur: Premier Paint (Thème Clair)
note right: L'utilisateur voit le thème clair
deactivate Render
Navigateur -> Script: Exécute le script
activate Script
Script -> Script: Lit localStorage
Script -> Navigateur: setAttribute('data-bs-theme', 'dark')
deactivate Script
activate Render
Render -> Render: Recalcule les styles avec data-bs-theme="dark"
note right: Thème sombre
Render -> Navigateur: Repaint (Thème Sombre)
note right: Clignotement visible
deactivate Render
deactivate Navigateur
@enduml
یہ ڈائرگرام مسئلے کو واضح طور پر دکھاتا ہے: پہلا پینٹ اس وقت ہوتا ہے جب ہمارا اسکرپٹ مناسب تھیيم سیٹ کرنے کا موقع نہیں ملتی۔ بعد میں ہونے والا رپینٹ مرئی جھلملاتی پیدا کرتا ہے۔
غیر مؤثر حل کرنے کی کوششیں
چند طریقوں کو اس مسئلے کو حل کرنے کی کوشش کی گئی، لیکن اکثر کے اپنے‑اپنے نقصانات ہیں:
Approach 1: لود ہونے تک مواد کو چھپا کریں
body {
opacity: 0;
transition: opacity 0.3s;
}
body.loaded {
opacity: 1;
}
یہ طریقہ JavaScript کے صحیح ٹھی밂 کو سیٹ کرنے تک تمام مواد کو چھپا رکھتا ہے۔ masalah؟ یہ مصنوعی طور پر مواد کی دکھائی کو دیرانداز کرتا ہے، جس سے سایت زیادہ سست لگنے کا احساس ہوتا ہے۔ علاوہً، اگر JavaScript غیر فعال کر دیا جائے، تو صارف کو کچھ بھی نہیں دikhái دےتا!
طریقہ 2: لوڈر/اسپنر استعمال کریں
Approach 1 کی طرح، لیکن بار‑لوڈر سپنر کے ساتھ۔ یہ مسئلے کو ڈھپکت ہے لیکن اصل عمل بہتری نہیں کرتی اور بے ضروری محسوس ہونے والی دیر شامل کرتی ہے۔
طریقہ 3: پیش فرض ڈارک تھییم
کسی ڈویلپر ڈارک ثیم کو CSS میں ڈیفالٹ کے طور پر معین کرتے ہیں۔ یہ ڈارک ثیم کے صارفین کے لیے جھمکنا روک دیتا ہے، لیکن روشن ثیم کے صارفین کے لیے برعکس مسئلہ پیدا کرتا ہے۔
یہ تمام اندراجات مناسب نہیں ہیں کیونکہ وہ بیماری کے علامت پر توجہ مرکوز کرتی ہیں، بنیادی سبب پر نہیں۔
حقیقی حل : جلدی عمل کریں
اس مسئلے کو حل کرنے کی کلید یہ ہے کہ ہم کو یہ جاننا ہے کہ ہم کو اس خصوصیت کو تعریف کرنا ہوگا۔data-bs-theme پہلےکہ براؤزر CSS اسٹائلز لاگو کرنے شروع نہیں کرتا۔ اس کا مطلب یہ ہے کہ ہمارا سکرپت پیج کے زندگی цикیل میں پہلے اجرا ہونا چاہیے، اور یہی وہ چیز ہے جو ہم اگلے حصے میں جانچیں گے۔
حل: پہلے بارگزاری (Early Loading)
اساسی اصول
ہماری جھلملاوٹ کا خوبصورت حل ایک سادہ لیکن طاقتور اصول پر مبنی ہے :ایپلیکیشن کی حالت کو براؤزر کے رینڈرنگ پروسیس کے ساتھ ہم آہنگ کرناصفحے کے لوڈ ہونے کے بعد themes کو سیٹ کرنے کا انتظار کرنے کی بجائے، ہمیں فوراً themes کو سیٹ کرنا ہوگا۔دورانبار لوڈ، حتی سے پہلے CSS کے اسٹائل لاگو نہیں کیے گئے۔
یہApproach 'Early Loading' یا 'Synchronous Preloading' keh kahī jātī hai web development ke istilahāt mein۔ Idea yeh hai ke hum apni theme detection logic ko page ke life cycle mein sab se pehle mumkin had tak execute karte hain, ideally tag ke andar۔<head>, حتی براؤزر سے پہلے CSS فائلز ڈاؤنلوڈ کرنے سے پہلے۔
کیوں <head> مثالی جگہ ہے
Le `<head>`ایک HTML دستاویز براؤزر کے ذریعے سِیکوئینسی طور پر، اوپر سے نیچے تک محروس کیا جاتا ہے۔ ہر عنصر اس کے ظہور کے مطابق ترتیب میں محروس کیا جاتا ہے۔ یہ خصوصیت ہماری حل کے لیے ضروری ہے۔
جیسے براؤزر ایک ٹیگ سے ملتا ہے`<script>`کے اندر`<head>`خصائص کے بغیر`async` ou defer, il :
-
HTML کے پارسنگ کو رک دیں
-
اسکرپٹ ڈاؤنلوڈ کریں(اگر externe) یا بستر (اگر ان لائن)
-
اسکریپت فوراً چلائیں
-
HTML کا parsing دوبارہ شروع کریں
یہ رویہ، اکثر کارکردگی کے مسئلے کے طور پر سمجھا جاتا ہے (جس کی وجہ سے سکرپٹس کو صفحے کے آخر میں رکھنے کی مشورہ ملتی ہے)، اس مخصوص صورت میں ہمارا حليف بن جاتا ہے۔ ہماری ٹیم ڈٹیکشن سکرپٹ کو صفحے کے آغاز پر رکھ کر`<head>`, ہم یہ ضمانت دیتے ہیں کہ یہ براؤزر کے ٹیگز سے ملاقات کرنے سے پہلے نفذ ہوتا ہے`<link>`ہمارے اسٹائل شیٹ.
텐 couche حل کی معماریت
همारा مكمل حل تین متبادل جدولخ سے بناؤا ہے, ہر ایک مخصوص rôle ادا کر رہا ہے :
Layer 1 : Persistence (localStorage) یہ لیئر سشنز کے درمیان صارف کے انتخاب کو محفوظ کرنے اور دوبارہ لانے کا ذمہ دار ہے۔
طبقہ 2 : جلدی ہم آہنگی (<head> میں این لائن اسکرپت) یہ لیئر ایپلیکیشن کے وضع کو DOM کے ساتھ ابتدائی رینڈر سے پہلے ہم آہنگ کرتی ہے۔
طبقہ 3 : ریاکٹِیو اسٹائلز (CSS میں ایٹریبیوٹ سلیکٹرز) یہ لیر ویجول سٹائلز تعین کرتی ہے جو لیر 2 کے ذریعے معین کردہ حالت پر مبنی ہیں۔
ابھی ہر لایر کی تفصیل سے استكشاف کریں۔
مرحلہ 1: استعمال کرنے والے کا انتخاب محفوظ کریں
localStorage : آپ کی مستمر यादاشت
Le localStorage`یہ Web Storage API ہے جو key-value pairs (کلی‑قدر) کو براؤزر میں مستقل طور پر محفوظ کرنے کی اجازت دیتا ہے۔ کوکیز کے برعکس، ڈیٹا کا`localStorage:
-
انہیں سرور پر خودکار طور پر کبھی بھی نہیں بھیجا جاتا
-
ان کی ذخیرہ کرنے کی صلاحیت زیادہ ہوتی ہے (عام طور پر 5-10 MB)
-
ان کی کوئی ختم ہونے کی تاریخ نہیں ہوتی (واضح حذف تک قائم رہتے ہیں)
-
انہیں پروٹوکول اور ڈومین تک محدود کیا جاتا ہے (Same-Origin Policy)
ہمارا استعمال کا مثال، ال`localStorage`ہے مکمل کیونکہ :
-
ہم سرور کے ساتھ یہ معلومات کا اشتراک کرنے کی ضرورت نہیں ہے
-
ہم چاہتے ہیں کہ ترجیح permanent طور پر برقرار رہے
-
مطلوب شدہ ذخیرہ کرنے کا سائز بہت کم ہے (چند بائٹ)
ٹھیم بیکاپ کی تنفيد
یہ ہے کہ ہم صارف کا انتخاب محفوظ کرتے ہیں جب وہ theme تبدیل کرتا ہے:
// Fonction complète pour changer le thème
function setTheme(newTheme) {
// Validation de l'entrée
if (!['light', 'dark', 'auto'].includes(newTheme)) {
console.error('Thème invalide:', newTheme);
return;
}
try {
// Sauvegarde dans localStorage
localStorage.setItem('preferred-theme', newTheme);
// Application immédiate dans le DOM
document.documentElement.setAttribute('data-bs-theme', newTheme);
// Dispatch d'un événement personnalisé pour notifier d'autres composants
window.dispatchEvent(new CustomEvent('theme-changed', {
detail: { theme: newTheme }
}));
console.log('Thème changé:', newTheme);
} catch (error) {
console.error('Erreur lors de la sauvegarde du thème:', error);
// Fallback : on applique quand même le thème visuellement
document.documentElement.setAttribute('data-bs-theme', newTheme);
}
}
// Exemple d'utilisation avec un bouton
document.getElementById('theme-toggle').addEventListener('click', () => {
const currentTheme = document.documentElement.getAttribute('data-bs-theme') || 'light';
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
setTheme(newTheme);
});
خطا کی حالات کا انتظام
یہ ان صورتوں کو سنبھالنا انتہائی ضروری ہے جہاں`localStorage`دستیاب یا قابل رسائی نہیں ہے۔ کئی منظرنامے اس تک رسائی کو روک سکتے ہیں`localStorage`Please provide the text you would like me to translate.
سخت خفیہ نیویگیشنسافاری برائیوزنگ کے خفیہ موڈ میں ایک استثنا اٹھاتی ہے`QuotaExceededError`کے اندر لکھنے کی कोशिशوں کے دوران`localStorage`.
خفیہ تنظیماتکچھ براؤزروں یا رازداری کے اضافے پہنچ کو بلوک کر سکتے ہیں`localStorage`.
دومین کی حدودیتیں : Le `localStorage`پروتوكول پر وصول نہیں`file://`کچھ براؤزرز میں.
اسٹوریج جگہ پر بھرپور: اگرچہ نادر، اسٹوریج کی جگہ پوری طرح بھری جا سکتی ہے۔
لہذا ہمارا کوڈ ایک بلاک استعمال کرتا ہے`try…catch`ان حالات کو خوشگوار انداز سے منظم کرنے کے لیے، موضوع تبدیلی کی سہولت جاری رکھتے ہوئے، جبکہ پوسٹنسنس دستیاب نہ ہو۔
ترقی یافتہ پائیداری کی استراتیجیاں
زیادہ پیچیدہ طلبوں کے لیے، آپ اضافی حکمت عملیوں پر غور کر سکتے ہیں :
سروئر ہم آہنگی (اختیاری)
async function setTheme(newTheme) {
// Sauvegarde locale immédiate
localStorage.setItem('preferred-theme', newTheme);
document.documentElement.setAttribute('data-bs-theme', newTheme);
// Synchronisation serveur en arrière-plan (si l'utilisateur est connecté)
if (userIsAuthenticated()) {
try {
await fetch('/api/user/preferences', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ theme: newTheme })
});
} catch (error) {
console.warn('Échec de la synchronisation serveur:', error);
// L'échec n'est pas critique car la préférence est déjà sauvegardée localement
}
}
}
یہapproach ربط شدہ استعمال کرنے والوں کے لیے ڈیوائسوں کے درمیان ترجیحوں کو ہم آہنگ کرنے کی اجازت دیتا ہے، اور مقامی فوری جواب دینے کی قابلیت کو محفوظ رکھتا ہے۔
مرحلہ 2: <head> میں پری-لوڈ سکرپت
حل کا دل
یہاں جادو سچمچ سے کام کرتی ہے۔ ہم ایک چھوٹا اسکریپٹ رکھیں گے۔ان لاينہماری میں مستقیماً`<head>`, hamari sabhi tags se pehle`<link>`یہ اسکرپٹ ارادی طور پر مینیمل، خود مختار، اور ممکنہ حد تک جلد chalنے کے لیے بنایا گیا ہے۔
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mon Site Incroyable</title>
<!-- ==========================================
NOTRE SCRIPT MAGIQUE DE PRÉ-CHARGEMENT
Ce script DOIT être le premier élément
dans le <head> après les meta tags
========================================== -->
<script>
// IIFE pour ne pas polluer le scope global
(function() {
'use strict';
try {
// Lecture de la préférence sauvegardée
const savedTheme = localStorage.getItem('preferred-theme');
// Si une préférence existe, on l'applique immédiatement
if (savedTheme) {
document.documentElement.setAttribute('data-bs-theme', savedTheme);
}
// Optionnel : Détecter la préférence système si aucune sauvegarde
else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.setAttribute('data-bs-theme', 'dark');
}
// Sinon, le thème par défaut du CSS sera utilisé (généralement 'light')
} catch (error) {
// En cas d'erreur (localStorage bloqué, etc.), on log discrètement
// et on laisse le thème par défaut s'appliquer
console.warn('Impossible de charger la préférence de thème:', error);
}
})();
</script>
<!-- FIN DU SCRIPT MAGIQUE -->
<!-- Les feuilles de style sont chargées APRÈS le script -->
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/styles.css">
<!-- Autres ressources du head -->
<link rel="icon" href="favicon.ico">
</head>
<body>
<!-- Contenu de la page -->
</body>
</html>
اسکریپٹ کی تشریح: ہر لکنی لائن گنتی ہوتی ہے
چلیے اس سکرپٹ کو لائن بای لائن تجزیہ کرتے ہیں۔ ہر ڈیزائن فیصلہ کو سمجھنے کے لیے :
IIFE (فوری طور پر بپレス ہونے والی فانکشن ایکسپرشن)
(function() {
// ...
})();
یہ ڈھانچہ ایک فنکشن بناتی ہے جو فوری طور پر چلتا ہے۔ کیوں؟ تاکہ ہم اپنی متغیرات کو لوکل سkope میں علیحدہ کر سکیں اور عالمی سkope کو آلودہ ہونے سے بچ سکیں۔ اگرچہ ہم صرف`const`(جس کا بلاک سkoپ ہے), IIFE ایک اچھی عمل ہے جو ہماری نیتوں واضح بناتا ہے اور اسموں کے ممکن تصادم سے حفاظت کرتا ہے۔
سٹریکٹ مود
'use strict';
یہ ہدایت JavaScript کے سٹرکٹ موڈ کو فعال کرتی ہے، جو: - غیر تصریح شدہ متغیرات کے استعمال پر پابندی - خطرناک آپریشنز کے لیے غلطی بناتا ہے - بعضی جاوا اسکرپٹ انجنوں میں کارکردگی کو بہتر بناتا ہے
ایسا حساس سکرپٹ جیسا یہ، ہم سب سے زیادہ سکیورٹی چاہتے ہیں۔
try…catch بلوک
try {
// Code principal
} catch (error) {
console.warn('Impossible de charger la préférence de thème:', error);
}
یہ بلک بالکل اہم ہے۔ یہ یقینی بناتا ہے کہ اگر کوئی چیز غلط ہو جائے (localStorage مسدود، ناممکن سینٹکس خرابی وغیرہ) تو ہمارا سکرپٹ پوری صفحے کا لوڈ روک نہیںے گا۔ استعمال کرنا`console.warn`بلکہ`console.error`یہ بتاتا ہے کہ یہ ایک غیرحرجی مسئلہ ہے۔
localsStorage کی پڑھائی
const savedTheme = localStorage.getItem('preferred-theme');
یہ لائن کچھ مخصوص سیاقات (سفاری کی سخت خفیہ ریموتنگ) میں ایک استثنا پراہنی ہو سکتی ہے۔ اس لیے اسے try…catch بلوک میں رکھا گیا ہے۔
شرطی ایپلیکیشن
if (savedTheme) {
document.documentElement.setAttribute('data-bs-theme', savedTheme);
}
ہم theme کو صرف تو لاگو کرتے ہیں جب ہم نے اسے محفوظ شدہ پایا ہو؛ ورنہ، ہم CSS کو اپنی ڈیفالٹ theme استعمال کرنے دیتے ہیں۔ یہ اندراز JavaScript میں ہارڈ کوڈ شدہ ڈیفالٹ قيمة سے زیادہ مضبوط ہے۔
نظام ترجیح کی تشخیص (ایجائز)
ایک اختیاراتی لیکن خوبصورت بہتری یہ ہے کہ آپ کے ایپلیکیشن میں، صارف کے عمل ہونے والے سسٹم کی تھیم ترجیح کا پتہ لگایا جائے، اگر وہ اب تک اپنی ایپلیکیشن میں واضح اختیار نہیں کیا :
else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.setAttribute('data-bs-theme', 'dark');
}
یہ فیچر Media Query استعمال کرتا ہے`prefers-color-scheme`system کو پوچھنے کے لئے. macOS, Windows 10+, iOS, اور آندروید کے جدید نسخے پر، یہ کوئری صارف کے نظام کی ترجیح واپس کرتی ہے۔
مفائد : - پہلا بازدید سے شخصیاتی تجربہ - مستعمل کے نظام کے ماحول سے مطابقت - پہلی ویزٹ کے لیے کوئی اسٹوریج ضروری نہیں
ملاحظات : - تمام براؤزرز اس فیچر کو سپورٹ نہیں کرتے (مگر 2020 سے اس کا سپورٹ شاندار ہے) - تصدیق`window.matchMedia`مطابقت کو یقینی بناتا ہے - صارف ہمیشه یہ اختیار اوورلوڈ کر سکتا ہے
عملکردگی : یہ اسکرپت تیز کیوں ہے؟
ہمارا پیش‑لوڈنگ سکرپت بے مثالی رفتار کرنے کے لیے بنایا گیا ہے :
حدّ کم ازمائی سائز: تقریباً 300 بائٹ غیر مینوفائیڈ، 200 بائٹ مینوفائیڈ۔ یہ کسی بھی تصویر یا جاوا اسکرپٹ لائبریری کی نسبت معذورات سے زیادہ نہیں۔
ان لائن: کوئی اضافی HTTP ریکوئسٹ نہیں ہے۔ اسکرپٹ HTML میں ہے، اس لیے یہ فوری طور پر دستیاب ہے۔
سادہ ہمמן اعمالکلید کی پڑھنا localStorage میں (بہت tez عمل) اور DOM کی صفت کی ترمیم (براؤزر کی داخلی عمل).
کسی انحصار نہیںکوئ فریم ورک نہیں، کوئی لائبریری نہیں، صرف سادہ جاوا اسکریپت۔ شروع ہونے کا وقت نہیں، انحصارات کا پارسنگ نہیں۔
ایک بار تنفیذاس اسکرپٹ ایک بار لُوڈ ہونے پر چلتا ہے۔ أيےٹ لیسنر نہیں، لُوپ نہیں، پیچیدہ حساب نہیں۔
عملی طور پر، حَدِيث ہارڈور پر، یہ سکرپٹ 1 ملِسی سیونڈ سے کم وقت میں چلتا ہے، ایک غیر محسوس وقت جو صفحے کے لوڈ کی کارکردگی پر کوئی اثر نہیںانداز کرتا۔
بہترین ترتیب <head> میں
عناصر کیordre میں`<head>`مهم ہے۔ یہ تجویز شدہ ترتیب :
<head>
<!-- 1. Métadonnées critiques -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 2. Notre script de pré-chargement (IMMÉDIATEMENT après les meta) -->
<script>
(function() { /* notre code */ })();
</script>
<!-- 3. Titre de la page -->
<title>Mon Site</title>
<!-- 4. Feuilles de style -->
<link rel="stylesheet" href="styles.css">
<!-- 5. Autres ressources (fonts, favicons, etc.) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="icon" href="favicon.ico">
<!-- 6. Autres scripts avec defer ou async -->
<script src="app.js" defer></script>
</head>
یہ حکم یقینی بناتا ہے کہ :
-
چarset متنی عمل سے پہلے تعین کردہ ہوتا ہے
-
ہمارا سکرپٹ CSS کے لوڈ سے پہلے چلتا ہے
-
CSS بعد میں لوڈ کیے جاتے ہیں اور وہ مستقیم مناسب موضوع لاگو کرتے ہیں
-
غیر حتمی وسائل آخر میں لوڈ کئے جاتے ہیں
مرحلہ 3: CSS کے صفی محدودات کی طاقت
بوٹسٹرپ 5 ٹیما سسٹم
Bootstrap 5 نے CSS custom properties (CSS variables) اور ایٹریبیٹ سلكتورز پر مبنی themes کے gérer کا ایک شاندار نظام پیش کیا۔ یہ نظام اس ایٹریبیٹ کو استعمال کرتا ہے۔data-bs-theme`العنصر پر<html>`رنگ کے متغیرات کی کون سی مجموعہ لاگو کرنے کے لیے.
نظام کی خوبصورتی اس کی سادگی میں ہے : ہزاروں عناصر پر مختلف CSS فائلوں لوڈ کرنے یا کلاسوں کو ٹوگِل کرنے کے بجائے، ہم صرف ایک عنصر پر ایک صفت کو سادہ طریقے سے تبدیل کرتے ہیں، اور CSS کاسکیڈ کی مدد سے بقیہ خود کار کر دیتا ہے۔
CSS کی ساخت ایک ٹیم سسٹم کے لیے
یہ ایک مکمل CSS ساخت ہے جس کا استعمال مضبوط تھیم سسٹم کو لاگو کرنے کے لیے کیا جاتا ہے :
/**
* SYSTÈME DE THÈME COMPLET
* Utilise les Custom Properties CSS pour une maintenance facile
*/
/* ============================================
THÈME PAR DÉFAUT (LIGHT)
Défini sur :root pour être le fallback
============================================ */
:root {
/* Couleurs de base */
--color-primary: #0d6efd;
--color-secondary: #6c757d;
--color-success: #198754;
--color-danger: #dc3545;
--color-warning: #ffc107;
--color-info: #0dcaf0;
/* Couleurs de fond */
--bg-primary: #ffffff;
--bg-secondary: #f8f9fa;
--bg-tertiary: #e9ecef;
/* Couleurs de texte */
--text-primary: #212529;
--text-secondary: #6c757d;
--text-tertiary: #adb5bd;
/* Couleurs de bordure */
--border-color: #dee2e6;
--border-color-subtle: #e9ecef;
/* Couleurs d'ombre */
--shadow-sm: rgba(0, 0, 0, 0.075);
--shadow-md: rgba(0, 0, 0, 0.15);
--shadow-lg: rgba(0, 0, 0, 0.25