I would like to preload Material Icons font thanks to:
<link rel="preload" href="https://fonts.gstatic.com/s/materialicons/v125/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2" as="font" type="font/woff2" crossorigin="anonymous">
In fact, it works!
However, in the filename, we have a hash/UUID: v125/flUhRq6tzZclQEJ-Vdg-IuiaDsNc
; consequently, if Google publishes a new release, for example v126/sjboabchdiamblq-Abf-abvichef
, then my preload won't work!
For more details, I use their CDN like this:
<link
href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet"
/>
Which returns this CSS:
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/materialicons/v125/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2');
}
.material-icons {
font-family: 'Material Icons';
[...]
}
Notice: I'm working with Angular, and I want the loading of the font start immediately, and not when the application is loaded, i.e. when a Material Icon is displayed.Moreover, even if the CSS file loads immediately, the font won't start loading until a Material Icon is displayed.
I found a solution, thanks to https://www.npmjs.com/package/@angular-builders/custom-webpack, and using a library for mMaterial Icons (https://www.npmjs.com/package/material-icons)
This builder allows to transform the index.html after the build process.
<link rel="preload" href="/material-icons.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="/material-icons-outlined.woff2" as="font" type="font/woff2" crossorigin="anonymous">
"indexTransform": "index-html-transform.js"
in angular.json like this:"configurations": {
"production": {
[...],
"indexTransform": "index-html-transform.js"
}
}
const fs = require("fs");
/**
* @param {string} indexHtmlSource
* @return {string}
*/
const setMaterialIconsFontsPreloading = (indexHtmlSource) => {
const allOutputFilenames = fs.readdirSync("./dist/essai-preload-mat-icons");
const requiredMatIconsFontsMatches = indexHtmlSource.matchAll(/(material-icons.*)\.woff2/g);
/**
* @exemple `['material-icons', 'material-icons-outlined']`
*/
const requiredIconTypes = [...requiredMatIconsFontsMatches].map((match) => match[1]);
return requiredIconTypes.reduce((previousIndexHtml, requiredIconType) => {
/**
* @exemple `'material-icons-outlined.woff2'`
*/
const inputFilename = `${requiredIconType}.woff2`;
/**
* @exemple `'material-icons-outlined.125af8545b6.woff2'`
*/
const outputFilename = allOutputFilenames.find((outputFilenameItem) => outputFilenameItem.match(`^${requiredIconType}\\.\\w+\\.woff2$`));
return previousIndexHtml.replace(inputFilename, outputFilename);
}, indexHtmlSource);
}
/**
*
* @param {{ configuration?: string; project: string; target: string;}} targetOptions
* @param {string} indexHtmlSource
* @returns {string} The final index.html to serve.
*/
module.exports = (targetOptions, indexHtmlSource) => {
return setMaterialIconsFontsPreloading(indexHtmlSource);
};