slopware 101 · step 3 of 35
What actually happens when you open a page?
by Damla Su Bilge · 5 min read
We have found the project folder. The page is open in the browser too, but those are two different views of the work. Changing a file does not, by itself, tell us what the browser received. Follow one small page from the folder to the screen and we can see which part does what.
What arrives when a page opens?
Make a folder, put one file in it called index.html, and write a single line.
<h1>hello</h1>
Open a terminal in that folder and run python3 -m http.server 8000 --bind 127.0.0.1, then open http://127.0.0.1:8000. This example needs Python 3 installed; on Windows the launcher is commonly py -3 instead of python3. Keep the server running while you try the page. The word hello appears in large bold letters.
Right click and choose View Page Source. What comes up is <h1>hello</h1>, exactly what you typed. The browser received that line of text and nothing else, so the large bold letters came from the browser itself. h1 means heading, and the browser decides what a heading looks like.
Change the h1 to a p and refresh. The same word comes back small, because p means paragraph. One letter changed in the file and the drawing changed, which tells you the drawing is made here, not sent.
A page is instructions that arrive and a program on your side that carries them out.
Source and the live page
Open the developer tools, Cmd+Option+I on a Mac or F12 on Windows and Linux, and look at the Elements panel (Inspector in Firefox). There is more than you wrote: html, head and body wrapped around your heading. Nobody sent those. The browser read your line, built a tree of elements from it, and filled in what a complete document needs.
That tree is the DOM1, and it is what the browser actually draws. View source shows the text that arrived. Elements shows the tree as it is right now. On this page the two are close. On a page with scripts they can be far apart, because scripts change the tree after it is built, and a page whose source is nearly empty can show a whole application. To learn what the server sent, read the source. To learn why something is on screen, read Elements.
How does the browser learn about a second file?
Put the h1 back and add style.css next to index.html.
h1 { color: crimson; }
Refresh and the word is still black. Your browser asked for one address and got one file. It has never seen your folder and has no way to know that a second file exists. The HTML has to say so.
<link rel="stylesheet" href="style.css">
<h1>hello</h1>
Now it is red. Click Network in the developer tools and refresh. Find the document request and the style.css request; the browser learned about the stylesheet by reading the document. A browser may also ask for a favicon or add other housekeeping requests, so the exact row count can differ.
That is discovery, and discovery is a chain. Fetching is not. Once the browser has read far enough to see several files named, it asks for them at the same time, and the waterfall column in the Network panel shows those bars overlapping. What it avoids is painting your heading in the wrong colour and then fixing it, so a stylesheet named at the top is usually waited for before the first paint, and some scripts hold things up the same way.
An ordinary site is that chain several layers deep: the document names a script, the script asks for a library, the library asks for a font. Each layer can start only after the one that names it has arrived and been read. A chain like this can delay a page even when each individual file is small. The waterfall helps you distinguish that delay from one unusually slow response.
The page asks for things on its own
So far every file was named in advance. Pages also ask the server for things while they run. Put tasks.json next to index.html:
["buy thread", "fix the hem"]
and add this to the bottom of index.html:
<ul id="list"></ul>
<script>
fetch('tasks.json')
.then(response => response.json())
.then(tasks => {
for (const task of tasks) {
const item = document.createElement('li');
item.textContent = task;
document.getElementById('list').appendChild(item);
}
});
</script>
Refresh. The list appears, and the Network panel has a new row for tasks.json. Click it: Headers shows what was asked and the status that came back, Response shows the text. Now view the source again. The list items are not there, only the empty ul and the script. Elements has both items, because the script made them after the page arrived.
From here on, almost everything in this book is a request, a response, and a row in that panel.
Where does the page go when the server stops?
Tick Disable cache in the Network panel, stop the server in your terminal with Ctrl+C, and refresh.
The tab shows the browser's own error page instead of yours. There is no complaint about your HTML, because your HTML never arrived. The browser asked again and nobody answered.
Start the server, refresh, and hello comes back in red, rebuilt from nothing.
Browsers can reuse cached responses, and sites can be built to work offline. In this experiment we disabled caching, so refreshing required a new response from the server. On the hello page you know which machine, because it is in your terminal. On your real project you have probably never asked, and the answer is the difference between a demo and a product.
Your own list
Open the Network panel on the project you are proudest of, refresh, and write down the number of requests and the amount transferred, both shown in the bar at the bottom. Then read down the list until you find a file you cannot account for. There is nearly always one, usually a font you stopped using or a library that arrived attached to something else.
Heavy is not the same as wrong. A large file you chose, knowing what it costs every visitor, is a decision. What matters is being the one who knows. Nothing needs removing today.
The next chapter is about the address you have been typing all along, and why that link does not open for anyone else.
DOM stands for Document Object Model, the tree of elements the browser builds from HTML and then keeps changing as scripts run.↩︎


