Բոլոր դասերը
Վեբի հիմունքներՍկսնակ10 րոպե ընթերցումԻմ ստեկում

Ինչպես է աշխատում վեբը

Ի՞նչ է իրականում կատարվում URL-ը մուտքագրելու և էջը տեսնելու միջև։

  • DNS
  • TCP
  • TLS
  • HTTP
  • Rendering
Քայլ 1/6
Գրում ես example.com և սեղմում Enter։ Բրաուզերը գործի է անցնում։

30 վայրկյանում

Երբ բացում եք կայք, բրաուզերը գտնում է սերվերի հասցեն (DNS), բացում է կապ նրա հետ (TCP կամ QUIC), այն դարձնում է գաղտնի (TLS), խնդրում է էջը (HTTP), իսկ հետո պատասխանը վերածում է պիքսելների։ Ամեն քայլ տևում է միլիվայրկյաններ, և ամեն մեկն այն տեղն է, որտեղ կայքը կարող է լինել արագ կամ դանդաղ, անվտանգ կամ կոտրված։ Այս շղթան իմանալը հիմքն է վեբի մնացած բոլոր թեմաների համար։

Ինչու եմ օգտագործում

  • Այս մտավոր մոդելն օգտագործում եմ ամեն օր․ երբ կայքը դանդաղ է կամ չի աշխատում, գուշակելու փոխարեն քայլ առ քայլ անցնում եմ շղթայով։
  • Production-ում հանդիպող գրեթե յուրաքանչյուր բագ նստած է այս շղթայի որևէ օղակում՝ DNS գրառում, սերտիֆիկատ, proxy header, քեշ կամ render-ը արգելափակող սկրիպտ։
  • Դա թույլ է տալիս հաճախորդներին պարզ բառերով բացատրել, թե ինչու CDN-ը, HTTPS-ը կամ քեշավորումն արժե վճարել։
  • Ֆրոնտենդի և բեքենդի արագությունն իմաստ ունեն միայն միասին․ այս ճանապարհն է նրանց կապում։

Ինչպես է աշխատում

01Ընդհանուր պատկերը՝ ռեստորանի անալոգիա

Պատկերացրեք, որ կայք այցելելը նման է պատվեր տալուն մի ռեստորանում, որտեղ երբեք չեք եղել։ Նախ գտնում եք հասցեն (DNS)։ Հետո գնում եք այնտեղ և սեղան ստանում (TCP կապ)։ Մատուցողի հետ պայմանավորվում եք գաղտնի լեզվի մասին, որպեսզի ուրիշ ոչ ոք չլսի (TLS)։ Պատվիրում եք մենյուից (HTTP հարցում)։ Խոհանոցը պատրաստում է (սերվերը կատարում է կոդը և հարցում անում տվյալների բազային)։ Մատուցողը բերում է ափսեն (HTTP պատասխան), և դուք այն դասավորում եք սեղանին ու սկսում ուտել (բրաուզերը parse և render է անում)։ CDN-ը ռեստորանի մասնաճյուղ է ձեր տան մոտ, որտեղ հայտնի ուտեստներն արդեն պատրաստ են։ Այս պատկերը պահեք մտքում․ ներքևի յուրաքանչյուր քայլ դրա մի մասն է։

  • URL՝ https://example.com/products?page=2 = scheme + host + path + query։
  • Client = բրաուզերը կամ հավելվածը, server = պատասխանող մեքենան։
  • Էջերի մեծ մասի համար latency-ն (round-trip time) ավելի կարևոր է, քան bandwidth-ը։

02Քայլ 1–3՝ DNS, TCP և TLS

Բրաուզերին պետք է IP հասցե, ոչ թե անուն։ Այն ստուգում է իր քեշը, օպերացիոն համակարգը, հետո հարցնում recursive resolver-ին (ձեր ISP-ից, 1.1.1.1 կամ 8.8.8.8)։ Resolver-ը անցնում է root սերվերներով, հետո .com սերվերներով, հետո դոմենի authoritative nameserver-ներով և պատասխանը քեշավորում իր TTL-ի չափով։ IP-ն ունենալով՝ բրաուզերը բացում է TCP կապ 443 պորտին՝ եռաքայլ handshake-ով (SYN, SYN-ACK, ACK)։ Հետո աշխատում է TLS 1.3-ը․ բրաուզերն ու սերվերը համաձայնեցնում են բանալիները, իսկ սերվերը սերտիֆիկատով ապացուցում է իր ինքնությունը։ TLS 1.3-ին պետք է մեկ լրացուցիչ round trip․ HTTP/3-ը տրանսպորտն ու TLS-ը միավորում է մեկ QUIC handshake-ի մեջ UDP-ի վրա։ 100 ms latency ունեցող մոբայլ կապի դեպքում այս round trip-երն արդեն 200–300 ms են՝ նախքան HTML-ի առաջին բայթը, ահա թե ինչու են կարևոր վերաօգտագործվող կապերն ու մոտ գտնվող սերվերները։

