WEBVTT

1
00:00:01.200 --> 00:00:04.031
A web page arrives with its words.

2
00:00:04.056 --> 00:00:08.512
The HTML has every letter of every paragraph.

3
00:00:08.723 --> 00:00:16.314
Yet on this slow connection, the page shows only empty space where the text should be.

4
00:00:16.514 --> 00:00:18.242
The words are there.

5
00:00:18.325 --> 00:00:23.896
What's missing is the font: the file that describes what each letter looks like.

6
00:00:24.037 --> 00:00:28.679
Until it arrives, the browser has to decide what to do.

7
00:00:28.983 --> 00:00:36.180
As a developer, you can make that decision for it, and leaving it to chance can be catastrophic.

8
00:00:36.380 --> 00:00:46.026
In the worst case, the font sits in what we call the critical rendering path: nothing on the page is drawn until it arrives.

9
00:00:46.423 --> 00:00:50.682
UC San Diego's own home page shows the problem.

10
00:00:50.823 --> 00:01:04.265
Its fonts are packed into a style sheet of more than two megabytes, which has to arrive before anything can be drawn, and which is downloaded again, in full, on every visit.

11
00:01:04.965 --> 00:01:08.051
Fonts are found late, by design.

12
00:01:08.355 --> 00:01:12.742
The browser reads the HTML, which names a style sheet.

13
00:01:12.883 --> 00:01:16.411
It fetches the style sheet, which declares a font.

14
00:01:16.436 --> 00:01:18.558
But it doesn't fetch the font yet.

15
00:01:18.769 --> 00:01:24.317
It waits until it lays out the page and finds text that actually uses it.

16
00:01:24.458 --> 00:01:27.881
Only then does the request begin.

17
00:01:28.081 --> 00:01:29.391
That's sensible.

18
00:01:29.532 --> 00:01:36.879
A site might declare eight faces and use three on a given page, so why download the other five?

19
00:01:37.021 --> 00:01:40.084
But it puts the font at the back of the line.

20
00:01:40.284 --> 00:01:44.125
A preload link in the head moves it to the front.

21
00:01:44.522 --> 00:01:54.516
While the browser is still reading the HTML, it learns that this font will be needed, and fetches it alongside the CSS.

22
00:01:54.716 --> 00:02:06.440
Preload only the most important font or fonts because if you preload everything, then you might create an experience worse than doing nothing.

23
00:02:07.140 --> 00:02:10.714
So what does the browser draw while it waits?

24
00:02:10.995 --> 00:02:14.998
The CSS specification describes three stages.

25
00:02:15.197 --> 00:02:20.292
First, during the block period, the text is drawn, but invisibly.

26
00:02:20.480 --> 00:02:28.361
Second, in the swap period, it's drawn in the fallback font, and swapped when the real one arrives.

27
00:02:28.665 --> 00:02:36.140
Last comes the failure period: if the font still hasn't arrived, the fallback stays for good.

28
00:02:36.340 --> 00:02:43.664
The font-display setting, inside the at font face rule, sets how long each period lasts.

29
00:02:43.794 --> 00:02:47.751
Block: hide the text for about three seconds.

30
00:02:47.880 --> 00:02:56.841
Swap: hide it for a tenth of a second at most, then show a fallback, and change it whenever the font is loaded.

31
00:02:57.042 --> 00:03:03.855
Fallback: the same tiny wait, but stop swapping after about three seconds.

32
00:03:03.938 --> 00:03:09.730
And optional: use the font only if it's ready for the first paint.

33
00:03:10.034 --> 00:03:13.039
Otherwise, keep the fallback.

34
00:03:13.238 --> 00:03:16.615
Now watch a font that arrives at two seconds.

35
00:03:16.628 --> 00:03:19.831
Block shows nothing at all, then the font.

36
00:03:19.960 --> 00:03:23.592
Swap shows a fallback at once, then changes.

37
00:03:23.791 --> 00:03:28.851
Fallback does the same, because two seconds is inside its window.

