diff --git a/server/lib/get-dependencies-for-entry-point-name.js b/server/lib/get-dependencies-for-entry-point-name.js
index 155da31..dd8cac1 100644
--- a/server/lib/get-dependencies-for-entry-point-name.js
+++ b/server/lib/get-dependencies-for-entry-point-name.js
@@ -30,6 +30,7 @@ function getEntryPoints() {
return _entryPoints;
}
+// eslint-disable-next-line max-statements
function recurseManifestEntryName(entryName) {
const manifest = getManifest();
const entry = manifest[entryName];
@@ -38,6 +39,9 @@ function recurseManifestEntryName(entryName) {
// css
const styles = [];
+ // assets
+ const fonts = [];
+ const images = [];
// imports
const scripts = [entryFilePath];
// imports, dynamicImports
@@ -50,11 +54,15 @@ function recurseManifestEntryName(entryName) {
const {
styles: moreStyles,
+ fonts: moreFonts,
+ images: moreImages,
scripts: moreScripts,
preloadScripts: morePreloadScripts,
} = recurseManifestEntryName(importName);
styles.push(...moreStyles);
+ fonts.push(...moreFonts);
+ images.push(...moreImages);
scripts.push(...moreScripts);
preloadScripts.push(...morePreloadScripts);
}
@@ -65,11 +73,15 @@ function recurseManifestEntryName(entryName) {
const {
styles: moreStyles,
+ fonts: moreFonts,
+ images: moreImages,
scripts: moreScripts,
preloadScripts: morePreloadScripts,
} = recurseManifestEntryName(dynamicImportName);
styles.push(...moreStyles);
+ fonts.push(...moreFonts);
+ images.push(...moreImages);
scripts.push(...moreScripts);
preloadScripts.push(...morePreloadScripts);
}
@@ -78,9 +90,36 @@ function recurseManifestEntryName(entryName) {
styles.push(path.join('/', cssName));
}
+ for (const assetName of entry.assets || []) {
+ const assetFileExtension = path.extname(assetName);
+ const assetFilePath = path.join('/', assetName);
+
+ if (
+ // We only care about preloading `.woff2` fonts since that is all of the major
+ // browsers support them.
+ ['.woff2'].includes(assetFileExtension) &&
+ // We only care about a few variants that we will actually likely use on the page
+ // (this may need to change over time).
+ ['-Regular-', '-Bold-', '-SemiBold-'].some((variant) => assetName.includes(variant))
+ ) {
+ fonts.push(path.join('/', assetFilePath));
+ } else if (
+ // Preload a specific file we use on the room directory homepage
+ assetName.includes('matrix-lines-hero')
+ // We don't care about preloading *all* images at the moment because there are a
+ // lot that we just don't use even though they are bundled because they are
+ // referened in the CSS.
+ //['.jpg', '.png', '.svg'].includes(assetFileExtension)
+ ) {
+ images.push(path.join('/', assetFilePath));
+ }
+ }
+
return {
// css
styles,
+ fonts,
+ images,
// imports
scripts,
// dynamicImports
@@ -103,11 +142,14 @@ function getDependenciesForEntryPointName(entryPointName) {
)}`
);
- const { styles, scripts, preloadScripts } = recurseManifestEntryName(entryPointName);
+ const { styles, fonts, images, scripts, preloadScripts } =
+ recurseManifestEntryName(entryPointName);
return {
// De-duplicate assets
styles: Array.from(new Set(styles)),
+ fonts: Array.from(new Set(fonts)),
+ images: Array.from(new Set(images)),
scripts: Array.from(new Set(scripts)),
preloadScripts: Array.from(new Set(preloadScripts)),
};
diff --git a/server/lib/set-headers-to-preload-assets.js b/server/lib/set-headers-to-preload-assets.js
index c501a69..9a173f7 100644
--- a/server/lib/set-headers-to-preload-assets.js
+++ b/server/lib/set-headers-to-preload-assets.js
@@ -16,13 +16,17 @@ function setHeadersToPreloadAssets(res, pageOptions) {
assert(pageOptions);
assert(pageOptions.entryPoint);
- const { styles, preloadScripts } = getDependenciesForEntryPointName(pageOptions.entryPoint);
+ const { styles, fonts, images, preloadScripts } = getDependenciesForEntryPointName(
+ pageOptions.entryPoint
+ );
+ // Work on assembling the `Link` headers
+ //
// Note: Any docs for the `` element apply to the `Link` header. "The `Link`
// header contains parameters [that] are equivalent to attributes of the ``
// element."
// (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link#parameters)
-
+ //
// XXX: Should we add `nopush` to the `Link` headers here? Many servers initiate an
// HTTP/2 Server Push when they encounter a preload link in HTTP header form
// otherwise. Do we want/care about that (or maybe we don't)? (mentioned in
@@ -32,16 +36,19 @@ function setHeadersToPreloadAssets(res, pageOptions) {
return `<${styleUrl}>; rel=preload; as=style`;
});
- // TODO: We should preload fonts as well.
- //
// We use `crossorigin` because fonts are fetched with anonymous mode "cors" and
// "same-origin" credentials mode (see
// https://drafts.csswg.org/css-fonts/#font-fetching-requirements). `crossorigin` is
// just short-hand for `crossorigin=anonymous` (see
// https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin and
// https://html.spec.whatwg.org/multipage/infrastructure.html#cors-settings-attribute).
- //
- // `Link: ; rel=preload; as=font; crossorigin`
+ const fontLinks = fonts.map((fontUrl) => {
+ return `<${fontUrl}>; rel=preload; as=font; crossorigin`;
+ });
+
+ const imageLinks = images.map((imageUrl) => {
+ return `<${imageUrl}>; rel=preload; as=image`;
+ });
// We use `rel=modulepreload` instead of `rel=preload` for the JavaScript modules
// because it's a nice dedicated thing to handle ESM modules that not only downloads
@@ -63,7 +70,7 @@ function setHeadersToPreloadAssets(res, pageOptions) {
return `<${scriptUrl}>; rel=modulepreload`;
});
- res.append('Link', [].concat(styleLinks, scriptLinks).join(', '));
+ res.append('Link', [].concat(styleLinks, fontLinks, imageLinks, scriptLinks).join(', '));
}
module.exports = setHeadersToPreloadAssets;