bash
# See each phase of a real request with timings
curl -o /dev/null -s -w "dns: %{time_namelookup}s
tcp: %{time_connect}s
tls: %{time_appconnect}s
first byte: %{time_starttransfer}s
total: %{time_total}s
" https://example.com/

03Քայլ 4–6՝ հարցում, սերվեր, պատասխան

Անվտանգ կապով բրաուզերն ուղարկում է HTTP հարցում՝ մեթոդ (GET), path և header-ներ, օրինակ՝ Host, Accept-Language, cookie-ներ և քեշավորման ակնարկներ։ Սերվերի կողմում այն ընդունում է nginx-ի նման վեբ սերվերը։ Այն կարող է անմիջապես պատասխանել ստատիկ ֆայլով կամ հարցումը փոխանցել հավելվածին (Laravel՝ PHP-FPM-ի միջոցով, Node.js պրոցես), որը կատարում է բիզնես լոգիկան, կարդում է տվյալների բազան կամ քեշը և կառուցում HTML կամ JSON։ Պատասխանը վերադառնում է status code-ով (200, 301, 404, 500), header-ներով (Content-Type, Cache-Control, Set-Cookie) և body-ով, որը սովորաբար սեղմված է gzip-ով կամ Brotli-ով։ Time to First Byte-ը (TTFB) չափում է այս ամբողջ շրջանը՝ ցանց գումարած սերվերի աշխատանք։ Դանդաղ TTFB-ն սովորաբար նշանակում է դանդաղ query-ներ, քեշի բացակայություն կամ օգտատիրոջից հեռու գտնվող սերվեր։

http
GET /products?page=2 HTTP/1.1
Host: example.com
Accept: text/html
Accept-Encoding: br, gzip
 
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Encoding: br
Cache-Control: public, max-age=60

04Քայլ 7՝ բրաուզերը կառուցում է էջը

Բրաուզերը կարդում է HTML-ը, մինչ այն հոսքով գալիս է, և կառուցում DOM-ը՝ էլեմենտների ծառ։ Երբ հանդիպում է CSS, ներբեռնում և parse է անում այն CSSOM-ի մեջ․ CSS-ը render-blocking է, քանի որ բրաուզերը չի նկարի առանց ոճերի բովանդակություն։ Դասական script թեգերը նույնպես արգելափակում են parsing-ը, եթե չունեն defer կամ async։ DOM-ն ու CSSOM-ը միավորվում են render tree-ի մեջ, հետո բրաուզերը հաշվում է layout-ը (չափեր և դիրքեր), նկարում պիքսելները և GPU-ի վրա composite անում շերտերը։ Պատկերները, ֆոնտերը և լրացուցիչ սկրիպտները բեռնվում են զուգահեռ։ JavaScript-ը կարող է հետո փոխել DOM-ը, ինչը կարող է կրկին layout առաջացնել։ Core Web Vitals-ը չափում է արդյունքը՝ LCP (որքան արագ է հայտնվում հիմնական բովանդակությունը), INP (որքան արագ է էջը արձագանքում մուտքին) և CLS (որքան են տարրերը ցատկոտում)։

  • CSS-ը դրեք վաղ, սկրիպտները՝ defer-ով, իսկ պատկերներին տվեք width և height։
  • Preload արեք hero պատկերն ու հիմնական ֆոնտը, lazy-load արեք այն, ինչ fold-ից ներքև է։
  • Ավելի քիչ JavaScript գրեթե միշտ նշանակում է ավելի արագ և արձագանքող էջ։

05Որտեղ է տեղավորվում CDN-ը

CDN-ը (Content Delivery Network), օրինակ՝ Cloudflare, Fastly կամ CloudFront, սերվերներ ունի հարյուրավոր քաղաքներում։ Երբ ձեր DNS-ը ցույց է տալիս CDN-ը, այցելուի TLS handshake-ն ավարտվում է ամենամոտ edge սերվերում, հաճախ 10–30 ms հեռավորության վրա՝ 150 ms-ի փոխարեն։ Edge-ը քեշավորված ֆայլերը (պատկերներ, CSS, JS, երբեմն ամբողջական HTML էջեր) մատուցում է անմիջապես, և միայն cache miss-երն է փոխանցում ձեր origin սերվերին՝ տաք, վերաօգտագործվող կապով։ Շատ CDN-ներ ավելացնում են նաև DDoS պաշտպանություն, web application firewall և HTTP/3։ Գինը մեկ լրացուցիչ շերտ է, որը պետք է հասկանալ՝ քեշավորման կանոններ, SSL կարգավորումներ edge-ի և origin-ի միջև, և այն փաստը, որ ձեր սերվերն այժմ տեսնում է CDN-ի IP-ն, եթե չվերականգնեք այցելուի իրական IP-ն header-ից։