38
00:03:28.981 --> 00:03:31.115
Optional never changes.

39
00:03:31.256 --> 00:03:38.894
This visit stays in the fallback, and the next one, with the font already cached, gets it from the start.

40
00:03:39.094 --> 00:03:41.077
Both failures have names.

41
00:03:41.161 --> 00:03:44.293
Hidden text is the flash of invisible text.

42
00:03:44.377 --> 00:03:47.509
The change is the flash of unstyled text.

43
00:03:47.593 --> 00:03:49.913
One costs reading time.

44
00:03:49.996 --> 00:03:53.187
The other costs a display jolt.

45
00:03:53.387 --> 00:03:59.655
The specification's advice for long text is fallback or optional, not swap.

46
00:03:59.958 --> 00:04:10.127
A reader halfway through a paragraph is better served by a font that never arrives than by one that arrives and disrupts their experience.

47
00:04:10.827 --> 00:04:13.077
Here's what we mean by the text jolt.

48
00:04:13.091 --> 00:04:16.572
A paragraph in Arial while Inter loads.

49
00:04:16.644 --> 00:04:22.981
Inter is a little wider, so when it arrives the lines break in different places.

50
00:04:23.110 --> 00:04:29.622
The paragraph grows by a line, and everything below it moves thirty pixels down.

51
00:04:30.018 --> 00:04:33.465
If you were reading, you've lost your place.

52
00:04:33.664 --> 00:04:46.781
That movement counts as layout shift: the Web Vital called Cumulative Layout Shift, or C L S, the same one images cause when they arrive without a width and height.

53
00:04:46.982 --> 00:04:50.893
The fix is to make the fallback the same size as the font.

54
00:04:51.196 --> 00:04:59.507
CSS can take Arial, scale it up by about six percent, and give it Inter's height above and below the baseline.

55
00:04:59.811 --> 00:05:06.276
Now, when Inter arrives, the letters change shape, but every line keeps its length.

56
00:05:06.580 --> 00:05:08.970
Zero pixels.

57
00:05:09.169 --> 00:05:15.065
You don't have to do that calculation by hand: tools read it from the font files.

58
00:05:15.206 --> 00:05:23.633
And a numeric line height, such as one point five, keeps every line the same height in any font.

59
00:05:24.333 --> 00:05:31.553
Everything so far happens on the first visit, and if we cache properly, it won't happen again.

60
00:05:31.753 --> 00:05:38.949
This course's own fonts, IBM Plex, cost about four hundred kilobytes on a first visit.

61
00:05:39.346 --> 00:05:45.625
But they live in a folder named for their release, so a file at that address never changes.

62
00:05:45.766 --> 00:05:51.604
That lets the server say: keep these for a year, and don't even ask.

63
00:05:51.804 --> 00:05:57.886
So on the next page, and the next visit, there is no request for a font at all.

64
00:05:58.189 --> 00:05:59.918
The wait happened once.

65
00:05:59.943 --> 00:06:07.975
This is just the course's Performance Law: send less data, less often, from nearby, and only when needed.

66
00:06:08.186 --> 00:06:12.039
We fetched the font early in the first visit, and kept it.

67
00:06:12.342 --> 00:06:21.779
And serving it from a content delivery network, as this site does, brings even that first download closer to the reader.

68
00:06:22.479 --> 00:06:26.761
So when a web font loads, four decisions are yours.

69
00:06:26.902 --> 00:06:32.137
Put it at the front of the line with a preload, if the first screen needs it.

70
00:06:32.533 --> 00:06:38.986
Choose what readers see while they wait, with fallback or optional for long text.

71
00:06:39.197 --> 00:06:42.179
Size the fallback so nothing jumps.

72
00:06:42.262 --> 00:06:47.996
And finally cache the font, so the wait happens only once.

73
00:06:48.196 --> 00:06:56.669
Open the loading lab, set the delay to five seconds, and watch all five choices play out side by side.
