ChatGPT грузится вокруг вопроса «можно ли уже печатать»

Деннис Бротцки (Dennis Brotzky) 2 июля опубликовал разбор веб-версии ChatGPT, собранный по HTML, бандлам и сетевым запросам. Главный вывод: загрузка chatgpt.com выстроена вокруг одного момента, когда в поле ввода уже можно печатать. В серверном конфиге загрузки так и лежит флаг deferStartupImportsUntilComposerTTFI. Он откладывает стартовые импорты, пока композер, то самое поле ввода, не станет интерактивным.
Разбор вышел в Performance. Бротцки в OpenAI не работает и исходников не видел. Сама OpenAI про устройство ChatGPT web почти ничего не публиковала, так что картину пришлось собирать снаружи: из страницы, кода, чужих выступлений, твитов и вакансий. Обслуживает этот фронтенд, по оценке автора, примерно миллиард человек.
От Next.js к React Router 7
ChatGPT запустили 30 ноября 2022 года как приложение на Next.js 12 с Pages Router. Внутри OpenAI это было «исследовательское превью»: быстрая обёртка вокруг дообученной GPT-3.5. В манифесте маршрутов той сборки, который сохранился в Wayback Machine, рядом с /chat стоят /codespace и /workspace/[[...tid]]. Автор считает, что это, скорее всего, внутренние инструменты, попавшие в прод вместе со спешно выпущенным MVP. App Router chatgpt.com так и не принял: на Pages Router сайт прожил около 21 месяца.
Переезд OpenAI не анонсировала, его заметили на живом сайте. 27 августа 2024 года Тибор Блахо увидел, что части пользователей в рамках эксперимента отдают сборку на Remix. К 4 сентября она раскатилась широко, и сооснователь Remix Райан Флоренс написал: «Вышло новое приложение на Remix: chatgpt.com». На следующий день Уэс Бос разобрал бандл на YouTube и нашёл странную конструкцию. Настоящий сервер на Express выполнял лоадеры маршрутов и сериализовал около 7000 строк JSON в window.__remixContext, но UI на сервере почти не рендерил: оболочка, preload-ссылки, скрипт темы. Экшенов Remix не было вовсе, мутации шли через собственный API. Флоренс позже подтвердил, что большую часть данных ChatGPT грузит через TanStack Query, а лоадеры React Router почти не использует. Создатель Vite Эван Ю подытожил реакцию сообщества одной строкой: «Многим из вас, наверное, тоже нужно просто SPA».
В ноябре 2024 года Remix v2 влился в React Router 7, и ChatGPT пошёл следом. Сейчас в исходнике каждой страницы лежит window.__reactRouterContext с "ssr": true и "isSpaMode": false, а значит, работает полный framework mode со стриминговым серверным рендерингом. Направление сменилось на противоположное: в эпоху Remix сервер отдавал пустую оболочку, а нынешний chatgpt.com рендерит на сервере весь интерфейс для незалогиненного гостя настоящим HTML.
В клиентском манифесте 354 маршрута, и собственно чату из них принадлежат около 13. Остальное занимают маркетинговые и лендинговые страницы вроде ($lang).codex.pricing и ($lang).business._index. Они живут в том же коде, роутере и деплое, поэтому переход с промостраницы в чат идёт клиентской навигацией, без новой загрузки страницы.
Что приходит в первых 84 КБ
Документ для гостя весит 84 КБ в сжатом виде. До ноутбука автора в Ванкувере первый байт с ближайшего узла Cloudflare приходил за 50-65 мс. В этом ответе около 30 КБ разметки (сайдбар, приветствие «What's on the agenda today?», поле ввода) и стили к ней. После гидратации, когда React подключается к уже отрисованному HTML, на странице всего 548 DOM-узлов. Ответ стримится: сервер сразу отдаёт оболочку, Suspense-границы заполняются по мере готовности данных, а данные лоадеров параллельно идут отдельным ReadableStream. В них сервер кладёт персональный план предзагрузки: shouldPrefetchModels, shouldPrefetchHistory, shouldPrefetchStarredConversations.
В head ещё до первого бандла выполняются инлайн-скрипты. Один читает тему из localStorage и ставит класс на элемент html до отрисовки, чтобы страница не мигнула не той темой. Другой ставит метки времени: момент, когда HTML начал выполняться (__oai_SSR_HTML), и первый кадр после этого (__oai_SSR_TTI). Эти замеры снимаются у каждого посетителя и уходят в мониторинг реальных пользователей.
Проверки авторизации на пути к полю ввода нет. У бэкенда есть параллельная анонимная ветка: /backend-anon/me, /backend-anon/models, /backend-anon/conversation. Анонимный посетитель получает настоящий ID пользователя, и на нём работают и лимиты, и эксперименты.
Холодная загрузка тянет больше сотни JS-чанков, но через modulepreload документ заранее запрашивает только 14: точку входа, вендорные чанки React и модули текущего маршрута. Ядро чата приходит под говорящим именем conversation-small, а рендер блоков кода и цепочек рассуждений подгружается отдельно, когда он понадобился ответу. CSS нарезан так же: корневая таблица, таблица разговора и мелкие code-block.css, cot-message.css, global-modals.css. Веб-шрифта для интерфейса нет, текст набран системными шрифтами (SF Pro, Segoe UI, Roboto), а шрифты KaTeX скачиваются, только если в ответе есть формулы. Всё отдаётся с chatgpt.com/cdn/assets через Cloudflare с кэшем на 30 дней, без сторонних доменов и лишних TLS-рукопожатий. Service worker нет совсем, хотя Linear, для сравнения, заранее кэширует около 1200 файлов.
556 гейтов в каждом документе
Самая тяжёлая часть HTML - тег script с 377 КБ JSON. В нём статус авторизации, локаль, регион и снимок всей системы экспериментов Statsig, посчитанный на сервере для каждого запроса по анонимному ID и региону. В день проверки там было 556 фич-гейтов, 144 динамических конфига и 192 слоя экспериментов. Запроса к сервису флагов на старте нет, поэтому не приходится выбирать между блокировкой рендера и миганием дефолтов: к гидратации ответ на каждый гейт уже готов. Имена гейтов захешированы, вместо названия стоит 3479398748. Автор связывает это с целой экосистемой любителей, которые выкапывают из фронтенда ChatGPT невыпущенные функции. События экспериментов уходят на chatgpt.com/ces/v1/, на собственный домен, поэтому из статистики не выпадают пользователи с блокировщиками рекламы.
Флагами управляется и сама загрузка. Рядом с deferStartupImportsUntilComposerTTFI стоят promoteCss и stripModulepreloadImports, серверные переключатели того, как документ грузит собственные CSS и JavaScript. Оба варианта выкатываются параллельно, и победителя определяет время загрузки у миллионов пользователей.
В цитате OpenAI на сайте Statsig говорится о запуске больше 600 функций за флагами, а команда дата-инженеров описывает «сотни экспериментов на сотнях миллионов пользователей». Запуск Codex один из инженеров описал так: задеплоить монолит, а потом «включить флаги». В сентябре 2025 года OpenAI купила Statsig за 1,1 миллиарда долларов, а основатель компании Виджай Раджи стал CTO по приложениям и возглавил разработку ChatGPT и Codex.
Где тратят сложность
Всё вокруг ответа подчёркнуто стандартное. Меню, селекты, тосты и поповеры сделаны на примитивах Radix, анимаций почти нет. Сложность сосредоточена в двух местах. Первое - композер: на вид это textarea, на деле полноценный редактор ProseMirror. Сервер рендерит визуально идентичную статичную заглушку, а ProseMirror подключается поверх, когда приходит бандл. OpenAI спонсирует Марейна Хавербеке, автора ProseMirror и CodeMirror.
Второе - сам ответ. Каждый токен приносит кусок markdown, и растущее сообщение перепарсивается и перерисовывается на месте, хотя посреди стрима разметка почти всегда незакончена: незакрытый блок кода, таблица с тремя строками, жирный текст без закрывающего маркера. Блок кода в ответе оказывается полноценным редактором CodeMirror с .cm-editor и .cm-content в DOM, тем же, что работает в canvas. Формулы KaTeX приходят дважды: видимая версия и скрытое дерево MathML. Второе нужно скринридерам и для копирования формулы как математики.
Список сообщений при этом не виртуализирован, каждое сообщение остаётся в DOM. Бротцки объясняет это тем, что разговоры в ChatGPT в основном короткие, а поиск по странице должен работать у миллиарда людей. Платить за такую ставку приходится длинным чатам, где в DOM остаётся вся история целиком.
Открытая дверь и охрана за ней
Бесплатный анонимный доступ к модели притягивает ботов, и каждый такой запрос стоит OpenAI денег на GPU. Поэтому до первого сообщения в фоне уже срабатывают две защиты. Cloudflare запускает proof-of-work: браузер тратит немного процессорного времени, доказывая, что он настоящий (это запросы cdn-cgi/challenge-platform). Собственная антиабьюз-система OpenAI под названием Sentinel загружается в изолированном iframe sentinel/frame.html со своим sentinel/sdk.js и снимает отпечаток клиента отдельно от приложения. Пока вы печатаете, приложение уже вызывает /backend-anon/conversation/init и проходит проверки chat-requirements/prepare и finalize. Исследователи, расшифровавшие челлендж Cloudflare на chatgpt.com, обнаружили, что он проверяет десятки свойств страницы, включая состояние React Router самого приложения.
После Enter короткий prepare подтверждает, что требования ещё выполнены, и сообщение уходит POST-запросом на /backend-anon/f/conversation. Ответ приходит как text/event-stream: SSE поверх fetch, та же схема, что и в 2022 году. В тело запроса добавляется client_contextual_info с размером окна, плотностью пикселей, состоянием тёмной темы и числом секунд с момента загрузки.
Сравнение с claude.ai автор строит на этой же развилке. В ChatGPT можно писать через несколько секунд и без аккаунта, а бесплатные ответы OpenAI уже начала окупать рекламой. На claude.ai сначала логин и онбординг, а само приложение представляет собой SPA с клиентским рендерингом, которое отдаётся прямо с CDN. Когда все пользователи залогинены, такой выбор оправдан, рассуждает Бротцки, и стратегию каждой компании, по его словам, «можно прочитать прямо по вкладке Network».
Дальше
Агенты OpenAI щупали Hugging Face за два месяца до взлома
Странно оформленные файлы улетели на серверы Hugging Face ещё 13 мая: по данным Reuters, два аккаунта угнали агенты OpenAI и прощупывали сеть за два месяца до июльского взлома. Следов прорыва в мае исследователи не нашли.
Читайте также
- Как Python-библиотека OpenAI доросла до миллиарда
- Десктопный ChatGPT возит с собой LibreOffice
- Погрешность до m/4 не ломает шаг в доказательстве OpenAI
- GPT-6 Astra спроектировала гаджет для Codex без правок людей
- Новый бэкенд Git в OpenAI ускорил пуши почти в 5 раз
- Мониторы OpenAI в повторе сработали за 30 часов до взлома
Комментарии
Пока никто не написал. Будьте первым.
Присоединяйтесь к разговору
Войдите, чтобы оставить комментарий. Он появится после модерации.