06Շղթայի debug-ը գործնականում

Երբ ինչ-որ բան սխալ է, գուշակելու փոխարեն հերթով ստուգեք յուրաքանչյուր օղակ։ Անունը resolve լինո՞ւմ է ճիշտ IP-ին։ Կարո՞ղ եք TCP կապ բացել 443 պորտին։ Սերտիֆիկատը վավե՞ր է այս hostname-ի համար։ Ի՞նչ status code և header-ներ են վերադառնում։ Սերվե՞րն է դանդաղ (բարձր TTFB), թե՞ բրաուզերը (երկար scripting կամ rendering DevTools-ում)։ Բրաուզերի Network tab-ը ցույց է տալիս DNS-ի, connect-ի, TLS-ի, սպասման և ներբեռնման ժամանակը յուրաքանչյուր ֆայլի համար։ Performance tab-ն ու Lighthouse-ը ցույց են տալիս parsing-ը, layout-ը և paint-ը։ Սերվերում access և error լոգերը ցույց են տալիս՝ հարցումն ընդհանրապես հասե՞լ է, թե ոչ։

bash
dig +short example.com A           # 1. DNS
nc -vz example.com 443             # 2. TCP port open?
openssl s_client -connect example.com:443 -servername example.com </dev/null | head -n 20   # 3. TLS
curl -sI https://example.com/      # 4. status + headers
sudo tail -f /var/log/nginx/access.log   # 5. did it reach the server?

Օգտագործեք, երբ

  • Ախտորոշել, թե ինչու է կայքը չաշխատում, դանդաղ է կամ սերտիֆիկատի սխալ է ցույց տալիս։
  • Նոր deploy պլանավորելիս՝ DNS-ի, CDN-ի, TLS-ի և սերվերի ընտրությունները բոլորը գալիս են այս շղթայից։
  • Ոչ տեխնիկական մարդկանց բացատրել performance-ի աշխատանքը (CDN, քեշավորում, պատկերների օպտիմալացում)։
  • Հարցազրույցների պատրաստվելիս՝ «ի՞նչ է կատարվում, երբ մուտքագրում ես URL» դասական հարց է։

Մի՛ օգտագործեք, երբ

  • Կայք կառուցելու համար պետք չէ անգիր անել TCP-ի յուրաքանչյուր flag․ սովորեք այն խորությամբ, որքան պետք է, երբ խնդիր է առաջանում։
  • Մի օպտիմալացրեք ցանցային round trip-երը՝ նախքան սերվերի ակնհայտ խնդիրները, օրինակ՝ դանդաղ query-ները, շտկելը։

Այլընտրանքներ

  • Native հավելվածներ

    Բաց են թողնում HTML-ի render-ը, բայց API-ների հետ խոսելու համար դեռ օգտագործում են DNS, TLS և HTTP։

  • WebSockets / SSE

    Real-time թարմացումների համար մեկ կապ են պահում բաց՝ ամեն փոփոխության համար request–response-ի փոխարեն։

  • Ստատիկ hosting CDN-ի վրա

    Հազվադեպ փոխվող էջերի համար ճանապարհից հանում է հավելվածի սերվերը։

Լավագույն պրակտիկաներ

  1. Ամեն ինչ մատուցեք HTTPS-ով՝ միացված HTTP/2-ով կամ HTTP/3-ով։
  2. Հանրային կայքերի առջև դրեք CDN և ստատիկ ֆայլերը քեշավորեք երկար, տարբերակավորված ժամկետներով։
  3. Պահեք TTFB-ն ցածր՝ քեշավորեք տաք տվյալները, index արեք query-ները, սերվերները պահեք օգտատերերին մոտ։
  4. Ուղարկեք ավելի քիչ JavaScript, defer արեք ոչ կրիտիկական սկրիպտները և խուսափեք render-blocking ռեսուրսներից։
  5. Տեքստային պատասխանները սեղմեք Brotli-ով կամ gzip-ով և մատուցեք ժամանակակից պատկերային ֆորմատներ (WebP, AVIF)։
  6. Չափեք իրական օգտատերերի տվյալներով (Core Web Vitals), ոչ միայն գրասենյակային Wi-Fi-ով արագ լափթոփով։

Տարածված սխալներ

  • Մեղադրել «սերվերին»՝ առանց նախապես ստուգելու DNS-ը, սերտիֆիկատները կամ բրաուզերը։
  • Մեծ, արգելափակող սկրիպտներ բեռնել head-ում՝ հետաձգելով առաջին paint-ը։
  • Մոռանալ, որ CDN-ը կամ proxy-ն թաքցնում է այցելուի իրական IP-ն լոգերից և rate limit-երից։
  • Մոբայլ հեռախոսներին պատկերներ մատուցել տեսախցիկի լրիվ թույլատրությամբ։

Խորը վերլուծություն

07Ինչու են առաջին 14 KB-ը կարևոր. TCP slow start

