# Устранение FOUC (Flash of Unstyled Content) ## Проблема При переходе между страницами происходило **мигание белой темы**, даже если пользователь выбрал тёмную тему. ### Ошибочное предположение ❌ "Стили не кэшируются" - **НЕверно!** - Статические файлы (CSS/JS) **всегда** кэшируются браузером - Nginx выдаёт их с `Cache-Control: public, max-age=31536000` - Проблема была НЕ в кэше! ### Настоящая причина ✅ **Неправильный порядок выполнения скриптов**: ``` 1. HTML загружается с data-bs-theme="auto" 2. CSS загружается и применяется (тема = auto = светлая) 3. 🔥 МИГАНИЕ БЕЛОЙ ТЕМЫ 🔥 4. JavaScript выполняется и меняет тему на тёмную ``` ## Решение ### До (неправильно) ```html ``` ### После (правильно) ```html ``` ## Как работает themeInitializer.js ### Синхронное выполнение (НЕ defer, НЕ async, НЕ module) ```javascript (function() { 'use strict'; // 1. Читаем сохранённую тему из localStorage const savedTheme = localStorage.getItem('theme') || 'auto'; // 2. Определяем эффективную тему let effectiveTheme = savedTheme; if (savedTheme === 'auto') { const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); effectiveTheme = prefersDark.matches ? 'dark' : 'light'; } // 3. НЕМЕДЛЕННО устанавливаем атрибут document.documentElement.setAttribute('data-bs-theme', effectiveTheme); // Всё это происходит ДО парсинга и ДО загрузки CSS! })(); ``` ### Почему это работает - ✅ Скрипт выполняется **синхронно** в `` - ✅ Браузер **блокируется** до выполнения скрипта - ✅ Атрибут `data-bs-theme` устанавливается **ДО** применения CSS - ✅ CSS применяется сразу с правильной темой - ✅ Никакого мигания! ## Preload критичных стилей ### Зачем нужен preload? ```html ``` **Без preload**: 1. Браузер парсит HTML 2. Доходит до `` 3. Начинает загрузку CSS (задержка!) 4. Парсит CSS 5. Применяет стили **С preload**: 1. Браузер парсит HTML 2. Видит `` → начинает загрузку **параллельно** 3. Доходит до `` → CSS уже загружен! 4. Сразу применяет стили **Результат**: ускорение на 100-300ms ## Кэширование и FOUC ### Важно понимать! **Кэш НЕ решает проблему FOUC**: ``` С кэшем (неправильный порядок): 1. HTML из disk cache (0ms) 2. CSS из disk cache (0ms) ← быстро! 3. 🔥 Но всё равно мигание! 🔥 4. JS меняет тему (слишком поздно) С кэшем (правильный порядок): 1. HTML из disk cache (0ms) 2. themeInitializer.js СИНХРОННО (0ms) 3. data-bs-theme установлен ДО парсинга CSS 4. CSS из disk cache (0ms) применяется с правильной темой 5. ✅ Никакого мигания! ``` **Вывод**: - Кэш **ускоряет** загрузку - Правильный порядок **устраняет** FOUC - Нужны **оба** решения! ## Тестирование ### Как проверить, что FOUC устранён 1. **Выберите тёмную тему** на сайте 2. **Hard refresh** (Ctrl+Shift+R) для сброса кэша 3. **Быстро переходите** между страницами 4. **Результат**: НЕ должно быть белых вспышек ### Проверка в DevTools ```javascript // Откройте Console // Проверьте, что атрибут установлен ДО DOMContentLoaded console.log('Theme on parse:', document.documentElement.getAttribute('data-bs-theme')); // Должно вывести 'dark' или 'light', НЕ 'auto' ``` ### Проверка порядка загрузки Network tab → фильтр "CSS": 1. ✅ `themeInitializer.js` - загружен первым 2. ✅ `bootstrap.css` (preload) 3. ✅ `variables.css` (preload) 4. ✅ Остальные стили ## Частые ошибки ### ❌ Использование defer/async ```html ``` ### ❌ Использование type="module" ```html ``` ### ❌ Установка темы в DOMContentLoaded ```javascript // НЕПРАВИЛЬНО: слишком поздно! document.addEventListener('DOMContentLoaded', () => { document.documentElement.setAttribute('data-bs-theme', 'dark'); }); // ПРАВИЛЬНО: немедленно document.documentElement.setAttribute('data-bs-theme', 'dark'); ``` ### ❌ data-bs-theme="auto" в HTML ```html ``` ## Совместимость с кэшированием ### Статика кэшируется правильно ``` themeInitializer.js: - Cache-Control: public, max-age=31536000 - Loaded: (disk cache) bootstrap.css: - Cache-Control: public, max-age=31536000 - Loaded: (disk cache) ``` ### HTML кэшируется с правильным порядком ``` base.html: - Cache-Control: private, max-age=60 - Loaded: (disk cache) - Порядок скриптов сохранён! ``` **Результат**: - ✅ Мгновенная загрузка из кэша - ✅ Без мигания темы - ✅ Идеальный UX! ## Резюме | Проблема | Решение | Результат | |----------|---------|-----------| | Мигание белой темы | Синхронный скрипт в `` | ✅ Нет FOUC | | Медленная загрузка CSS | Preload критичных стилей | ✅ +100-300ms | | "Стили не кэшируются" | Это было заблуждение | ✅ Всегда кэшировались | | data-bs-theme="auto" | Убрали из HTML | ✅ JS устанавливает сразу | **Главный вывод**: Проблема была НЕ в кэшировании, а в **порядке выполнения**! 🎯