vyvchy
    Теми розділу

    03 · Веб і мережі для AQA

    Життєвий цикл запиту

    Зміст

    Між натисканням Enter і появою сторінки відбувається довгий ланцюг подій. Для користувача це просто «сайт відкрився». Для AQA це послідовність фаз, у кожної з яких власна тривалість, власні режими й власні причини, чому тест раптом червоніє без жодної зміни в коді.

    Ця глава — повний виклад шляху запиту на сайті: решта глав розділу посилаються сюди по карту фаз, а вона відсилає до них по деталі кожної. Мета одна — вміти за хвилину сказати, яка саме фаза зʼїла час або зламала перевірку, до того як хтось почав правити код тесту.

    Сім фаз одного запиту

    Життєвий цикл запиту (request lifecycle) — послідовність фаз між натисканням Enter і появою сторінки: DNS → TCP → TLS → надсилання запиту → очікування сервера → відповідь → рендер. Кожна стрілка тут — це час і можлива точка збою.

    DNS
    імʼя → адреса

    TCP
    рукостискання

    TLS
    рукостискання

    Надсилання
    запиту

    Очікування
    сервера

    Відповідь

    Рендер

    DNS
    імʼя → адреса

    TCP
    рукостискання

    TLS
    рукостискання

    Надсилання
    запиту

    Очікування
    сервера

    Відповідь

    Рендер

    Розкладка не абстрактна — саме нею інструменти й міряють час: панель Network розводить кожен запит на ті самі фази окремими смужками (до її таблиці ми повернемося наприкінці). Дрібниця, яка щоразу спантеличує: узгодження шифрування довідник кладе всередину фази Initial connection — разом із TCP- і його можливими повторами.

    Наша практика (не канон). Далі — спостереження команд, під яке окремого джерела немає: більшість «повільних» і ламаються не на видимому етапі рендеру, а на невидимих ранніх фазах — резолвінгу імені, встановленні зʼєднання чи очікуванні першого байта. Тому діагностику варто починати з початку шляху, а не з кінця.

    Резолвінг імені: фаза, якої не видно

    Браузер не вміє підключатися до example.com — йому потрібна адреса. Перекладає імʼя в адресу DNS (Domain Name System): розподілена ієрархічна система з простору імен, серверів імен і резолверів. Резолвер операційної системи (stub-резолвер) ієрархію сам не обходить — він перекладає роботу на рекурсивний сервер імен, а той іде звичним ланцюгом: кореневі сервери → сервери зони верхнього рівня → авторитетний сервер домену, який і повертає A-запис. Кожен запис живе стільки, скільки дозволяє TTL, і орієнтир самого RFC для типового вузла — порядок днів.

    Звідси симптоми. Час «холодної» резолюції додається до часу відкриття сторінки — іноді саме він перетворює нормальний прогін на перевищення . Якщо середовище нещодавно змінило IP, а десь у ланцюжку живий старий запис, тести стукають за застарілою адресою, і чекати доводиться саме TTL. Окремо стоїть локальна таблиця хостів (файл hosts): це резерв або доповнення до DNS, і що з них має пріоритет, залежить від конфігурації вузла, тож запис на машині розробника чи на CI- тихо спрямовує тести на інший стенд. Деталі протоколу й типи записів — глава «DNS, IP, порти та мережа».

    Наша практика (не канон). Джерела такого правила не дають, але воно економить години: якщо тест падає лише в одному оточенні, перша гіпотеза — не код, а те, куди насправді резолвиться імʼя (запис у hosts, повільний корпоративний резолвер, непропагований домен). Так само з практики, а не зі специфікації, взято звичний опис пошуку як каскаду «кеш браузера → кеш ОС і hosts → резолвер провайдера».

    Рукостискання: скільки їх на шляху HTTPS-запиту

    Рукостискання (handshake) — узгодження параметрів зʼєднання перед тим, як піде корисний трафік. На шляху звичайного HTTPS-запиту їх щонайменше два: транспортне TCP і криптографічне TLS. Для реалтайму додається третє — відкривальне рукостискання WebSocket, зроблене як HTTP-запит Upgrade.

    TCP. Зʼєднання встановлюється тристороннім рукостисканням SYNSYN-ACKACK. Кроків саме три, бо підтвердження й власний SYN сервера обʼєднані в одне повідомлення; після цього зʼєднання — логічний канал, який ідентифікує пара сокетів.

    TLS. Протокол складається з двох компонентів: рукостискання, що автентифікує сторони, узгоджує криптографічні параметри й встановлює спільний ключовий матеріал, і record-протоколу, який цими параметрами захищає трафік. Клієнт шле ClientHello, сервер відповідає ServerHello — і в TLS 1.3 усі повідомлення рукостискання після ServerHello уже зашифровані, зокрема сертифікат. У ClientHello їде імʼя хоста (SNI, Server Name Indication), щоб сервер із багатьма доменами на одній IP віддав потрібний сертифікат; це імʼя має збігтися з іменем у сертифікаті.

    СерверКлієнтСерверКлієнтTCP-канал відкритодалі все шифрованеаж тепер іде HTTP-запитSYNSYN-ACKACKClientHello (версії, шифри, SNI)ServerHelloCertificate, FinishedFinishedСерверКлієнтСерверКлієнтTCP-канал відкритодалі все шифрованеаж тепер іде HTTP-запитSYNSYN-ACKACKClientHello (версії, шифри, SNI)ServerHelloCertificate, FinishedFinished

    Це вимірюваний внесок у : специфікація сама називає звичайне рукостискання TLS 1.3 «1-RTT handshake». Режим 0- економить іще один обхід, коли сторони мають спільний ключ PSK — отриманий зовні або попереднім рукостисканням, а не лише відновленням сесії; плата названа прямо: властивості безпеки раннього трафіку слабші, тобто він уразливий до повторного відтворення (replay). Добра новина — платиться це раз на зʼєднання: HTTP тримає канал відкритим (keep-alive) і перевикористовує його, тому перший запит до нового хоста дорожчий за наступні.

    WebSocket. Зʼєднання відкривається звичайним GET із заголовками Upgrade: websocket, Connection: Upgrade і Sec-WebSocket-Key, а успіх означає рівно 101 Switching Protocols із Sec-WebSocket-Accept. Будь-який інший статус означає, що рукостискання не завершилося і далі діє звичайна семантика HTTP: 403 тут не «зламаний веб-сокет», а незавершений апгрейд. Далі — глави «WebSockets і реалтайм» і «HTTPS, TLS і безпека».

    Наша практика (не канон). Дві речі тут ідуть від досвіду, а не від специфікацій. Поширену оцінку «TLS 1.2 коштує близько 2 RTT» жодне джерело реєстру не підтверджує — це галузева цифра. І найчастіша причина падінь саме на фазі TLS — сертифікати нестабільних оточень (самопідписаний або прострочений на , невідповідність імені), а вимикач перевірки на кшталт ignoreHTTPSErrors вмикають свідомо й лише для тестових доменів.

    Запит пішов: TTFB як межа між «сервер думає» і «дані йдуть»

    Запит складається з методу, шляху, заголовків і тіла. Частину заголовків код задати не може: Fetch перелічує їх поіменно як forbidden request-header — серед них Cookie, Origin, Referer, Host, Content-Length. Їх ставить сам браузер із контексту сторінки й свого сховища, і саме звідси беруться типові репорти «у Postman працює, а в браузері ні». Виняток, який плутають найчастіше: User-Agent у переліку немає — браузер підставляє його лише за відсутності власного значення, тому підміна в тесті й працює.

    Заголовки — не єдина відмінність браузера від консольного клієнта. Браузер здатен не відправити запит узагалі: (mixed content) на HTTPS-сторінці він або підвищує до HTTPS, або блокує, а CSP (Content Security Policy) обмежує, звідки сторінці дозволено вантажити ресурси. Обидва механізми спрацьовують ще до мережевої фази, і в панелі такий запит зазвичай або відсутній, або одразу червоний.

    Далі — очікування. Момент, коли до клієнта доходить перший байт відповіді, задає (time to first byte). І тут головна пастка: під однією абревіатурою живуть два різні вимірювані обʼєкти.

    Що міряютьВід чого рахуютьЩо входить
    Навігаційний TTFB (MDN, web.dev)старт навігаціїрезолвінг DNS, TCP- і TLS-рукостискання, час редиректів, передача запиту
    Фаза Waiting (TTFB) у DevToolsмомент, коли запит уже відправленоодин обхід затримки плюс час, який сервер витратив на підготовку відповіді

    MDN формулює перший дослівно: цей час «includes DNS lookup and establishing the connection using a TCP handshake and TLS handshake if the request is made over HTTPS». Довідник DevTools описує другий: «This timing includes 1 round trip of latency and the time the server took to prepare the response», причому DNS Lookup, Initial connection і Request sent стоять фазами перед ним.

    Практична цінність пряма: якщо велике саме Waiting (TTFB), а Content Download і рендер нормальні, проблема на бекенді або в мережі до нього — це вже напрям для баг-репорту, а не розмите «сторінка гальмує». Структуру запиту — глава «HTTP: методи, структура, заголовки».

    Наша практика (не канон). Сам поділ TTFB на два обʼєкти — наше співставлення джерел: кожне означує свій предмет, але прямо про два предмети не каже жодне. Наслідок робочий: числа з різних інструментів «у лоб» не порівнюються, і в баг-репорті варто писати, звідки взято цифру.

    Кеш: фаза, яка вміє обірвати шлях на самому початку

    Не кожен запит доходить до сервера. (HTTP caching) — зберігання вже отриманих відповідей у проміжному сховищі, щоб не тягнути їх мережею повторно: поки копія свіжа, вона віддається без жодного мережевого походу. Ще ближче до сторінки стоїть Service Worker — фоновий скрипт, який працює як між вебзастосунком, браузером і мережею й перехоплює навігаційні та ресурсні запити. Довідник DevTools фіксує це в описі фази Content Download: браузер отримує відповідь «either directly from the network or from a service worker». Тобто рядок у панелі є, а мережевого обміну могло не бути взагалі.

    Два схожі на вигляд стани варто розрізняти. Свіжа копія з кешу означає, що сервера навіть не питали, і зміна на бекенді до тесту не доїде, доки не мине свіжість. 304 Not Modified — навпаки, живий запит: сервер підтвердив збережену відповідь і не передав тіла, тобто ревалідація працює. Правила свіжості й механіку 304 розбирає глава «Кешування».

    Редирект і preflight: фази, що подовжують ланцюг

    Кеш шлях вкорочує, а дві інші фази — подовжують.

    Редирект (redirect) — відповідь із кодом 3xx і заголовком Location, куди клієнту треба піти далі. Браузери й більшість HTTP-клієнтів ідуть за перенаправленням автоматично; помітний виняток — curl, який без прапорця -L за редиректом не піде. Ціну MDN називає прямо: кожен редирект коштує зайвого HTTP-запиту, тобто має відчутний вплив на продуктивність — і саме тому час редиректів входить у навігаційний TTFB. Що при цьому стається з методом і тілом:

    КодМетод і тіло при переході
    301, 302незмінність гарантована лише для GET; інші методи клієнт може підмінити на GET і втратити тіло
    303навмисно переводить на GET, тіло втрачається
    307, 308«Method and body not changed» — і метод, і тіло зберігаються

    Звідси правило: перенаправляти POST/PUT/DELETE без втрати тіла — це 307/308, а не 301/302. Петля редиректів зазвичай є проблемою конфігурації сервера, і якщо сервер її помічає, то віддає 500. Увесь ланцюг видно однією командою:

    curl -sIL https://example.com/ | grep -i -E 'HTTP/|location'

    Класи кодів — глава «HTTP статус-коди».

    Preflight — додатковий раунд перед «справжнім» запитом. Для запитів, складніших за ті, що дозволяє HTML-форма, браузер спершу шле окремий OPTIONS із заголовками Access-Control-Request-Method і Access-Control-Request-Headers, і лише після дозвільної відповіді летить основний виклик. Тригери: метод поза GET/HEAD/POST; Content-Type поза трьома значеннями (application/x-www-form-urlencoded, multipart/form-data, text/plain) — тому типовий REST-виклик із application/json preflight спричиняє; будь-який заголовок поза безпечним переліком. Успішним preflight вважається лише за статусу в діапазоні 200–299, а Access-Control-Max-Age дозволяє кешувати дозвіл.

    Чотири деталі просто для тестів. Preflight ніколи не надсилається з обліковими даними, тож вішати перевірку авторизації на маршрут OPTIONS не можна — вона його завалить. Запит з обліковими даними (cookie або HTTP-автентифікація) вимагає від сервера Access-Control-Allow-Credentials: true, і * у Access-Control-Allow-Origin при цьому неприпустимий — потрібне конкретне . Заголовок Authorization — окремий випадок: Fetch відносить його до CORS non- request-header, тож Access-Control-Allow-Headers: * його не покриває — сервер має назвати цей заголовок поіменно. І один логічний виклик дає два записи в мережі: якщо очікування привʼязане не до того запису, тест плаватиме. Механізм цілком — глава «CORS і політика одного походження».

    Скільки зʼєднань і якою версією протоколу

    Досі ми йшли одним запитом, а реальна сторінка тягне десятки підресурсів — і тут вмикається паралелізм. Зʼєднання HTTP/1.x серіалізує запити: наступний іде після відповіді на попередній. Щоб це обійти, браузер відкриває до одного домену кілька зʼєднань — колишній дефолт 2–3, нинішній поширений — шість. Довідник DevTools фіксує число прямо в поясненні черги («There are already six TCP connections open for this origin») і додає межу: правило стосується лише HTTP/1.0 і HTTP/1.1. На HTTP/2 картина протилежна — специфікація каже, що клієнт не повинен відкривати більш ніж одне зʼєднання на пару «хост+порт». Тому гіпотеза «сторінка гальмує, бо забагато дрібних файлів» на HTTP/1.1 правдоподібна, а на HTTP/2 — ні. Саме число шість при цьому — спостережувана поведінка браузерів, а не норма протоколу: у RFC його немає.

    Версію теж не «вмикають» — про неї домовляються на старті зʼєднання (узгодження версії протоколу, protocol negotiation). Рекомендований шлях — узгодити протокол усередині TLS-рукостискання через ALPN, без додаткових обходів; браузери піднімають HTTP/2 лише поверх TLS. Наслідок: локальний стенд на http:// у браузері завжди піде по HTTP/1.1, і це не дефект. Мультиплексування, й HTTP/3 — глава «HTTP/2 і HTTP/3: еволюція протоколу».

    Рендер: «відповідь прийшла» ще не означає «видно»

    Отримавши HTML, браузер будує DOM, паралельно з CSS — CSSOM, з їх поєднання постає дерево рендерингу, яке розкладається (layout) і малюється (paint), а шари складаються в підсумкову картинку (composite). Уся послідовність від отримання HTML до перших пікселів називається критичним шляхом рендерингу (critical rendering path).

    Ключове для нашої теми: рендер породжує нові запити. Натрапляючи на підресурси — CSS, скрипти, шрифти, зображення, — браузер ініціює власні запити, і для кожного цикл повторюється, часто вже поверх перевикористаного зʼєднання; частина цих запитів блокує подальший розбір документа.

    Дві події, на які часто «чекають» тести: DOMContentLoaded — HTML розпарсено й DOM побудовано, підресурси можуть іще вантажитися; load — завантажено всю сторінку разом із залежними ресурсами (стилі, скрипти, iframe, картинки), окрім лінивих. Але головне правило сучасних фреймворків інше: чекати на факт, а не на секунди — фіксована пауза на швидкій машині зайва, а на повільній недостатня.

    // погано: гонка з реальним часом завантаження
    await page.waitForTimeout(3000);
    
    // добре: чекаємо на факт
    await page.getByRole('row', { name: 'Some user name' }).waitFor();
    
    // або саме на потрібну відповідь API
    await page.waitForResponse((r) => r.url().includes('/api/users') && r.ok());

    Етапи конвеєра розбирає глава «Архітектура браузера й рендеринг», а те, коли між ними виконується JavaScript, — глава «Виконання JavaScript та event loop».

    Наша практика (не канон). Два уточнення досвіду, яких джерела прямо не роблять. Перше: жодна з двох подій не засвідчує подальших XHR/fetch — JavaScript часто запускає їх уже після load, тож тест, що чекає лише на подію завантаження, може прокинутися раніше за дані. Друге: серед блокувальних запитів окремо називають зовнішній CSS і синхронний script без async/defer; джерело говорить лише про «some requests are blocking», без переліку.

    Що з цього видно у вкладці Network

    Панель записує всі запити автоматично — але лише поки DevTools відкриті, тож перше правило діагностики: відкрити її до відтворення проблеми. Колонка Time показує повну тривалість від старту запиту до останнього байта, — запити один відносно одного (типово за часом старту), а розкладка Timing розводить смужку по фазах:

    ФазаЩо означає
    Queueing / Stalledзапит іще не відправлено: він стоїть у черзі — наприклад, бо на це походження вже відкрито шість зʼєднань
    DNS Lookupбраузер резолвить IP-адресу запиту
    Initial connectionвстановлення зʼєднання: TCP-рукостискання (з можливими повторами) і узгодження SSL
    Request sentпередача запиту до сервера
    Waiting (TTFB)один обхід затримки плюс час підготовки відповіді на сервері
    Content Downloadотримання тіла — з мережі або від service worker

    Звідси й прочитання стану pending: браузер запит уже ініціював, але (повної) відповіді ще не отримав — сам собою це «в процесі», а не помилка. Дві колонки, без яких половина цієї глави лишається невидимою, у дефолтний набір не входять: Protocol (h2 для HTTP/2, h3 для HTTP/3) і Connection ID (у якому зʼєднанні пішов запит) — їх вмикають правою кнопкою по шапці таблиці. І дрібниця для баг-репортів: експорт HAR типово «санітизований», із нього прибрано Cookie, Set-Cookie й Authorization. Панель як інструмент — глава «DevTools: вкладка Network і дебаг».

    Наша практика (не канон). У довіднику фаз не описані ні стан Blocked, ні навмисно довгі зʼєднання, тож наступне — з практики: для стрімів, SSE й WebSocket-апгрейдів вічний pending нормальний, бо канал тримають відкритим свідомо, і плутати його із зависанням не варто.

    Діагностика фазами: від симптому до фази

    Тест бачить лише кінцевий результат — зелено або червоно, тоді як причина сидить на конкретній фазі. Тож перше питання одне: яка фаза зʼїла час або зламалася. Найшвидший спосіб розвести резолвінг, зʼєднання й сервер — розкласти час по шарах. curl дає готові змінні, і кожна відлічується від старту, тож вартість фази — це різниця сусідніх:

    curl -sS -o /dev/null -w 'dns=%{time_namelookup} tcp=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer}\n' https://example.com/

    Великий time_namelookup — гальмує резолвінг; резолвінг швидкий, а time_connect довгий — проблема зʼєднання; зʼєднання й TLS швидкі, а time_starttransfer великий — думає сервер. Якщо ж усі чотири числа малі, а сторінка «гальмує», справа вже на клієнті — у рендері або в JavaScript.

    Друга вісь — чий таймаут спрацював. Вони живуть на різних рівнях: --connect-timeout у клієнта обмежує лише фазу встановлення зʼєднання; read/response обмежує очікування відповіді, а idle — простій у вже відкритому зʼєднанні; , який не дочекався бекенда, віддає клієнту 504; а таймаути тест-фреймворку (навігація, дія, перевірка, тест) — це вже про очікування в самому тесті, і їхню ієрархію розбирає розділ про інструменти автоматизації.

    Третя вісь — , теж багаторівневі. TCP сам повторно надсилає втрачені сегменти нижче за HTTP, і цього не видно; HTTP-клієнти й проксі повторюють запити, часто на 502/503/504, а ретрай зазвичай робить паузу, що зростає між спробами (), щоб не добивати перевантажений сервіс. Чи безпечно повторювати, вирішує : GET, HEAD, OPTIONS, TRACE, PUT і DELETE ідемпотентні — стан сервера після одного й після N викликів однаковий; POST, PATCH і CONNECT — ні, тому автоповтор POST, що створює замовлення, здатен породити дубль.

    СимптомНайімовірніша фазаКуди дивитися
    падає лише в одному оточеннірезолвінг іменіtime_namelookup, запис у hosts, TTL
    помилка сертифікатаTLS-рукостисканняімʼя в сертифікаті проти SNI, термін дії
    довге очікування без данихсерверфаза Waiting (TTFB) у Timing
    запит стоїть, хоч сервер вільнийчерга зʼєднаньQueueing/Stalled, колонка Connection ID
    не той URL або порожнє тілоланцюг редиректівкоди 3xx і Location, прапорець -L
    «дані не приходять» у браузері, а в curl усе гараздpreflightзапис OPTIONS перед основним запитом
    елемента ще немає, хоч відповідь прийшларендерочікування факту замість паузи

    Наша практика (не канон). Канонічного джерела під це немає, але правило варте того, щоб його записали: піднімати таймаут замість діагнозу — означає ховати проблему. Більший таймаут не робить тест стабільним, він робить його повільним і перетворює швидке падіння на довге зависання.

    Типові помилки

    • Виглядає як «повільний фронтенд», а насправді велика фаза Waiting (TTFB): думає сервер, і жодна оптимізація верстки цього не змінить.
    • Виглядає як «сервер не отримав запит», а насправді відповідь прийшла з кешу або від service worker — рядок у панелі є, мережевого обміну не було.
    • Виглядає як «дані не приходять», а насправді не пройшов preflight: браузер заблокував основний запит ще до відправлення, і бекенд його не бачив.
    • Виглядає як «редирект безкоштовний», а насправді кожен крок ланцюга — окремий HTTP-запит із ціною, яку MDN називає відчутною.
    • Виглядає як «браузер завжди тримає шість зʼєднань», а насправді це поточна практика для HTTP/1.0 і HTTP/1.1; на HTTP/2 клієнт не повинен відкривати більш ніж одне.
    • Виглядає як «спрацював load, отже дані на місці», а насправді подія засвідчує лише ресурси самої сторінки, а не дані, які JavaScript довантажує пізніше.
    • Виглядає як «у Postman 200, отже баг фронтенду», а насправді CORS перевіряє лише браузер: клієнти поза ним заголовки Access-Control-* ігнорують.

    Підсумок

    1. Шлях запиту — послідовність фаз, і кожна стрілка між ними коштує часу й уміє зламатися окремо від інших.
    2. Рукостискань на звичайному HTTPS-запиті щонайменше два (TCP і TLS), плюс третє для WebSocket; платяться вони раз на зʼєднання, тому перший запит до хоста дорожчий за наступні.
    3. TTFB — межа між «сервер думає» і «дані йдуть», але це два різні виміри: навігаційний включає резолвінг і рукостискання, фаза в DevTools — ні.
    4. Кеш уміє обірвати шлях на початку, а редирект і preflight — подовжити його зайвими повними запитами.
    5. Діагностика починається з локалізації фази — розкладкою часу або фазами Timing, — і лише потім переходить до гіпотези про причину.

    Можливі питання

    • «Що відбувається між натисканням Enter і появою сторінки?» Питання на структуру мислення. Сильна відповідь називає фази по порядку й одразу додає, що кожна — це і час, і окремий режим відмови.
    • «Скільки рукостискань на шляху HTTPS-запиту?» Перевіряють, чи не злипаються у вас TCP і TLS в одне. Очікують «щонайменше два» плюс третє для WebSocket, зроблене як HTTP-запит Upgrade.
    • «Що таке TTFB і що саме він міряє?» Дивляться на точність: чи згадаєте, що під однією абревіатурою живуть два різні виміри, і чи скажете, звідки взято число.
    • «Тест падає лише на одному стенді. Ваші дії?» Міні-кейс, у якому слухають порядок: спершу фаза, потім гіпотеза, і лише тоді код.
    • «Чому запит працює в curl, але падає в браузері?» Питання про межу відповідальності клієнта. Очікують: браузер додає шар, якого поза ним немає, — CORS і preflight, автоматичні Cookie й Origin, кеш і service worker.
    • «Чому не можна просто підняти таймаут?» Перевіряють інженерну зрілість: сильна відповідь спершу питає, чий таймаут спрацював.

    Джерела

    Сім фаз одного запиту

    • Chrome DevTools — Network features reference — фази запиту в розкладці Timing: резолвінг, встановлення зʼєднання з TCP-рукостисканням і узгодженням SSL, очікування першого байта, завантаження тіла.
    • MDN — Critical rendering path — що відбувається з відповіддю після отримання і як із неї постає сторінка.

    Резолвінг імені: фаза, якої не видно

    Рукостискання: скільки їх на шляху HTTPS-запиту

    • RFC 9293 — Transmission Control Protocol (TCP) — тристороннє рукостискання, чому кроків саме три, зʼєднання як пара сокетів.
    • RFC 8446 — TLS 1.3 — два компоненти протоколу, шифрування всього після ServerHello, «1-RTT handshake» і 0-RTT із зовнішнім або успадкованим PSK разом з його ціною.
    • RFC 6066 — TLS Extensions: Extension Definitions — SNI у ClientHello як спосіб отримати правильний сертифікат від сервера з багатьма доменами.
    • RFC 6455 — The WebSocket Protocol — відкривальне рукостискання як HTTP-запит Upgrade і 101 як єдина ознака успіху.
    • MDN — Connection management in HTTP/1.x відкритого зʼєднання, через яке перший запит дорожчий за наступні.

    Запит пішов: TTFB як межа між «сервер думає» і «дані йдуть»

    • WHATWG Fetch Standard — поіменний перелік forbidden request-header і правило, за яким User-Agent додається лише за відсутності власного значення.
    • MDN — HTTP messages — склад запиту: метод, шлях, заголовки, тіло.
    • MDN — Mixed content — незахищені підресурси на захищеній сторінці браузер або підвищує до HTTPS, або блокує.
    • W3C — Content Security Policy Level 3 — політика керує тим, які ресурси сторінці дозволено завантажувати й виконувати.
    • MDN Glossary — Time to first byte (TTFB) — навігаційний TTFB включає резолвінг DNS, TCP- і TLS-рукостискання.
    • web.dev — Time to First Byte (TTFB) — розклад навігаційного TTFB на суму фаз, зокрема час редиректів.
    • Chrome DevTools — Network features referenceWaiting (TTFB) як окрема фаза після встановлення зʼєднання: один RTT плюс підготовка відповіді.

    Кеш: фаза, яка вміє обірвати шлях на самому початку

    • RFC 9111 — HTTP Caching — кеш як сховище відповідей, перевикористання свіжої копії замість походу мережею, семантика 304 Not Modified.
    • MDN — HTTP caching — правила кешування диктує сервер заголовками відповіді.
    • MDN — Service Worker API як проксі між застосунком, браузером і мережею, що перехоплює навігаційні та ресурсні запити.
    • Chrome DevTools — Network features reference — фаза Content Download як отримання відповіді з мережі або від service worker.

    Редирект і preflight: фази, що подовжують ланцюг

    • MDN — Redirections in HTTP3xx плюс Location, поведінка методу й тіла для 301/302/303/307/308, ціна редиректу в продуктивності, петля й відповідь 500.
    • RFC 9110 — HTTP Semantics — семантика класу 3xx: запит нормальний, але для завершення потрібна ще одна дія.
    • curl — manual page (--write-out variables)curl повторює запит за новою адресою лише з -L/--location.
    • web.dev — Time to First Byte (TTFB) — час редиректів як складова навігаційного TTFB.
    • MDN — Cross-Origin Resource Sharing (CORS) — preflight як окремий OPTIONS-запит, його заголовки, Access-Control-Max-Age і два записи на один логічний виклик.
    • WHATWG Fetch Standard — умови, за яких preflight потрібен, безпечний перелік заголовків і значень Content-Type, «ok»-статус як умова успіху, заборона надсилати preflight з обліковими даними.

    Скільки зʼєднань і якою версією протоколу

    Рендер: «відповідь прийшла» ще не означає «видно»

    Що з цього видно у вкладці Network

    • Chrome DevTools — Network features reference — автоматичний запис лише за відкритих DevTools, колонка Time, Waterfall за часом старту, повна розкладка фаз Timing, колонки Protocol і Connection ID поза дефолтним набором, санітизований експорт HAR.

    Діагностика фазами: від симптому до фази

    Пояснення

    «Поясни» працює з власним API-ключем Anthropic: запит іде з вашого браузера прямо до Anthropic.

    Свій API-ключ (BYOK)

    Вставте власний ключ Anthropic — пояснення працюватиме на реальній моделі. Ключ зберігається лише у вашому браузері (localStorage), нікуди не надсилається, крім api.anthropic.com, і не логується.