Նոր TCP կամ QUIC կապը չգիտի, թե որքան արագ է ճանապարհը, դրա համար սկսում է զգուշորեն։ Ուղարկողը կարող է «օդում» պահել մոտ տասը փաթեթ (սկզբնական congestion window, մոտ 14 KB), հետո պետք է սպասի հաստատումներին, իսկ հետո յուրաքանչյուր round trip-ում կրկնապատկում է այդ ծավալը, քանի դեռ ոչինչ չի կորչում։ Այսինքն՝ թարմ կապով 100 KB HTML փաստաթուղթը պահանջում է մի քանի round trip, ոչ թե մեկ, նույնիսկ արագ գծում։ Ահա թե ինչու critical CSS-ը inline անելը և HTML-ի վերին մասը փոքր պահելը արագացնում են առաջին նկարումը, և ինչու վերօգտագործվող, արդեն «տաքացած» կապերն այդքան ավելի արագ են թվում։ Փաթեթների կորուստը ստիպում է ուղարկողին նորից փոքրացնել պատուհանը, ահա թե ինչու կորուստներով մոբայլ ցանցերն ավելի շատ են վնասում, քան ցույց են տալիս bandwidth-ի թվերը։ Ժամանակակից congestion control-ը, օրինակ BBR-ը, կորուստներին ավելի լավ է արձագանքում, քան հին ալգորիթմները, բայց round trip-ների ֆիզիկան մնում է։

  • Փոքր, սերվերում ռենդեր արված HTML-ը critical CSS-ով ավելի շուտ է նկարվում։
  • Կապի վերօգտագործումը (keep-alive, HTTP/2 multiplexing) հաջորդ հարցումների համար շրջանցում է slow start-ը։
  • Յուրաքանչյուր լրացուցիչ origin նշանակում է նոր DNS lookup, handshake և «սառը» պատուհան։

08Ինչպես է բրաուզերը որոշում, թե ինչն առաջինը բեռնել

Բրաուզերները ռեսուրսները չեն բեռնում էջի հերթականությամբ։ Մինչ հիմնական parser-ը սպասում է script-ին, preload scanner-ը առաջ է կարդում «հում» HTML-ը և սկսում է բեռնել իր գտած նկարները, stylesheet-ները և script-ները։ Յուրաքանչյուր հարցում ստանում է առաջնահերթություն. CSS-ը և blocking script-ները բարձր են, viewport-ի նկարները բարձրացվում են layout-ից հետո, async script-ները և էջի ներքևի նկարները ցածր են։ Սա կարելի է կառավարել։ rel=preload-ը բեռնում է այն, ինչ scanner-ը չի տեսնում, օրինակ՝ font, որին հղում կա միայն CSS-ի ներսում։ fetchpriority=high-ը LCP նկարը նշում է որպես կարևոր։ 103 Early Hints-ը թույլ է տալիս սերվերին կամ CDN-ին preload հղումներն ուղարկել դեռ HTML-ի պատրաստ լինելուց առաջ՝ օգտագործելով սերվերի «մտածելու» ժամանակը։ Թակարդը չափազանց օգտագործելն է. եթե ամեն ինչ բարձր առաջնահերթություն ունի, ուրեմն ոչինչ չունի, իսկ չօգտագործվող ֆայլերի preload-ը կրիտիկական ճանապարհին bandwidth է վատնում։

html
<!-- In the <head>: help the browser find critical files early -->
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
<img src="/img/hero.avif" width="1200" height="630" fetchpriority="high" alt="Product hero">
<img src="/img/footer.webp" width="400" height="300" loading="lazy" alt="Team photo">
<script src="/js/app.3f9a1c.js" defer></script>

09Քեշի շերտերը օգտատիրոջ և տվյալների բազայի միջև

Հարցմանը կարելի է պատասխանել բազմաթիվ շերտերում, և յուրաքանչյուրն ավելի էժան է հաջորդից։ Բրաուզերում՝ back/forward cache-ը ամբողջ էջերը պահում է հիշողության մեջ՝ ակնթարթային «հետ» նավիգացիայի համար, memory և HTTP disk cache-երը ֆայլեր են պահում ըստ Cache-Control-ի, service worker-ը կարող է պատասխանել իր սեփական քեշից, նույնիսկ offline։ Հետո CDN edge-ն է, երբեմն origin-ի առջև ռեգիոնալ շերտով։ Origin-ում nginx-ի նման reverse proxy-ն կարող է քեշավորել ամբողջական պատասխաններ (microcaching-ը մի քանի վայրկյանով կլանում է տրաֆիկի պիկերը)։ Հավելվածի ներսում Redis-ը կամ memory cache-ը պահում են հաշվարկված տվյալներ, իսկ բազան ունի իր buffer pool-ը։ Ինժեներական հարցը միշտ նույնն է. որտե՞ղ կարելի է այս պատասխանն ապահով վերօգտագործել, ո՞ւմ համար և որքա՞ն ժամանակ։ Անհատականացված տվյալները կարող են ապրել միայն այն քեշերում, որոնց key-ը կապված է տվյալ օգտատիրոջ հետ։

