WEBVTT

1
00:00:01.200 --> 00:00:03.220
You type one URL.

2
00:00:03.220 --> 00:00:04.764
You get one page.

3
00:00:04.764 --> 00:00:06.841
At least, that's how it feels.

4
00:00:07.041 --> 00:00:09.930
Open the Network panel and reload.

5
00:00:09.955 --> 00:00:12.231
The browser didn't make one request.

6
00:00:12.231 --> 00:00:13.657
It made dozens.

7
00:00:13.798 --> 00:00:19.230
In 2024, the median home page made around seventy.

8
00:00:19.429 --> 00:00:26.649
You asked for one document, but it arrived in many parts, some of them unexpected.

9
00:00:27.349 --> 00:00:36.542
Remember the three inventions: a URL names a thing, HTTP fetches it, and HTML describes a document.

10
00:00:36.846 --> 00:00:41.674
The trick is what HTML does with other URLs.

11
00:00:41.874 --> 00:00:49.651
As the browser reads the HTML from top to bottom, every URL it meets becomes another HTTP request.

12
00:00:49.664 --> 00:00:51.067
A stylesheet.

13
00:00:51.081 --> 00:00:52.044
A script.

14
00:00:52.044 --> 00:00:52.903
An image.

15
00:00:52.903 --> 00:00:53.935
A video.

16
00:00:53.948 --> 00:00:55.038
An icon.

17
00:00:55.040 --> 00:00:58.660
An iframe, which is a whole other page.

18
00:00:58.860 --> 00:01:01.505
Each of those tags is a placeholder.

19
00:01:01.646 --> 00:01:04.141
An img tag holds no picture.

20
00:01:04.166 --> 00:01:10.027
It holds an address for one, and the browser fills the spot by fetching it.

21
00:01:10.227 --> 00:01:21.115
Fun fact: a data: URL carries the asset inside the address itself, trading one less request for a bigger document.

22
00:01:21.315 --> 00:01:30.439
So the HTML document is the root of a tree, and most of what it contains is a list of things to go get.

23
00:01:31.139 --> 00:01:33.018
And the tree keeps growing.

24
00:01:33.287 --> 00:01:36.884
Stylesheets request fonts and background images.

25
00:01:37.072 --> 00:01:44.535
Scripts fetch JSON, load more scripts, and sometimes load other organizations' scripts onto your page.

26
00:01:44.595 --> 00:01:50.061
That iframe brings its own HTML, with its own tree.

27
00:01:50.261 --> 00:01:51.606
Depth matters.

28
00:01:51.910 --> 00:01:58.398
A font can't be requested until the stylesheet that names it has arrived and been read.

29
00:01:58.701 --> 00:02:04.772
Three links in a chain means three waits, one after another.

30
00:02:04.972 --> 00:02:08.163
Developers call these critical request chains.

31
00:02:08.246 --> 00:02:10.705
Your users just call it waiting.

32
00:02:10.905 --> 00:02:16.418
Even if you never mention it, most browsers will ask your server for a favicon.

33
00:02:16.559 --> 00:02:19.982
The tree has a branch you didn't draw.

34
00:02:20.682 --> 00:02:24.082
Here's the part that makes the web so flexible.

35
00:02:24.478 --> 00:02:37.097
To the browser, every node in that tree is the same kind of thing: a URL, fetched over HTTP, with a label on the response that says what it is.

36
00:02:37.297 --> 00:02:41.417
That label is the Content-Type header, written as a MIME type.

37
00:02:41.465 --> 00:02:44.505
text/html.

38
00:02:44.681 --> 00:02:47.303
text/css.

39
00:02:47.351 --> 00:02:49.253
text/javascript.

40
00:02:49.348 --> 00:02:51.854
image/avif.

41
00:02:51.949 --> 00:02:54.118
application/json.

42
00:02:54.364 --> 00:02:56.730
font/woff2.

43
00:02:56.930 --> 00:03:02.129
When loading over a network, the browser goes by the label, not the file name.

44
00:03:02.340 --> 00:03:11.441
The same URL could return a page, a picture, or data, and the MIME type tells the browser what to do with it.

45
00:03:11.641 --> 00:03:17.154
Fun fact: MIME stands for Multipurpose Internet Mail Extensions.

46
00:03:17.237 --> 00:03:23.458
The web borrowed the idea from email, and it's now integral to how the web works.

47
00:03:24.158 --> 00:03:27.384
So the details of a Content-Type matter.

48
00:03:27.780 --> 00:03:35.743
When a response arrives, the browser reads its type and asks: given this, what do I do?

49
00:03:35.943 --> 00:03:40.515
For text/html, parse it as HTML.

50
00:03:40.599 --> 00:03:44.231
For text/css, apply the styles.

51
00:03:44.314 --> 00:03:48.143
For text/javascript, run it in the JavaScript engine.

52
00:03:48.168 --> 00:03:51.440
For image/jpeg, draw the picture.

53
00:03:51.466 --> 00:03:53.054
And so on.

54
00:03:53.254 --> 00:03:57.757
A type can even launch another application, called a helper.

