Почему в React-приложении страница постоянно остаётся в состоянии загрузки и не завершает этот процесс?

Всем доброго времени суток. Разворачиваю React‑проект на VDS — при переходе по URL страница бесконечно загружается: отображается белый экран без ошибок. В консоли браузера ошибок нет, index.html возвращает HTTP 200, npm install и npm run build проходят без ошибок. Подскажите, что стоит проверить и в каком направлении искать причину?
  • 23 апреля 2026 г. 9:01
Ответы на вопрос 1
Ниже — упорядоченный чек‑лист и типичные причины, которые нужно проверить, когда React‑приложение на сервере «висит» на белом экране и не завершает загрузку.

Быстрая проверка (выполните в первую очередь)
1. Откройте DevTools → Network, нажмите Ctrl+R (полная перезагрузка, отключите кэш), посмотрите:
   - Загружаются ли все .js и .css файлы и возвращают ли они статус 200 (или 304)?  
   - Не возвращает ли вместо .js файл HTML (частая причина — сервер отдает index.html при запросе ассетов).
   - Content‑Type и Content‑Encoding для .js: должны быть text/javascript/ application/javascript и корректный Content‑Encoding (если сжатие включено).
2. В DevTools → Console:
   - Уберите фильтры (Errors, Warnings и т.д.), проверьте, нет ли синтаксических ошибок (Unexpected token <), ошибок загрузки скриптов, CSP, SRI, ошибок Service Worker.
3. Попробуйте локально: в папке build запустите serve -s build или npx serve build — если локально всё ок, значит проблема на сервере.

Типичные причины и что проверить дальше
1. Неправильная отдача статики (чаще всего)
   - Сервер (nginx/Apache) настроен так, что при запросе /static/js/... возвращается index.html (200) — тогда браузер получает HTML вместо JS, и скрипты ломаются. В Network браузера это видно по содержимому ответа (начинается с <!doctype html>).
   - Проверка: curl -i https://example.com/static/js/main.*.js или откройте файл в браузере — должен быть JS, а не HTML.

2. Неправильный publicPath/homepage (путь к ассетам)
   - Если приложение развернуто в подпапке, а сборка предполагает корень (/), пути к ассетам будут неверные и файлы 404. Для create‑react‑app прописывайте "homepage" в package.json или настраивайте publicPath в сборщике.
   - Альтернатива: используйте HashRouter вместо BrowserRouter если не хотите настраивать серверную маршрутизацию.

3. Ошибки сжатия/Content‑Encoding
   - Сервер может отдавать gzip‑сжатый файл без заголовка Content‑Encoding: gzip (или наоборот декомпрессировать дважды), в результате браузер получает «мусор» и не выполняет JS, иногда без понятной ошибки.
   - Проверка: смотрите заголовки ответа (curl -I) и исход содержимого.

4. CSP / SRI / CORs / политика безопасности
   - Content‑Security‑Policy может блокировать выполнение inline‑скриптов или загрузку ресурсов. SRI (integrity attribute) может блокировать, если хеш не совпадает.
   - Проверка: заголовки ответа на index.html, сообщения в Console о CSP/SRI.

5. Service Worker / кеширование старой версии
   - Старый SW может перехватывать запросы и отдавать некорректные ресурсы.
   - Проверка: DevTools → Application → Service Workers → unregister и Hard Reload.

6. Ошибки маршрутизации (React Router)
   - При переходе по URL сервер должен отдавать index.html для всех SPA‑маршрутов (try_files ... /index.html). Но при неправильной конфигурации сервер может отдавать 404 или неправильный файл.
   - Нужна конфигурация fallback на index.html, но при этом статику нужно отдавать корректно.

7. Неправильные MIME‑типы
   - Сервер может отдавать .js как text/html. Проверить заголовок Content‑Type.

8. Файловая система и регистрозависимость
   - На Windows/Dev регистр файла не важен, на Linux — важен. Неправильный импорт/имя файла может пройти на сборке, но при runtime ассеты не найдутся.
   - Проверка: убедитесь, что имена файлов совпадают по регистру.

9. Ошибки маршаллинга или root‑элемент отсутствует
   - index.html должен содержать <div id="root"></div> (id совпадает с тем, что использует React). Отсутствие элемента может привести к ошибкам при монтировании.

10. Скрипты блокируются политиками хоста (WAF, прокси)
   - Внешние прокси или CDN могут блокировать/модифицировать скрипты.

Что конкретно сделать — шаги и команды
1. Откройте DevTools → Network → Reload (Disable cache). Просмотрите:
   - Список статичных файлов (.js, .css, fonts, images) — статус, размер, тип.
   - Откройте проблемный .js — если видите HTML, это подтверждение проблемы с отдачей статики.
2. Используйте curl/wget:
   - curl -I https://example.com/                (проверить заголовки index.html)
   - curl -I https://example.com/static/js/main.*.js
   - curl -s https://example.com/static/js/main.*.js | head -n 5 (показать начало файла)
3. Посмотрите логи сервера:
   - nginx: /var/log/nginx/error.log и access.log — есть ли 404/500 на статические файлы?
4. Если nginx, проверьте конфиг. Пример корректного для SPA:
   - location /static/ { alias /var/www/app/build/static/; }
   - location / { try_files $uri $uri/ /index.html; }
   Убедитесь, что static/ и index.html корректно указывают на build.
5. Проверить Content‑Encoding:
   - curl -I https://example.com/static/js/main.*.js  (проверить Content-Encoding)
6. Service Worker:
   - DevTools → Application → Service Workers → Unregister, затем Hard Reload.
7. Попробуйте развернуть build локально (serve -s build). Если локально всё ок — значит дело в серверной конфигурации.
8. Посмотрите на package.json: есть ли поле "homepage" (если развернуто в подпапке)? Если нет — установите или исправьте publicPath.
9. Включите source maps (если отключены) при сборке, чтобы видеть ошибки в исходном коде.

Что чаще всего помогает (решения)
- Исправить nginx/Apache конфиг, чтобы статические файлы отдавались как файлы, а не перенаправлялись на index.html.
- Установить correct Content‑Type и Content‑Encoding для JS/CSS.
- Добавить "homepage" в package.json или настроить publicPath в сборщике, или использовать HashRouter.
- Удалить/обновить Service Worker (часто после деплоя остаётся старый SW и мешает).
- Проверить и исправить CSP/SRI заголовки, если они блокируют.

Если хотите, могу помочь конкретно с проверкой — пришлите:
- URL, где это воспроизводится (если публично доступен), или
- вывод curl -I для index.html и для одного из JS-файлов, или
- ваш nginx/Apache конфиг (фрагмент, где настроены location/alias/try_files) и структуру build (например ls -la build/static/js).
Похожие вопросы