10Վստահությունը շղթայի երկայնքով. ինչը կարելի է կեղծել

Յուրաքանչյուր քայլ ինչ-որ բանի վստահում է։ Սովորական DNS պատասխանները թշնամական ցանցում կարելի է կեղծել, դրա համար էլ գոյություն ունի DNSSEC-ը, իսկ գաղտնագրված DNS-ը (DNS over HTTPS կամ TLS) lookup-ները թաքցնում է լոկալ ցանցից։ Իրական պաշտպանությունը, սակայն, TLS-ն է. նույնիսկ եթե DNS-ը ձեզ սխալ IP ուղարկի, հարձակվողը չի կարող ներկայացնել example.com-ի վավեր սերտիֆիկատ, և բրաուզերը կանգ կառնի։ HSTS-ը վերացնում է առաջին ոչ անվտանգ http:// հարցումը, որը հարձակվողը կարող էր որսալ։ Բրաուզերի ներսում same-origin policy-ն թույլ չի տալիս մի կայքին կարդալ մյուսի տվյալները, SameSite-ով cookie-ները սահմանափակում են cross-site հարցումները, իսկ Content-Security-Policy-ն սահմանափակում է, թե որ script-ները կարող են աշխատել։ Սերվերի կողմում հարցման ամեն ինչ (header-ներ, cookie-ներ, X-Forwarded-For) օգտատիրոջ input է, քանի դեռ վստահելի proxy-ն չի երաշխավորել դրա համար։

Իրական իրավիճակներ

01

Գրասենյակում արագ է, արտասահմանի օգտատերերի մոտ՝ դանդաղ

Խնդիր

Data center-ի մոտ գտնվող թիմի համար կայքն ակնթարթային է, բայց մեկ այլ մայրցամաքի օգտատերերը բողոքում են երեքից չորս վայրկյան բեռնումից։ Սերվերի մետրիկաները նորմալ են։

Ինչպես լուծել

Չափեք այնտեղից, որտեղ օգտատերերն են. curl timing աշխատեցրեք հեռավոր VPS-ից կամ multi-region թեստով և համեմատեք DNS, connect, TLS և TTFB։ Եթե connect-ը և TLS-ը մոտ 150 ms են տևում, խնդիրը հեռավորությունն է, ոչ թե կոդը։ Առջևում դրեք CDN, որպեսզի handshake-ները ավարտվեն մոտակա edge-ում, static ֆայլերը քեշավորեք երկար, տարբերակված ժամկետներով, իսկ եթե էջերը հրապարակային են, HTML-ը կարճ ժամանակով քեշավորեք edge-ում։ Միացրեք HTTP/2 և HTTP/3, հեռացրեք ավելորդ third-party origin-ները և կրճատեք redirect-ների շղթաները։ Հետո ստուգեք իրական օգտատերերի Core Web Vitals-ը ըստ երկրների՝ բարելավումը հաստատելու համար։

02

TTFB-ն լավն է, բայց LCP-ն չորս վայրկյանից ավելի է

Խնդիր

HTML-ը գալիս է 200 ms-ում, բայց մոբայլում հիմնական նկարն ուշ է երևում։ Lighthouse-ը LCP տարրը նշում է որպես մեծ hero նկար։

Ինչպես լուծել

Ուշացումը բրաուզերում է, ուրեմն նայեք waterfall-ին։ Տիպիկ պատճառներ. hero նկարը դրված է որպես CSS background կամ ավելացվում է JavaScript-ով, և preload scanner-ը չի կարող գտնել այն, սխալմամբ lazy-load է արված, կամ 3 MB JPEG է։ Ուղղեք՝ օգտագործելով սովորական img tag width-ով և height-ով, fetchpriority=high և առանց loading=lazy, մատուցեք AVIF կամ WebP ճիշտ չափով՝ srcset-ով, և preconnect արեք image CDN-ին։ Render-blocking script-ները տեղափոխեք defer։ Նորից թեստավորեք throttled մոբայլ պրոֆիլով և մի քանի օր անց ստուգեք field data-ն։

03

Միգրացիայից հետո որոշ օգտատերեր դեռ տեսնում են հին սերվերը

Խնդիր

A record-ը մեկ ժամ առաջ փոխվել է նոր սերվերի վրա։ Տրաֆիկի մեծ մասը տեղափոխվել է, բայց մի քանի հաճախորդ դեռ տեսնում է հին կայքը և դրա հին տվյալները։

Ինչպես լուծել

