All articles
37 articles · updated weekly See our Tools
All articles
Tutorials

How a Web Page Works: From Browser to Server and Back

From DNS to rendering: what actually happens between typing a URL and seeing a page — TCP, TLS, HTTP request/response, and how the browser paints pixels.

COVER · Tutorials

You type https://example.com in the browser, hit Enter, and half a second later a page appears. Looks like magic. It's not. There are about six or seven well-defined steps happening so fast that most people never think to ask what goes on between Enter and page load. If you're new to web development and want to actually understand what happens in that interval, this post is for you.

What happens when you type a URL

A URL (Uniform Resource Locator) is an address. https://example.com/contact has three main parts: the protocol (https), the domain (example.com), and the path (/contact).

Before any request leaves your computer, the browser needs to turn example.com into an IP address — because the internet doesn't work with pretty names, it works with numbers. For that, it needs DNS.

What DNS is and why it exists

DNS (Domain Name System) is the internet's contact book. You look up example.com, it gives you back 93.184.216.34.

When you type a URL, the browser first checks its local cache — if you visited the site recently, the IP might already be stored. If not, it asks the DNS server configured on your system (usually your ISP's, or a public one like Google's 8.8.8.8).

That DNS server runs a series of hierarchical queries:

  1. Who's responsible for .com? (root servers)
  2. Who's responsible for example.com? (TLD servers)
  3. What's the IP for example.com? (authoritative name server)

At the end of this chain, you have the IP. The whole process typically takes under 100ms — but it's a network roundtrip that happens before the main request even leaves your machine.

TCP connection and TLS handshake

With the IP in hand, the browser needs to open a connection to the server. It uses TCP (Transmission Control Protocol), which ensures packets arrive in the right order without loss.

This involves the well-known three-way handshake:

Client → Server: SYN
Server → Client: SYN-ACK
Client → Server: ACK

Three messages before anything useful is sent. With HTTPS (which is HTTP over TLS), there's an extra step: the TLS handshake, where client and server negotiate encryption algorithms and exchange keys. This ensures data travels encrypted — nobody in between can read what you're sending or receiving.

That's why HTTPS matters even on "simple" sites. It's not just about login forms — it's about not exposing your browsing data to every router along the way.

The HTTP request

With the connection established, the browser finally sends the HTTP request. A basic GET request looks like this:

GET /contact HTTP/1.1
Host: example.com
Accept: text/html,application/xhtml+xml
Accept-Language: en-US,en;q=0.9
User-Agent: Mozilla/5.0 ...

A few important fields:

  • Method: GET fetches content, POST sends data, PUT/PATCH updates, DELETE removes
  • Host: required because one server can host multiple domains
  • Headers: request metadata — what the browser accepts, preferred language, cookies, auth tokens

The server response

The server receives the request, processes it (might query a database, run code, fetch files), and sends back an HTTP response:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 12458
Cache-Control: max-age=3600

<!DOCTYPE html>
<html lang="en">
...

The first three digits are the status code — probably the most useful HTTP concept for beginners:

Range Meaning Examples
2xx Success 200 OK, 201 Created
3xx Redirect 301 Moved Permanently, 304 Not Modified
4xx Client error 404 Not Found, 401 Unauthorized, 403 Forbidden
5xx Server error 500 Internal Server Error, 503 Service Unavailable

A 404 means the resource doesn't exist on the server — not a connection problem. A 500 means the server crashed on its own. A 301 means the URL permanently moved to a new address. Each code tells a different story, and understanding them saves a lot of debugging time.

The browser renders HTML

The server sent the HTML. Now the browser needs to turn that into pixels on screen. This process is called the rendering pipeline, and it works roughly like this:

1. HTML parsing → DOM

The browser reads the HTML top to bottom and builds the DOM (Document Object Model) — a tree of objects representing each element on the page. A <div> becomes a node, a <p> becomes another, and so on.

During this process, if the browser finds a CSS <link> tag or <script>, it fires new requests to fetch those files.

2. CSS parsing → CSSOM

Downloaded CSS is also parsed into a parallel tree: the CSSOM (CSS Object Model). This holds the style rules associated with each selector.

