Skip to content

Commit 43d6fdc

Browse files
Simplify font preloading (#499)
1 parent 02eeeb7 commit 43d6fdc

File tree

3 files changed

+26
-66
lines changed

3 files changed

+26
-66
lines changed

assets/packs/data_table/main.js

Lines changed: 22 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -9,61 +9,36 @@ import { createTableSkeleton } from "./Skeleton";
99
export async function init(ctx, data) {
1010
ctx.root.appendChild(createTableSkeleton());
1111

12-
try {
13-
await loadStyles(ctx);
14-
} finally {
15-
const root = createRoot(ctx.root);
16-
root.render(<App ctx={ctx} data={data} />);
17-
}
18-
}
19-
20-
async function loadStyles(ctx) {
21-
const cssPromises = [
12+
await Promise.all([
2213
ctx.importCSS(
2314
"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap",
2415
),
2516
ctx.importCSS(
2617
"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap",
2718
),
2819
ctx.importCSS("main.css"),
29-
];
20+
]);
3021

31-
// We force all fonts to be loaded by adding an invisible element,
32-
// and then we explicitly wait for the fonts to finish loading.
22+
// We force all fonts to be loaded before rendering the table.
3323
// This is important on first uncached render. If we don't wait
3424
// and render the table with fallback fonts, the columns get wrong
35-
// default widths. Also, on Firefox ans Safari, once the font is
36-
// loaded, the table only updates on hover, which is bad UX.
37-
38-
const fontPreloader = document.createElement("div");
39-
fontPreloader.setAttribute("aria-hidden", "true");
40-
fontPreloader.style.cssText = `
41-
position: absolute;
42-
visibility: hidden;
43-
left: -9999px;
44-
`;
45-
fontPreloader.innerHTML = `
46-
<span style="font-family: 'JetBrains Mono'">
47-
<span style="font-weight: 400">preload</span>"
48-
<span style="font-weight: 500">preload</span>"
49-
<span style="font-weight: 600">preload</span>"
50-
</span>"
51-
<span style="font-family: 'Inter'">
52-
<span style="font-weight: 400">preload</span>"
53-
<span style="font-weight: 500">preload</span>"
54-
<span style="font-weight: 600">preload</span>"
55-
</span>"
56-
`;
57-
58-
document.body.appendChild(fontPreloader);
59-
60-
try {
61-
await Promise.all(cssPromises);
62-
63-
if (document.fonts && document.fonts.ready) {
64-
await document.fonts.ready;
65-
}
66-
} finally {
67-
document.body.removeChild(fontPreloader);
68-
}
25+
// default widths. Also, in Firefox ans Safari, once the font is
26+
// loaded, the table only updates on hover, which is bad UX. That
27+
// said, in Firefox, this doesn't help 100% of the time either.
28+
await Promise.race([
29+
Promise.all([
30+
document.fonts.load("400 16px 'JetBrains Mono'"),
31+
document.fonts.load("500 16px 'JetBrains Mono'"),
32+
document.fonts.load("600 16px 'JetBrains Mono'"),
33+
document.fonts.load("400 16px Inter"),
34+
document.fonts.load("500 16px Inter"),
35+
document.fonts.load("600 16px Inter"),
36+
]),
37+
// If a font request fails, the promises may not be resolved, so
38+
// we add a timeout just to make sure this finishes at some point.
39+
new Promise((resolve) => setTimeout(resolve, 5000)),
40+
]);
41+
42+
const root = createRoot(ctx.root);
43+
root.render(<App ctx={ctx} data={data} />);
6944
}

0 commit comments

Comments
 (0)