Սա քեշավորված DNS է, ոչ թե կոտրված deploy։ Ստուգեք, թե ինչ TTL ուներ հին record-ը. resolver-ները կարող են պահել այն մինչև ժամկետի ավարտը, իսկ որոշ client-ներ ավելի երկար են քեշավորում։ Հաստատեք authoritative պատասխանը dig-ով՝ nameserver-ին ուղղված, և համեմատեք հրապարակային resolver-ների հետ։ Հին սերվերը թողեք աշխատող և կամ դարձրեք read-only՝ banner-ով, կամ նրա տրաֆիկը proxy արեք նոր սերվերին, որպեսզի գրառումները չբաժանվեն երկու բազայի միջև։ Հաջորդ անգամ մեկ օր առաջ TTL-ն իջեցրեք 300 վայրկյանի։ Երբ հին սերվերի access log-երը լռեն, ապամոնտաժեք այն։

Արագ ուղեցույց

Չափել հարցման յուրաքանչյուր փուլի ժամանակը
curl -o /dev/null -s -w "%{time_namelookup} %{time_connect} %{time_appconnect} %{time_starttransfer} %{time_total}\n" https://example.com/
Resolve անել անունը հրապարակային resolver-ով
dig +short example.com A @1.1.1.1
Ստուգել, որ TCP port-ը բաց է
nc -vz example.com 443
Տեսնել սերտիֆիկատը և TLS տարբերակը
openssl s_client -connect example.com:443 -servername example.com -brief </dev/null
Միայն header-ները
curl -sI https://example.com/
Դիմել կոնկրետ սերվերի՝ շրջանցելով DNS-ը
curl -sI https://example.com/ --resolve example.com:443:203.0.113.10
Հետևել ցանցային ճանապարհին և փաթեթների կորստին
mtr -rwc 50 example.com
Լաբորատոր performance audit
npx lighthouse https://example.com --view
LCP նկարը դարձնել առաջնահերթ
<img src="/hero.avif" fetchpriority="high" width="1200" height="630" alt="">

Իմ իրական նախագծերում

  • Production Laravel և Next.js կայքեր եմ աշխատեցնում Ubuntu սերվերների վրա՝ առջևում nginx-ով, և միջադեպերը ախտորոշելիս անցնում եմ այս շղթայով։
  • Իմ կառավարած կայքերում Cloudflare-ը կանգնած է առջևում DNS-ի և հիմնական DDoS պաշտպանության համար, ամենուր HTTPS և ավտոմատ թարմացվող սերտիֆիկատներ։
  • Կարդում եմ սերվերի լոգերը, որպեսզի production-ի խնդիրները հետևեմ մինչև կոնկրետ հարցումը, օրինակ՝ լոկալիզացիայի middleware-ի բագը և պատկեր-WebP փոխարկման բագը։

Հարցեր և պատասխաններ

Q1Ի՞նչ է կատարվում, երբ մուտքագրում ես URL և սեղմում Enter։

Բրաուզերը parse է անում URL-ը և ստուգում քեշերը։ Եթե IP չունի, անունը resolve է անում recursive resolver-ի միջոցով, որն անցնում է root, TLD և authoritative nameserver-ներով։ Այն բացում է TCP կապ 443 պորտին և կատարում TLS handshake՝ ստուգելով սերտիֆիկատը։ Հետո ուղարկում է HTTP հարցում header-ներով և cookie-ներով։ Սերվերը, հաճախ nginx հավելվածի առջև, կատարում է կոդը, կարող է հարցում անել տվյալների բազային և վերադարձնում է status, header-ներ և body։ Բրաուզերը HTML-ը parse է անում DOM-ի, CSS-ը՝ CSSOM-ի մեջ, կատարում է սկրիպտները, հաշվում layout-ը, նկարում և composite անում։ CDN-ը կարող է պատասխանել edge-ից՝ ընդհանրապես չդիպչելով origin-ին։

Q2Ի՞նչ է TTFB-ն և ինչպե՞ս կլավացնեիր այն։

Time to First Byte-ը հարցումն ուղարկելուց մինչև պատասխանի առաջին բայթը ստանալու ժամանակն է։ Այն ներառում է DNS-ը, կապի և TLS-ի կարգավորումը, ցանցային latency-ն և սերվերի մշակման ժամանակը։ Այն լավացնելու համար նախ ստուգում եմ սերվերի ժամանակը՝ դանդաղ query-ներ, բացակայող index-ներ, N+1 query-ներ, հավելվածի քեշի բացակայություն։ Հետո նայում եմ հեռավորությանը․ CDN-ը կամ edge քեշը բովանդակությունը մոտեցնում է և վերաօգտագործում origin-ի հետ տաք կապերը։ HTTP/2-ը կամ HTTP/3-ը և keep-alive-ը կրճատում են handshake-ի ծախսը։ Հազվադեպ փոխվող էջերի համար ամբողջական HTML-ի քեշավորումը edge-ում կարող է TTFB-ն հարյուրավոր միլիվայրկյաններից իջեցնել մի քանի տասնյակի։

Q3Ի՞նչ է critical rendering path-ը։