3. Render tree

DOM + CSSOM are combined into a render tree — only visible elements, with their computed styles. An element with display: none doesn't even make it into this tree.

4. Layout

The browser calculates the position and size of each element on screen. This step is expensive — changing the size of one element can affect the layout of neighboring ones.

5. Paint and composite

Finally, elements are drawn in layers and composited into the final screen image. That's what you see.

The role of JavaScript

HTML and CSS are declarative — you describe what you want, the browser renders it. JavaScript is different: it's code that executes in the browser.

Scripts block HTML parsing by default. If the browser hits a <script> in the <head> without async or defer, it stops processing HTML, downloads the script, executes it, then continues. That's why heavy scripts in the <head> slow down page load.

<!-- Blocks rendering: -->
<script src="app.js"></script>

<!-- Non-blocking, executes when available: -->
<script src="app.js" async></script>

<!-- Non-blocking, executes after HTML is parsed: -->
<script src="app.js" defer></script>

For most scripts, defer is the safer choice.

Cache: what the browser stores

Requests are expensive. HTTP has mechanisms to prevent the browser from downloading the same resource twice:

  • Cache-Control: the server tells the browser how long to keep the resource (max-age=3600 = 1 hour)
  • ETag: a "fingerprint" of the resource. On the next request, the browser sends the ETag; if nothing changed, the server replies with 304 Not Modified and no body — saving bandwidth
  • Last-Modified: similar to ETag, but based on modification date

In practice, image and CSS files with a hash in the name (like app.abc123.css) can have long max-age because the hash changes when the file changes — forcing the browser to download the new version.

Frequently asked questions

Why do some sites take longer to load?

Several factors: server physically far away (network latency), many resources to download (JS, CSS, images), JavaScript blocking rendering, missing cache headers, or no CDN configured. Physical distance between client and server is still one of the biggest factors — requests travel at a finite speed.

What is HTTPS and why does it matter?

HTTPS is HTTP with TLS. All communication is encrypted: URL, headers, body. Without HTTPS, any node along the way (router, ISP) can read and modify what's transmitted. Modern browsers flag HTTP sites as "not secure," and some features (geolocation, service workers) only work over HTTPS.

What's the difference between HTTP/1.1, HTTP/2, and HTTP/3?

HTTP/1.1 opens one connection per request (or keeps parallel connections, capped per domain). HTTP/2 multiplexes multiple requests over a single TCP connection — significantly more efficient. HTTP/3 replaces TCP with QUIC (UDP-based), reducing latency especially on unstable connections. For the beginning web developer, the practical difference is: modern sites use HTTP/2 or HTTP/3 transparently, with nothing to configure.

What is a CDN?

CDN (Content Delivery Network) is a network of geographically distributed servers. Instead of everyone downloading static files from a server in one location, users in Europe download from a server in Frankfurt. Lower latency, faster loading. It's how large sites perform well worldwide — they replicate content close to the people consuming it.

The full stack in under a second

In practice, all of this — DNS resolution, TCP/TLS handshake, HTTP request, response, HTML/CSS parsing, resource downloads, JS execution, rendering — happens in fractions of a second. A well-optimized site loads in under 1 second. A poorly optimized one can take 10 seconds running through the exact same steps, just inefficiently.

When a page fails to load, getting stuck at one of these stages is the diagnosis. DNS not resolving? DNS problem. Connection refused? Server down. Status 500? Server-side failure. Blank page with JS enabled? Script error. Understanding the sequence means knowing where to look.

To quickly look up what any HTTP status code means when it shows up in a log or browser DevTools, I use the HTTP Status Codes tool — especially handy when a 4xx or 5xx appears and you need to know whether it's your fault or the server's.

RD
Author
Rafael Duarte
Desenvolvedor backend com passagem por fintech e SaaS B2B — trabalhou em times que escalaram APIs de zero a milhões de requisições. Carrega cicatrizes de produção suficientes para ter opiniões fortes sobre ferramentas, padrões e decisões de arquitetura. Não é acadêmico: leu a RFC do UUID quando precisou escolher entre v4 e v7 para uma tabela de alta escrita.
View profile