DEV Community

Cover image for From URL to Pixels: DNS, TCP, TLS and Rendering Explained
Md. Isfar Uddin
Md. Isfar Uddin

Posted on

From URL to Pixels: DNS, TCP, TLS and Rendering Explained

"What happens when you type a URL and press Enter?"

It is one of the most common interview questions in web development, and for nine years I could not answer it properly. I knew the word DNS. That was about it.

Here is the full answer, start to finish.


The whole thing in five moves

You type example.com and press Enter. Before anything appears:

  1. Browser finds the IP address behind that name. (DNS)
  2. Browser opens a connection to it. (TCP)
  3. If it is HTTPS, both sides agree on encryption. (TLS)
  4. Browser asks for the page. (HTTP)
  5. HTML comes back, browser draws it.

That is the whole journey. Now let us go through each step one by one.


1. Finding the IP address

Your computer has no idea what example.com means. It only speaks in numbers like 104.20.23.154. DNS is the translator that sits between the two.

But the browser is lazy, in the way good engineering is lazy. Asking a DNS server over the network takes time, so it checks everything closer to home first, and only moves outward when it comes up empty.

Flowchart of a DNS lookup. The browser checks four caches in order, each one only if the previous missed: browser cache, OS cache, router cache, then the ISP resolver. If all four miss, the real hunt begins: root servers, then .com servers, then example.com's nameservers, which finally return the IP address.

Notice the pattern there. Picture it as asking a question in a house.

First you ask yourself, because you might already know. That is the browser cache. If you visited the site a minute ago, the answer is right there, and the trip is over before it starts.

No luck? You ask the rest of the house. That is the OS cache, shared by every app on your machine. Maybe your email client looked up the same domain earlier.

Still nothing? You ask the router, which has been listening to everyone on the wifi. Your laptop, your phone, the smart TV nobody uses. One of them may have asked recently.

Still nothing? You ask your internet provider. Their resolver serves thousands of people in your area, so for any site with real traffic, somebody else almost certainly looked it up minutes ago, and the answer is sitting there waiting.

That last one is why the web feels fast even on a site you have never visited. A stranger warmed the cache for you.

If every single cache misses, the resolver has to go and find out properly. It does that by asking three questions in a row:

Root servers — "who handles .com?"
.com servers — "who handles example.com?"
example.com's nameservers — "here is the IP."

Nobody in that chain knows the final answer except the last one. The root servers are not being unhelpful; they genuinely do not store it. They just know who to ask next, like a very well-organised receptionist.

Each answer gets cached on the way back, so the next person asking gets it instantly.

One thing worth clearing up: DNS has no idea whether you want HTTP or HTTPS. It only maps names to numbers. The thing deciding the protocol is the HSTS preload list, a list baked into the browser of sites that should always use HTTPS. The browser checks that before DNS even starts.


2. Opening the connection

We have an IP. Now we need an actual connection, which TCP sets up with a three-message greeting:

Diagram of the TCP three-way handshake between client and server. The client sends SYN with its starting number. The server replies SYN and ACK with its own number and confirmation of the client's. The client sends ACK confirming the server's number. The connection is then established.

Your browser says hello and mentions a number. The server says hello back, mentions its own number, and confirms it heard yours. Your browser confirms it heard the server's. Done, three messages, and they are connected.

Why the numbers? Because your page does not travel as one piece. It gets chopped into many small packets, and those packets can arrive out of order or go missing on the way. So every packet carries a number. The receiving side uses those numbers to put everything back in the right order, and to notice when there is a gap so it can ask for that missing piece again.

The handshake is just the two sides agreeing on where to start counting. That is all it is.

Yes, that is three messages before a single byte of your actual page moves. Without it, your HTML would arrive shuffled, with pieces quietly missing, and nobody would know.


3. TLS, only if https

If the URL starts with https, there is one more negotiation first.

The browser says hello and lists the encryption it can handle. The server picks one and sends its certificate. The browser checks that certificate against the authorities it already trusts, shipped with the browser itself. If it passes, both sides derive a shared key, and everything after that is encrypted.

TLS 1.2 needed two round trips for this. TLS 1.3, which most of the web runs now, does it in one.

On plain HTTP, this step simply does not happen. Faster, and also a terrible idea.


4. Asking for the page

After all that setup, the actual request is almost boring:

GET /index.html HTTP/1.1
Host: example.com
Accept: text/html
Enter fullscreen mode Exit fullscreen mode

That Host line does more work than it looks like. One IP address often serves dozens of sites, so without the name the server has no way to know which one you meant.

Back comes a status line and the content. 200 is fine, 301 means it moved, 404 means not found, 500 means something on their side caught fire.


5. Drawing the page

The HTML arrives, and now the browser does the part frontend people live in.

Diagram of the browser rendering pipeline. HTML becomes the DOM and CSS becomes the CSSOM. The two merge into the render tree, which goes to layout, where positions are worked out, and then to paint, which draws pixels on screen.

The short version: HTML becomes a tree called the DOM, CSS becomes a parallel tree called the CSSOM, and the two merge into a render tree holding only what is actually visible. The browser works out where everything sits, then paints pixels.

Two details worth carrying around. CSS blocks painting, because showing unstyled content and then restyling it would look dreadful. And a plain <script> tag stops HTML parsing dead while it downloads and runs, since it might change the document. That is the entire reason defer and async exist.

This part deserves a post of its own, so I will leave it there.


If I missed something or got a detail wrong, tell me in the comments.

Top comments (0)