Skip to content

Commit 3e74810

Browse files
gabalafoutrallard
andauthored
MAINT - Defer FontAwesome script to improve performance (#2209)
This pull request: - Adds "defer" attribute to the script tag that loads the FontAwesome library - Consolidates our two custom icon files into one and also loads them with defer - Updates documentation to reflect the above two changes - Excludes images.html from the list of Kitchen Sink pages to check with Lighthouse. ### Defer > [!WARNING] > When this pull request gets released in the next version of the PyData Sphinx Theme, it will require theme users to update their custom icon entries in `html_js_files` to include the `defer` attribute (see the update to the docs page in this pull request). Without the defer attribute, the entire page has to wait for the FontAwesome script to be downloaded and executed. Lighthouse identified this script as the worst offender. With the defer attribute, the page should be able to load faster. ### Excluding images.html The reason I'm excluding images.html from Lighthouse is because it contains images that are hotlinked from Picsum. I think that this is the reason the Lighthouse performance score comes in too low (below 80). Because when I examined the Lighthouse report for that page, I saw the main reason the page failed was because of a slow Largest Contentful Paint, and when digging into that, the report showed the following table: Phase | % of LCP | Timing -- | -- | -- TTFB | 8% | 460 ms Load Delay | 89% | 5,350 ms Load Time | 2% | 110 ms Render Delay | 2% | 100 ms I assume that most of that load delay has to do with hotlinking from Picsum and nothing that we can fix without modifying the Kitchen Sink pages, which we're not supposed to do since those are generated from a script. Using the [Lighthouse score calculator](https://googlechrome.github.io/lighthouse/scorecalc/#FCP=1665&LCP=6016&TBT=54&CLS=0&SI=2861&TTI=6045&device=mobile&version=12.1.0), if I substract 5,000 ms from Largest Contentful Paint, the performance score climbs to 99, which puts it in line with the new performance scores for the other Kitchen Sink pages. On the flip side, even though this PR excludes images.html from Lighthouse, it actually adds more Kitchen Sink pages to the Lighthouse audit because previously only 5 pages were being checked because the [default for maxAutodiscoverUrls](https://github.com/GoogleChrome/lighthouse-ci/blob/main/docs/configuration.md) is 5. ### How I checked this PR - [x] Looked at the results on the lighthouse-audit CI job - Inspected the two custom icons in the preview build - [x] Brave browser, desktop mode - [x] Brave browser, mobile mode - [x] Safari, desktop mode - [x] Firefox, desktop mode - [x] Checked the preview build to make sure there were no new JavaScript or other errors in the browser dev tools console log. - [x] Checked the updated [Header Links docs page](https://pydata-sphinx-theme--2209.org.readthedocs.build/en/2209/user_guide/header-links.html) in the preview build --------- Co-authored-by: Tania Allard <taniar.allard@gmail.com>
1 parent 6e536c2 commit 3e74810

File tree

6 files changed

+75
-51
lines changed

6 files changed

+75
-51
lines changed

.github/workflows/lighthouserc.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@
22
"ci": {
33
"collect": {
44
"staticDistDir": "./audit/_build/",
5-
"autodiscoverUrlBlocklist": [
6-
"/genindex.html",
7-
"/search.html",
8-
"/_static/webpack-macros.html"
5+
"url": [
6+
"/admonitions.html",
7+
"/api.html",
8+
"/blocks.html",
9+
"/generic.html",
10+
"/lists.html",
11+
"/really-long.html",
12+
"/structure.html",
13+
"/tables.html",
14+
"/typography.html"
915
],
1016
"settings": {
1117
"skipAudits": ["canonical"]
Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
1-
/*******************************************************************************
2-
* Set a custom icon for pypi as it's not available in the fa built-in brands
3-
*/
41
FontAwesome.library.add(
5-
(faListOldStyle = {
2+
/**
3+
* Custom icon definitions
4+
*
5+
* see https://pydata-sphinx-theme.readthedocs.io/en/latest/user_guide/header-links.html#svg-image-icons
6+
*/
7+
{
68
prefix: "fa-custom",
79
iconName: "pypi",
810
icon: [
9-
17.313, // viewBox width
10-
19.807, // viewBox height
11-
[], // ligature
12-
"e001", // unicode codepoint - private use area
13-
"m10.383 0.2-3.239 1.1769 3.1883 1.1614 3.239-1.1798zm-3.4152 1.2411-3.2362 1.1769 3.1855 1.1614 3.2369-1.1769zm6.7177 0.00281-3.2947 1.2009v3.8254l3.2947-1.1988zm-3.4145 1.2439-3.2926 1.1981v3.8254l0.17548-0.064132 3.1171-1.1347zm-6.6564 0.018325v3.8247l3.244 1.1805v-3.8254zm10.191 0.20931v2.3137l3.1777-1.1558zm3.2947 1.2425-3.2947 1.1988v3.8254l3.2947-1.1988zm-8.7058 0.45739c0.00929-1.931e-4 0.018327-2.977e-4 0.027485 0 0.25633 0.00851 0.4263 0.20713 0.42638 0.49826 1.953e-4 0.38532-0.29327 0.80469-0.65542 0.93662-0.36226 0.13215-0.65608-0.073306-0.65613-0.4588-6.28e-5 -0.38556 0.2938-0.80504 0.65613-0.93662 0.068422-0.024919 0.13655-0.038114 0.20156-0.039466zm5.2913 0.78369-3.2947 1.1988v3.8247l3.2947-1.1981zm-10.132 1.239-3.2362 1.1769 3.1883 1.1614 3.2362-1.1769zm6.7177 0.00213-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4124 1.2439-3.2947 1.1988v3.8254l3.2947-1.1988zm-6.6585 0.016195v3.8275l3.244 1.1805v-3.8254zm16.9 0.21143-3.2947 1.1988v3.8247l3.2947-1.1981zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4124 1.2432-3.2947 1.1988v3.8254l3.2947-1.1988zm-6.6585 0.019027v3.8247l3.244 1.1805v-3.8254zm13.485 1.4497-3.2947 1.1988v3.8247l3.2947-1.1981zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm2.4018 0.38127c0.0093-1.83e-4 0.01833-3.16e-4 0.02749 0 0.25633 0.0085 0.4263 0.20713 0.42638 0.49826 1.97e-4 0.38532-0.29327 0.80469-0.65542 0.93662-0.36188 0.1316-0.65525-0.07375-0.65542-0.4588-1.95e-4 -0.38532 0.29328-0.80469 0.65542-0.93662 0.06842-0.02494 0.13655-0.03819 0.20156-0.03947zm-5.8142 0.86403-3.244 1.1805v1.4201l3.244 1.1805z", // svg path (https://simpleicons.org/icons/pypi.svg)
11+
17.313,
12+
19.807,
13+
[],
14+
"e001",
15+
// https://simpleicons.org/icons/pypi.svg
16+
"m10.383 0.2-3.239 1.1769 3.1883 1.1614 3.239-1.1798zm-3.4152 1.2411-3.2362 1.1769 3.1855 1.1614 3.2369-1.1769zm6.7177 0.00281-3.2947 1.2009v3.8254l3.2947-1.1988zm-3.4145 1.2439-3.2926 1.1981v3.8254l0.17548-0.064132 3.1171-1.1347zm-6.6564 0.018325v3.8247l3.244 1.1805v-3.8254zm10.191 0.20931v2.3137l3.1777-1.1558zm3.2947 1.2425-3.2947 1.1988v3.8254l3.2947-1.1988zm-8.7058 0.45739c0.00929-1.931e-4 0.018327-2.977e-4 0.027485 0 0.25633 0.00851 0.4263 0.20713 0.42638 0.49826 1.953e-4 0.38532-0.29327 0.80469-0.65542 0.93662-0.36226 0.13215-0.65608-0.073306-0.65613-0.4588-6.28e-5 -0.38556 0.2938-0.80504 0.65613-0.93662 0.068422-0.024919 0.13655-0.038114 0.20156-0.039466zm5.2913 0.78369-3.2947 1.1988v3.8247l3.2947-1.1981zm-10.132 1.239-3.2362 1.1769 3.1883 1.1614 3.2362-1.1769zm6.7177 0.00213-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4124 1.2439-3.2947 1.1988v3.8254l3.2947-1.1988zm-6.6585 0.016195v3.8275l3.244 1.1805v-3.8254zm16.9 0.21143-3.2947 1.1988v3.8247l3.2947-1.1981zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4124 1.2432-3.2947 1.1988v3.8254l3.2947-1.1988zm-6.6585 0.019027v3.8247l3.244 1.1805v-3.8254zm13.485 1.4497-3.2947 1.1988v3.8247l3.2947-1.1981zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm2.4018 0.38127c0.0093-1.83e-4 0.01833-3.16e-4 0.02749 0 0.25633 0.0085 0.4263 0.20713 0.42638 0.49826 1.97e-4 0.38532-0.29327 0.80469-0.65542 0.93662-0.36188 0.1316-0.65525-0.07375-0.65542-0.4588-1.95e-4 -0.38532 0.29328-0.80469 0.65542-0.93662 0.06842-0.02494 0.13655-0.03819 0.20156-0.03947zm-5.8142 0.86403-3.244 1.1805v1.4201l3.244 1.1805z",
1417
],
15-
}),
18+
},
19+
{
20+
prefix: "fa-custom",
21+
iconName: "pydata",
22+
icon: [
23+
24,
24+
24,
25+
[],
26+
"e002",
27+
"M12.1,17.8v5.8l-5-2.9v-5.8L12.1,17.8z M12.1,12v5.8l-5-2.9V9.1L12.1,12z M17,9.1L12.1,12v5.8l4.9-2.9V9.1z M12.1,6.2L7,9.1l5,2.9L17,9.1L12.1,6.2z M17,9.1V3.3l-4.9-2.8v5.8L17,9.1z",
28+
],
29+
},
1630
);

docs/_static/pydata-icon.js

Lines changed: 0 additions & 16 deletions
This file was deleted.

docs/conf.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,9 @@
257257
# so a file named "default.css" will overwrite the builtin "default.css".
258258
html_static_path = ["_static"]
259259
html_css_files = ["custom.css"]
260-
html_js_files = ["pydata-icon.js", "custom-icon.js"]
260+
html_js_files = [
261+
("custom-icons.js", {"defer": "defer"}),
262+
]
261263
todo_include_todos = True
262264

263265
# -- favicon options ---------------------------------------------------------

docs/user_guide/header-links.rst

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -205,38 +205,54 @@ SVG image icons
205205
In order to make use of the full feature set of ``.svg`` images provided by HTML you will need
206206
to set up the ``.svg`` to be used as a FontAwesome type icon. This is a fairly straightforward process:
207207

208-
#. Copy the contents of ``custom-icon.js`` - located within the ``docs`` tree - into an appropriate directory of your documentation
209-
source (typically ``source/js``) and rename the file however you like. Highlighted below are the lines which must be modified
208+
#. Copy `custom-icons.js`_ into an appropriate directory of your documentation
209+
source (typically ``source/js``). In that file you will find a list of custom
210+
icon definitions. Each definition looks like this:
210211

211212
.. code:: javascript
212213
213-
prefix: "fa-custom",
214-
iconName: "pypi",
215-
icon: [
216-
17.313, // viewBox width
217-
19.807, // viewBox height
218-
[], // ligature
219-
"e001", // unicode codepoint - private use area
220-
"m10.383 0.2-3.239 ...", // string definined SVG path
221-
],
222-
214+
{
215+
prefix: "fa-custom",
216+
iconName: "pypi",
217+
icon: [
218+
17.313, // viewBox width
219+
19.807, // viewBox height
220+
[], // ligature
221+
"e001", // unicode codepoint - private use area
222+
"m10.383 0.2-3.239 ...", // svg path
223+
],
224+
}
223225
224-
#. Update the following file contents:
226+
#. Remove the existing list of icon definitions and add your own using the same pattern as above:
225227

226-
#. ``iconName`` to be one of our choosing
227-
#. Change the viewbox height and width to match that of your icon
228-
#. Replace the SVG path string with the path which defines your custom icon
228+
#. Keep the value of ``prefix`` as "fa-custom"
229+
#. Set the value of ``iconName`` to a short, sensible, lowercase name for your icon
230+
#. Change the view box height and width to match that of your icon
231+
#. For each custom icon you define in the list, increment the Unicode codepoint by 1: ``"e001"``, ``"e002"``, ``"e003"``...
232+
#. Replace the SVG path string with the path that defines your custom icon
229233

230-
#. Add the relative path from your source directory to the custom javascript file to your ``conf.py``:
234+
#. In ``conf.py``, add the relative path from your source directory to the custom javascript file:
231235

232236
.. code:: python
233237
234238
html_js_files = [
235239
...
236-
"js/pypi-icon.js",
240+
("js/custom-icons.js", {"defer": "defer"}),
237241
...
238242
]
239243
244+
.. versionchanged:: v0.17.0
245+
246+
``defer`` attribute is required.
247+
248+
.. important::
249+
250+
Do not add more than one ``custom-icons.js`` file in your ``conf.py``.
251+
252+
Each custom icon js file includes a call to ``FontAwesome.library.add()``.
253+
Your site's JavaScript can only call that function once. In our testing,
254+
subsequent calls to that function do not load additional icons.
255+
240256
#. Set up the icon link in the ``html_theme_options`` as a FontAwesome icon:
241257

242258
.. code:: python
@@ -254,7 +270,7 @@ to set up the ``.svg`` to be used as a FontAwesome type icon. This is a fairly s
254270
...
255271
]
256272
257-
That's it, your icon will now be inserted with the ``<svg>`` tag and not ``<img>``! You can reference your custom FontAwesome icon in CSS using ``fa-<custom-name>``.
273+
That's it, your icon will now be inserted with the ``<svg>`` tag and not ``<img>``! You can reference your custom FontAwesome icon in CSS using the pattern ``.fa-<iconName>`` , for example ``.fa-pypi``.
258274

259275
.. _icon-link-shortcuts:
260276

@@ -309,3 +325,5 @@ For example, to specify a custom ``target`` and ``rel`` attribute, and to define
309325
310326
.. warning::
311327
This might make your icon links behave unexpectedly and might override the default behavior, so make sure you know what you're doing!
328+
329+
.. _custom-icons.js: ../_static/custom-icons.js

webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ function macroTemplate({ compilation }) {
7474
7575
{% macro head_js_preload() %}
7676
<!-- So that users can add custom icons -->
77-
${fa_scripts.map(script.bind(compilation)).join("\n")}
77+
${fa_scripts.map(deferScript.bind(compilation)).join("\n")}
7878
<!-- Pre-loaded scripts that we'll load fully later -->
7979
${theme_scripts.map(preloadScript.bind(compilation)).join("\n")}
8080
{% endmacro %}

0 commit comments

Comments
 (0)