Դա այն հաջորդականությունն է, որը բրաուզերը պետք է ավարտի, նախքան կկարողանա նկարել՝ ներբեռնել և parse անել HTML-ը DOM-ի մեջ, ներբեռնել և parse անել CSS-ը CSSOM-ի մեջ, կատարել արգելափակող սկրիպտները, ամեն ինչ միավորել render tree-ի մեջ, հաշվել layout-ը և նկարել։ Այն ամենը, ինչ արգելափակում է այս ճանապարհը, հետաձգում է առաջին իմաստալից paint-ը։ CSS-ը արգելափակում է rendering-ը, իսկ դասական սկրիպտները՝ parsing-ը։ Այն կրճատելու համար inline եմ անում կամ առաջնահերթություն տալիս կրիտիկական CSS-ին, սկրիպտներին ավելացնում եմ defer, preload եմ անում hero պատկերն ու հիմնական ֆոնտը և խուսափում եմ client-side մեծ bundle-ներից։ Նպատակն այն է, որ ամենամեծ տեսանելի էլեմենտն արագ հայտնվի, և հենց դա է չափում LCP-ն։

Q4Ինչո՞ւ է CDN-ը կայքն արագացնում, և որո՞նք են ռիսկերը։

Վեբում ուշացման մեծ մասը round trip-երն են, ոչ թե bandwidth-ը։ CDN-ը TCP-ն ու TLS-ը ավարտում է այցելուին մոտ գտնվող edge սերվերում, այնպես որ handshake-երը տևում են մի քանի միլիվայրկյան՝ երկար միջմայրցամաքային ճանապարհի փոխարեն։ Քեշավորված ռեսուրսները մատուցվում են edge-ից, իսկ miss-երը origin են հասնում տաք, վերաօգտագործվող կապերով։ Ռիսկերը կոնֆիգուրացիայի մեջ են՝ պատահաբար քեշավորել մասնավոր կամ անհատականացված էջեր, edge-ի և origin-ի միջև սխալ SSL ռեժիմ, լոգերում և rate limiting-ում կորցնել client-ի իրական IP-ն, և deploy-ից հետո հնացած բովանդակություն։ Քեշի հստակ կանոնները, տարբերակավորված ֆայլանունները և deploy-ի ժամանակ purge քայլը լուծում են դրանց մեծ մասը։

Q5Ո՞րն է տարբերությունը TCP-ի և UDP-ի միջև, և ինչո՞ւ է վեբն այժմ օգտագործում երկուսն էլ։

TCP-ն տալիս է հուսալի, կարգավորված բայթային հոսք․ այն վերաուղարկում է կորած փաթեթները և տվյալները հասցնում հերթականությամբ՝ handshake-ի և փաթեթ կորցնելու դեպքում head-of-line blocking-ի գնով։ UDP-ն պարզապես ուղարկում է datagram-ներ՝ առանց հերթականության կամ առաքման երաշխիքների, ինչը ավելի թեթև է։ HTTP/1.1-ն ու HTTP/2-ը աշխատում են TCP-ի վրա։ HTTP/3-ն աշխատում է QUIC-ի վրա, որը կառուցված է UDP-ի վրա, բայց user space-ում ավելացնում է սեփական հուսալիություն, գաղտնագրում և անկախ stream-ներ։ Դա թույլ է տալիս, որ մեկ կորած փաթեթը հետաձգի միայն իր stream-ը, և միավորում է տրանսպորտի ու TLS-ի handshake-երը, ինչը շատ է օգնում մոբայլ ցանցերում։

Սենիոր մակարդակի հարցեր

S1Ինչպե՞ս կնախագծեք գլոբալ լսարանի համար մեկ origin սերվերով։

Ես կպահեմ մեկ origin-ը, որը պարզ է սպասարկել, և հնարավորինս շատ բան կտեղափոխեմ edge։ Static ֆայլերը ստանում են hash-ով անուններ և մեկ տարվա քեշավորում CDN-ում։ Հրապարակային HTML-ը edge-ում քեշավորվում է վայրկյաններից մինչև րոպեներ՝ stale-while-revalidate-ով, և purge է արվում հրապարակման ժամանակ։ Անհատականացված մասերը բեռնվում են փոքր API կանչերով, կամ էջը բաժանվում է այնպես, որ shell-ը քեշավորվի։ Tiered cache-ը ավելի է կրճատում origin-ին հասնող հարցումները։ Գրառումները դեռ գնում են origin, ուստի API պատասխանները պահում եմ փոքր և դարձնում idempotent՝ ապահով retry-ների համար։ Գինը cache invalidation-ի բարդությունն է և բովանդակության eventual consistency-ն։ Multi-region origin-ներն արդարացված են միայն այն ժամանակ, երբ գրառման latency-ի կամ հասանելիության պահանջները արժեն տվյալների շատ ավելի բարդ replication-ը։

