
Optimize web fonts loading and rendering with preloading and font-display to improve loading speed
Optimize web fonts loading and rendering with preloading and font-display to improve loading speed
#FOIT #FOUT #webdevelopment #performance #fontLoadingOptimization
- This video first talks about the problems of FOIT (Flash of invisible text) and the solution to overcome this by using the preloading strategy, \u0026lt link rel=“preload” href="" as=“font” crossorigin /\u0026gt
- Also, it talks about the problems of FOUT (Flash of unstyled text) and the solution to overcome this by using font-display property of @font-face along with values such as auto | block | swap | fallback | optional in css.
- Concept of critical rendering paths, waterfall steps are also briefly discussed with the help of diagrams and the network tab of the browser.
I also have a blog post about it which can be found here :)
https://medium.com/@sanjeevsubedi/opt…
Content
0.57 -> Hi everyone, welcome back.
2.65 -> In this video, we'll talk about how to optimize
web fonts loading and rendering to improve
9.51 -> the loading speed of your web application
by using preloading strategy and font-display
16.03 -> property.
17.03 -> So, let's get started.
18.85 -> Now, I have a simple webpage here which has
one image, which is right here and a few paragraphs
27.369 -> below the image,
and as well as I have one stylesheet which
32.46 -> is right here.
33.84 -> And inside this CSS file, I have this custom
font called Tangerine and it basically downloads
41.52 -> the font from one of my local server.
44.26 -> So, my main idea here is that any web application
can request other cross origin server to download
52.739 -> the font.
53.79 -> For example, you might request the Google
Server to download the Google fonts.
58.3 -> Let me show my local server quickly as well.
61.969 -> But we didn't need to worry much about the
local server setup.
66.049 -> So, as you can see that I have set up a static
server on express here.
72.12 -> And if you look on the public folder, I have
few static resources here.
77.08 -> In our case, the font called Tangerine Regular
is being downloaded
82.4 -> by the user Agent.
84.86 -> Now, before implementing the solution to optimize
the web fonts loading and rendering, let's
91.65 -> try to understand the problem.
93.86 -> That way, when we implement the solution,
we are very clear about it.
99.07 -> Let me try to open this webpage on a new tab.
104.36 -> We just saw the flash of invisible text.
107.45 -> We call it as FOIT and it's pretty popular
term across the web.
113.25 -> Let me do this one more time.
115.299 -> I opened a new tab.
119.12 -> We just saw that white screen for one or 2
seconds.
123 -> And the reason for that is let me share this
document quickly right here
128.83 -> and then we will be clear about it.
131.46 -> So here we have different browsers and their
default behaviours while downloading the custom
136.95 -> font.
137.95 -> So, in case of Chrome, which I'm using at
the moment, it has a timeout of 3 seconds,
143.76 -> meaning for the first 3 seconds, it will wait
for the fonts to get downloaded and rendered
150.4 -> on the webpage, and during that time it simply
displays the white screen.
155.88 -> If the font is downloaded
within 3 seconds, white screen is replaced
160.35 -> with the custom font.
162.069 -> If the font takes longer to download, let's
say 4 or 5 seconds, then in that scenario,
169.01 -> Chrome will try to display the system font.
172.2 -> And when the actual custom font is downloaded,
the system font will be swapped with the custom
177.39 -> font.
178.39 -> I'll talk more about it later, but these are
the behaviour of different browsers while
184.709 -> downloading the custom fonts.
188.319 -> And I want to show you one more thing quickly
here as well.
191.84 -> If we look on the network tab right here,
let me refresh the page, we see that the first
198.59 -> request is of course the HTML document, and
then we request for main CSS, which is right
204.87 -> here, and then we have picture, and then don't
worry about install hook and content because
212.319 -> these are these JavaScripts that are being
added by few extensions on my browser.
219.26 -> But the last resource of this page is this
font, right, which is being downloaded here.
225.87 -> And the reason for this is the request to
download this font is only triggered while
231.67 -> your browser is parsing this CSS file, right?
235.65 -> I want to illustrate this waterfall steps
with the help of image as well.
242.68 -> So this is the diagram which represents the
exact waterfall steps, right?
249.17 -> Or we call it as Critical Rendering Path.
251.7 -> I'll be covering this topic later in the future,
but let's try to jump into this quickly.
259.229 -> So, as I mentioned earlier, your user agent
will request for the page, you get the HTML
265.82 -> and then based on that HTML, browser will
construct the DOM, which is Document Object
270.46 -> Model.
271.539 -> And then while parsing your HTML page, if
it finds the link tag, then it will try to
277.9 -> create the CSS Object Model.
281.09 -> And when it parses the CSS, if it finds any
request being made to fonts, it generates
288.81 -> a new request, which is exactly the same scenario
in our case.
294.259 -> And then your browser will wait, right?
297.289 -> So in case of Chrome, it will wait for 3 seconds
with that white screen until the font is successfully
305.84 -> downloaded on your browser.
308.33 -> So at that time, the painting of text is delayed
here, right, which is depicted
315.11 -> right here.
317.18 -> So now, sorry, to fix this problem, what we
can do actually is we can initiate the download
324.5 -> of this font early in the process, rather
than we wait here and then make a request
330.979 -> to download the font, we can say to our browser,
hey, start downloading this font because I
336.55 -> need this font later in the process.
339.63 -> That way when browser builds this CSS Object
Model, then at this stage, font is already
346.99 -> being downloaded and then is ready to be painted
on the screen.
351.86 -> So that's the whole idea here.
354.43 -> And we can achieve this thing with the help
of preload.
358.31 -> I just added one line of code here.
361.819 -> If you look closely here, we are using link
tag and then for this rel attribute, we are
367.28 -> using preload.
368.819 -> So it's pretty similar to how
we attach external CSS file.
373.099 -> And on the ref we just give the name of the
resource that we want to preload.
377.1 -> In our case, we want to preload the web font
early in the process.
381.88 -> And as is basically, so this payload helps
to preload any resource.
387.41 -> For example, we can instruct the browser to
preload JavaScript file or any other CSS file.
394.02 -> In our case, we are preloading font.
396.37 -> So this as attribute would be font.
398.56 -> And finally, we must have this crossorigin
attribute as well.
403.38 -> Even though you are hosting your font in your
same origin, you are still required to add
410.4 -> this attribute as per the documentation of
Google.
415.36 -> That's pretty much it for the Preload instruction
here.
418.62 -> Let me save this page.
420.96 -> Now let me try to open this page on a new
tab.
425.88 -> Now, we didn't see that flash of invisible
text.
430.72 -> Let me do this one more time quickly.
433.62 -> So, I think with this solution we have
improved the load speed of our application.
441.259 -> So it's very crucial to have this small change
and then achieve very good performance on
447.63 -> your web application.
449.229 -> Let me also show some differences on the waterfall
steps which we discussed earlier.
455.94 -> So if I open the network tab right here, let
me refresh the page.
462.879 -> So if we compare the earlier steps, we can
save this font on the second step right here.
470.33 -> If you remember, the font was the last resource
to be downloaded without preloading.
476.34 -> But with the help of preloading strategy,
browser has started to download the font very
481.789 -> early in the process.
482.99 -> So, that's the whole idea about preloading
strategy.
488.3 -> Up until now we talked about a scenario where
the font will be downloaded within a period
493.949 -> of 3 seconds.
494.949 -> So now let's try to delay the time taken by
the user agent to download the font.
502.08 -> So I can do some simulation around it on our
local server.
507.52 -> And that's the whole
idea of creating a local server and then hosting
511.419 -> this font.
512.669 -> So, I'm going to add a few code quickly here.
516.05 -> I just added a delay of 4 seconds here.
519.419 -> Let me start the server quickly here.
522.669 -> And now let's see the output on the browser.
527.029 -> As we can see that white screen and then after
that we saw the system font.
532 -> Let me do this one more time quickly.
538.16 -> There's the white screen, system font and
then we actually saw the custom font.
546.28 -> Let me show the network tab here as well.
550.839 -> Open the page, timeout period, default font
is still being downloaded.
556.3 -> It gets downloaded and then the actual custom
font is rendered.
560.72 -> We call this problem as FOUT.
564.52 -> In other words, we call it as Flash Of Unstyled
Text.
569.24 -> And the reason why we are seeing unstyled
is your system font might be different from
574.55 -> your actual custom font.
576.95 -> And there are a few solutions to solve this
problem and people have different opinions
581.839 -> about different solutions.
584.89 -> So on the CSS file I'm going to add a new
property
588.49 -> called font-display.
590.089 -> It is being supported by all the major browsers.
595.07 -> In case if you are still operating under some
old browser, I guess there is a separate library
601.87 -> which handles the same scenario.
605.09 -> So for the time-being, I'm just going to focus
on the font-display property.
608.68 -> So, there are a few options here and each
of these options have different use cases.
615.36 -> So this auto value is basically value which
is defined by your user agent.
624.7 -> In case of Safari it might be different, in
case of Chrome it might be different and so
629.2 -> on, right?
631.42 -> So in case of chrome, auto means block because
block is the default behaviour, meaning it
637.639 -> will wait for that 3 seconds with white screen
and then if it's not being downloaded, it
644.12 -> shows the system font and when the actual
custom font gets downloaded, the system font
649.42 -> is being swapped, right?
651.839 -> And there is another option called swap and
with the swap,
658.05 -> what your browser does is, it doesn't have
any block period, meaning it will display
664.98 -> the system font right away.
666.74 -> Let me show that quickly as well.
670.7 -> We didn't see that white space here.
674.4 -> Your browser directly shows the system font,
like so, and then
679.98 -> when the custom font is downloaded, it just
swaps with the new custom font.
687.14 -> And people have different opinions about the
swap because if you notice here, the custom
693.25 -> font only occupies three lines on the first
paragraph, right?
697.96 -> But if you look on the system font, it took
I guess, 5 lines here and with this differences
706.04 -> on the layout and positions, it will trigger
the layout shifts, right?
710.959 -> Or we call it as Reflow, right?
714.6 -> Imagine you have some Button right here and
this is, sorry, we have three lines here and
722.279 -> on the system font, your button will be pushed
downwards and it might not be a good user
729.25 -> experience.
731.39 -> Let me share one more document quickly here
to talk more about these options.
736.899 -> So, as we saw earlier about block and swap
options, these two options has problems of
745.279 -> layout shifts.
747.01 -> In case of block there's a problem of flash
of invisible text, whereas in case of swap
753.3 -> there's a problem of flash of unstyled text.
757.279 -> So there are two more options which are fallback
and optional.
762.459 -> So the main idea of fallback and optional
options are to minimize the risks of layout
769.1 -> shifts and invisible text.
772.31 -> And the way it does is by providing extremely
short window for block period and also the
779.16 -> swap period is pretty small.
781.709 -> So if the font is not downloaded and rendered
within this time period, then browser will
788.97 -> only display the system font even though it
later downloads the font.
795.19 -> And it's the same thing with optional with
just one difference and that is there is no
801.149 -> swap period window for the optional option,
meaning if the browser is able to
808.41 -> download and render the custom font within
this block period, then it displays else it
815.741 -> will never display the custom font even in
the future browser successfully downloads
821.35 -> the font.
822.9 -> So let's try to implement these remaining
options now.
827.82 -> So let me try to make it fallback and with
everything remaining the same, let me try
834.899 -> to open a new tab here.
837.81 -> So we saw the default font and meanwhile the
font is being downloaded which we can see
846.009 -> here.
847.139 -> Let me try to refresh.
848.91 -> So the font is still getting downloaded.
851.72 -> We already saw the system font.
853.72 -> Now the font has been downloaded but it didn't
swap with the custom front, right?
860.3 -> Because fallback option prioritizes to minimize
the reflows.
868.32 -> So it's the same thing with the optional as
well, right?
873.75 -> Which is even stricter than the fallback option.
879.24 -> Let me open this tab one more time.
882.06 -> It shows the default font on the network tab.
889.61 -> Let me do this one more time.
892.68 -> System font is here still downloading.
895.54 -> Even if the font is downloaded successfully,
it will never swap the system font with the
901.47 -> custom font.
902.54 -> It's because the main goal of the optional
option is to prevent the layout shifts or
911.199 -> reflow in order to provide good user experience.
914.49 -> That's pretty much it about the font-display.
918.06 -> And please make sure to pick the correct option
based on your situation.
924.62 -> If you think that font style is very important
then I guess you have to go with either block
930.37 -> or swap.
931.91 -> And if layout shifts is important to you,
then I guess you have to pick between fallback
939.37 -> or optional.
940.39 -> Thank you much for watching my video.
944 -> If you like my video, please share and subscribe
to my channel.
947.27 -> It would really help me to grow my channel.
950.639 -> Until then, see you on the next video.
952.61 -> Bye.
Source: https://www.youtube.com/watch?v=wnpMeYARV4g