55
00:03:58.061 --> 00:04:03.585
A zip file might be handed to an unzip program on your system.

56
00:04:03.785 --> 00:04:06.500
URL schemes work the same way.

57
00:04:06.699 --> 00:04:15.509
A mailto: link opens your mail program, tel: makes your phone dial, and a custom scheme can open an app like Spotify.

58
00:04:15.697 --> 00:04:21.593
These aren't ancient ideas; they're how the web reaches beyond the browser.

59
00:04:21.793 --> 00:04:26.505
Danger: when a server leaves the type out, browsers guess.

60
00:04:26.530 --> 00:04:29.198
That's called MIME sniffing.

61
00:04:29.409 --> 00:04:38.393
It's convenient, but it has enabled content-sniffing attacks, so label your responses and tell the browser not to sniff.

62
00:04:39.093 --> 00:04:41.645
Now flip the tree on its side.

63
00:04:41.787 --> 00:04:49.656
Every node becomes a bar on the loading timeline, and the shape of the tree becomes the shape of the load.

64
00:04:49.856 --> 00:04:52.803
Most requests go to your own server.

65
00:04:53.014 --> 00:05:05.249
Requests to other servers, the third parties, need their own setup before the first byte: look up the name, open a connection, negotiate encryption.

66
00:05:05.449 --> 00:05:10.405
First party or third party, the mechanism is the same.

67
00:05:10.615 --> 00:05:12.901
The difference is control.

68
00:05:13.297 --> 00:05:26.693
92% of pages load something from a third party, and they do it at some risk, because you don't control its speed, its uptime, or what it does with your users.

69
00:05:27.394 --> 00:05:29.935
Two tools shrink the timeline.

70
00:05:29.937 --> 00:05:38.422
Compression squeezes text, the HTML, CSS, JavaScript, and JSON, often to a fraction of its size.

71
00:05:38.598 --> 00:05:44.552
The browser says which encodings it accepts, and the server labels what it sent.

72
00:05:44.752 --> 00:05:56.430
Images and video are already compressed, so for them, the savings come from your choices: format, dimensions, and quality.

73
00:05:56.629 --> 00:05:59.739
Caching skips the trip entirely.

74
00:05:59.903 --> 00:06:05.091
A Cache-Control header says how long a response stays fresh.

75
00:06:05.197 --> 00:06:13.833
Put a fingerprint in the file name, and you can cache it for a year, because a new version gets a new URL.

76
00:06:14.033 --> 00:06:19.209
The fastest request is the one you never make, so cache it if you can.

77
00:06:19.410 --> 00:06:26.072
Caching myth: loading a popular library from a shared CDN doesn't help reuse.

78
00:06:26.213 --> 00:06:34.942
Browsers keep a separate cache for each site, so a copy fetched for someone else's site isn't reused on yours.

79
00:06:35.642 --> 00:06:39.251
Last, the tree decides who waits for whom.

80
00:06:39.555 --> 00:06:48.202
A plain script tag in the head stops the HTML parser until the script downloads and runs.

81
00:06:48.402 --> 00:06:55.401
Stylesheets block rendering, on purpose, so you don't see a flash of unstyled content.

82
00:06:55.484 --> 00:06:57.375
Images block neither.

83
00:06:57.516 --> 00:06:59.940
They fill in as they arrive.

84
00:07:00.140 --> 00:07:03.145
And you control most of this with a word or two.

85
00:07:03.321 --> 00:07:09.972
Defer lets a script download in parallel and run after the HTML is parsed.

86
00:07:10.310 --> 00:07:13.432
Async runs it as soon as it arrives.

87
00:07:13.538 --> 00:07:17.065
Module scripts are deferred by default.

88
00:07:17.266 --> 00:07:21.931
loading="lazy" holds back images that are off-screen.

89
00:07:22.014 --> 00:07:31.916
Preload and preconnect start important work early, and fetch priority tells the browser what matters most.

90
00:07:32.116 --> 00:07:34.877
Same page, two trees.

91
00:07:34.902 --> 00:07:41.785
With the right hints you help the browser; in the critical path, you slow everything down.

92
00:07:41.996 --> 00:07:48.391
How you build the page shapes delivery, even when the byte count is the same.

93
00:07:49.091 --> 00:07:51.469
So a page isn't a file.

94
00:07:51.610 --> 00:07:57.216
It's a tree of addresses, each fetched over HTTP and labeled with a type.

95
00:07:57.427 --> 00:08:05.877
That one simple idea lets the web carry any kind of content, and hand off whatever it can't handle.

96
00:08:06.077 --> 00:08:09.814
When you build a page, you aren't just writing markup.

97
00:08:10.117 --> 00:08:17.337
You're designing a tree, and its shape decides how it loads for everyone on the other end.

98
00:08:17.537 --> 00:08:19.114
Try it yourself.

99
00:08:19.325 --> 00:08:24.350
In Chrome's Network panel, hold Shift and hover over a request.

100
00:08:24.491 --> 00:08:29.726
You'll see who asked for it, and what it asked for in turn.

101
00:08:29.926 --> 00:08:38.353
Next, the Availability lesson: is the page there at all, and did it arrive while the user still cared?