S2Ո՞ւր կնայեք առաջինը, երբ p95 latency-ն կրկնապատկվում է, իսկ p50-ը մնում է նույնը։

Կայուն միջինը և վատացած «պոչը» սովորաբար նշանակում են, որ որոշ հարցումներ ընկնում են դանդաղ ճանապարհի վրա, ոչ թե ամեն ինչ է դանդաղել։ Բաժանում եմ ըստ չափումների. route, ռեգիոն, սարք, cache status և upstream։ Տարածված պատճառներն են՝ cache miss-եր deploy-ից կամ purge-ից հետո, կոնկրետ query, որը կորցրել է իր index-ը, lock contention, garbage collection կամ worker pool-ի սպառում, որի պատճառով հարցումները հերթ են կանգնում, դանդաղ third-party կանչ առանց timeout-ի, կամ փաթեթների կորուստ մեկ ցանցում։ Սերվերի կողմում nginx log-երում համեմատում եմ upstream response time-ը հարցման ընդհանուր ժամանակի հետ, որպեսզի հերթը տարանջատեմ աշխատանքից։ Request ID-ներով tracing-ը ցույց է տալիս, թե որտեղ է լրացուցիչ ժամանակը։ Ուղղումը կախված է պատճառից, բայց timeout-ները, pool-ի չափը և դանդաղ ճանապարհի քեշավորումը տիպիկ են։

S3SSR, static generation, թե client-rendered SPA. ինչպե՞ս են դրանք փոխում շղթան։

Static generation-ը HTML-ը ստեղծում է build-ի ժամանակ, ուստի CDN-ը կարող է պատասխանել ամեն ինչի, և TTFB-ն նվազագույն է. գինը rebuild-ներն են կամ revalidation-ը, երբ բովանդակությունը փոխվում է։ Server-side rendering-ը HTML-ը կառուցում է յուրաքանչյուր հարցման համար՝ տալով թարմ, անհատականացված բովանդակություն և լավ LCP, բայց TTFB-ն կախված է սերվերի և տվյալների արագությունից, ուստի քեշավորումը և streaming-ը կարևոր են։ Client-rendered SPA-ն ուղարկում է փոքր HTML shell և մեծ JavaScript bundle. իրական բովանդակության առաջին նկարումը սպասում է բեռնմանը, parse-ին, կատարմանը և API կանչերին, ինչը դանդաղ սարքերում վնասում է LCP-ին և SEO-ին, բայց հետագա նավիգացիան արագ է։ Ժամանակակից framework-ները դրանք խառնում են ըստ route-ի. static՝ մարքեթինգային էջերի համար, SSR կամ streaming՝ դինամիկ էջերի համար, և client component-ներ միայն այնտեղ, որտեղ ինտերակտիվություն է պետք։

Բառարան

RTT
Round-trip time. որքան ժամանակ է պետք փաթեթին հասնելու սերվեր և վերադառնալու։ Վեբի ուշացման մեծ մասը հաշվվում է RTT-ներով։
TTFB
Time to First Byte. հարցումն ուղարկելուց մինչև պատասխանի առաջին բայթի ժամանումը։
DOM
Document Object Model. տարրերի ծառը, որը բրաուզերը կառուցում է HTML-ից, և որը JavaScript-ը կարող է կարդալ ու փոխել։
CSSOM
Բրաուզերի կողմից parse արված բոլոր CSS կանոնների մոդելը, որը DOM-ի հետ միասին որոշում է, թե ինչպես է ամեն ինչ երևում։
LCP
Largest Contentful Paint. երբ է ավարտվում ամենամեծ տեսանելի տարրի՝ հաճախ hero նկարի կամ վերնագրի ռենդերը։ Լավը 2.5 s-ից պակասն է։
INP
Interaction to Next Paint. որքան արագ է էջը տեսողականորեն արձագանքում click-երին, tap-երին և ստեղնաշարին։ Լավը 200 ms-ից պակասն է։
CLS
Cumulative Layout Shift. որքան է տեսանելի բովանդակությունն անսպասելիորեն «ցատկում» բեռնման ընթացքում։ Լավը 0.1-ից պակասն է։
Origin
Ձեր սեփական սերվերը CDN-ի հետևում. բրաուզերի անվտանգության մեջ նաև URL-ի scheme + host + port-ը։
Edge
Այցելուին մոտ CDN սերվեր, որն ավարտում է կապերը և մատուցում քեշավորված բովանդակություն։
Preload scanner
Բրաուզերի երկրորդական parser, որն առաջ է կարդում HTML-ը՝ ռեսուրսները շուտ բեռնելու համար։

Պրոդուկտի գաղափար ունե՞ք։Եկեք ստեղծենք այն։

Պատմեք ձեր գաղափարի, պրոդուկտի կամ թիմի մասին։ Սովորաբար պատասխանում եմ մեկ աշխատանքային օրվա ընթացքում։