tangled mirror of catsky-🐱 Soothing soft social-app fork with all the niche toggles! (Unofficial); for issues and PRs please put them on github:NekoDrone/catsky-social

[Neue] Parallel font loading on web (#5411)

* Parallel font loading

(cherry picked from commit 10e2b05b575bbbf8b0ca5b4a336817cd902d712b)

* Handle failures

* Rely on font-face and preload tags for font loading (#5431)

* Cache fonts for a year

authored by Eric Bailey and committed by GitHub 22410a3c c8184e82

+5
bskyweb/cmd/bskyweb/server.go
··· 210 210 maxAge = 7 * (60 * 60 * 24) // 1 week 211 211 } 212 212 213 + // fonts can be cached for a year 214 + if strings.HasSuffix(path, ".otf") { 215 + maxAge = 365 * (60 * 60 * 24) // 1 year 216 + } 217 + 213 218 c.Response().Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%d", maxAge)) 214 219 return next(c) 215 220 }
bskyweb/static/media/Inter-Black.66e9a87f1c921e844ed4.otf

This is a binary file and will not be displayed.

bskyweb/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf

This is a binary file and will not be displayed.

bskyweb/static/media/Inter-Bold.8d330503e1d034ad68de.otf

This is a binary file and will not be displayed.

bskyweb/static/media/Inter-BoldItalic.bb17e63f9baa0d861a20.otf

This is a binary file and will not be displayed.

bskyweb/static/media/Inter-ExtraBold.ff2581a193bf6b7e0b06.otf

This is a binary file and will not be displayed.

bskyweb/static/media/Inter-ExtraBoldItalic.0e50b40728d24d40fdf4.otf

This is a binary file and will not be displayed.

bskyweb/static/media/Inter-Italic.95778eb0c75dc956257e.otf

This is a binary file and will not be displayed.

bskyweb/static/media/Inter-Medium.296aa2d65964269836b3.otf

This is a binary file and will not be displayed.

bskyweb/static/media/Inter-MediumItalic.0e57e17a6311368e2114.otf

This is a binary file and will not be displayed.

bskyweb/static/media/Inter-Regular.1f5ed03b6dd9fd1f9982.otf

This is a binary file and will not be displayed.

bskyweb/static/media/Inter-SemiBold.2277990330981b8409bb.otf

This is a binary file and will not be displayed.

bskyweb/static/media/Inter-SemiBoldItalic.f62fea3df3a521d6c8a7.otf

This is a binary file and will not be displayed.

bskyweb/static/media/MaterialIcons.f20305dee9d396fea5c7.ttf

This is a binary file and will not be displayed.

+98
bskyweb/templates/base.html
··· 13 13 14 14 <!-- Hello Humans! API docs at https://atproto.com --> 15 15 16 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Regular.1f5ed03b6dd9fd1f9982.otf"> 17 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Italic.95778eb0c75dc956257e.otf"> 18 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Medium.296aa2d65964269836b3.otf"> 19 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-MediumItalic.0e57e17a6311368e2114.otf"> 20 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-SemiBold.2277990330981b8409bb.otf"> 21 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-SemiBoldItalic.f62fea3df3a521d6c8a7.otf"> 22 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Bold.8d330503e1d034ad68de.otf"> 23 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-BoldItalic.bb17e63f9baa0d861a20.otf"> 24 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-ExtraBold.ff2581a193bf6b7e0b06.otf"> 25 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-ExtraBoldItalic.0e50b40728d24d40fdf4.otf"> 26 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Black.66e9a87f1c921e844ed4.otf"> 27 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf"> 28 + 16 29 <style> 30 + @font-face { 31 + font-family: "Inter-Regular"; 32 + src: local("Inter-Regular"), url(/static/media/Inter-Regular.1f5ed03b6dd9fd1f9982.otf) format("font/otf"); 33 + font-weight: 400; 34 + font-style: normal; 35 + font-display: swap; 36 + } 37 + @font-face { 38 + font-family: "Inter-Italic"; 39 + src: local("Inter-Italic"), url(/static/media/Inter-Italic.95778eb0c75dc956257e.otf) format("font/otf"); 40 + font-weight: 400; 41 + font-style: italic; 42 + font-display: swap; 43 + } 44 + @font-face { 45 + font-family: "Inter-Medium"; 46 + src: local("Inter-Medium"), url(/static/media/Inter-Medium.296aa2d65964269836b3.otf) format("font/otf"); 47 + font-weight: 500; 48 + font-style: normal; 49 + font-display: swap; 50 + } 51 + @font-face { 52 + font-family: "Inter-MediumItalic"; 53 + src: local("Inter-MediumItalic"), url(/static/media/Inter-MediumItalic.0e57e17a6311368e2114.otf) format("font/otf"); 54 + font-weight: 500; 55 + font-style: italic; 56 + font-display: swap; 57 + } 58 + @font-face { 59 + font-family: "Inter-SemiBold"; 60 + src: local("Inter-SemiBold"), url(/static/media/Inter-SemiBold.2277990330981b8409bb.otf) format("font/otf"); 61 + font-weight: 600; 62 + font-style: normal; 63 + font-display: swap; 64 + } 65 + @font-face { 66 + font-family: "Inter-SemiBoldItalic"; 67 + src: local("Inter-SemiBoldItalic"), url(/static/media/Inter-SemiBoldItalic.f62fea3df3a521d6c8a7.otf) format("font/otf"); 68 + font-weight: 600; 69 + font-style: italic; 70 + font-display: swap; 71 + } 72 + @font-face { 73 + font-family: "Inter-Bold"; 74 + src: local("Inter-Bold"), url(/static/media/Inter-Bold.8d330503e1d034ad68de.otf) format("font/otf"); 75 + font-weight: 700; 76 + font-style: normal; 77 + font-display: swap; 78 + } 79 + @font-face { 80 + font-family: "Inter-BoldItalic"; 81 + src: local("Inter-BoldItalic"), url(/static/media/Inter-BoldItalic.bb17e63f9baa0d861a20.otf) format("font/otf"); 82 + font-weight: 700; 83 + font-style: italic; 84 + font-display: swap; 85 + } 86 + @font-face { 87 + font-family: "Inter-ExtraBold"; 88 + src: local("Inter-ExtraBold"), url(/static/media/Inter-ExtraBold.ff2581a193bf6b7e0b06.otf) format("font/otf"); 89 + font-weight: 800; 90 + font-style: normal; 91 + font-display: swap; 92 + } 93 + @font-face { 94 + font-family: "Inter-ExtraBoldItalic"; 95 + src: local("Inter-ExtraBoldItalic"), url(/static/media/Inter-ExtraBoldItalic.0e50b40728d24d40fdf4.otf) format("font/otf"); 96 + font-weight: 800; 97 + font-style: italic; 98 + font-display: swap; 99 + } 100 + @font-face { 101 + font-family: "Inter-Black"; 102 + src: local("Inter-Black"), url(/static/media/Inter-Black.66e9a87f1c921e844ed4.otf) format("font/otf"); 103 + font-weight: 900; 104 + font-style: normal; 105 + font-display: swap; 106 + } 107 + @font-face { 108 + font-family: "Inter-BlackItalic"; 109 + src: local("Inter-BlackItalic"), url(/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf) format("font/otf"); 110 + font-weight: 900; 111 + font-style: italic; 112 + font-display: swap; 113 + } 114 + 17 115 /** 18 116 * Extend the react-native-web reset: 19 117 * https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/exports/StyleSheet/initialRules.js
+2 -3
src/App.native.tsx
··· 55 55 import {Provider as VideoVolumeProvider} from '#/view/com/util/post-embeds/VideoVolumeContext' 56 56 import * as Toast from '#/view/com/util/Toast' 57 57 import {Shell} from '#/view/shell' 58 - import {ThemeProvider as Alf, useFonts} from '#/alf' 58 + import {ThemeProvider as Alf} from '#/alf' 59 59 import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 60 60 import {NuxDialogs} from '#/components/dialogs/nuxs' 61 61 import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry' ··· 156 156 157 157 function App() { 158 158 const [isReady, setReady] = useState(false) 159 - const [loaded] = useFonts() 160 159 161 160 React.useEffect(() => { 162 161 initPersistedState().then(() => setReady(true)) 163 162 }, []) 164 163 165 - if (!isReady || !loaded) { 164 + if (!isReady) { 166 165 return null 167 166 } 168 167
+2 -3
src/App.web.tsx
··· 46 46 import * as Toast from '#/view/com/util/Toast' 47 47 import {ToastContainer} from '#/view/com/util/Toast.web' 48 48 import {Shell} from '#/view/shell/index' 49 - import {ThemeProvider as Alf, useFonts} from '#/alf' 49 + import {ThemeProvider as Alf} from '#/alf' 50 50 import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 51 51 import {NuxDialogs} from '#/components/dialogs/nuxs' 52 52 import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry' ··· 146 146 147 147 function App() { 148 148 const [isReady, setReady] = useState(false) 149 - const [loaded, error] = useFonts() 150 149 151 150 React.useEffect(() => { 152 151 initPersistedState().then(() => setReady(true)) 153 152 }, []) 154 153 155 - if (!isReady || (!loaded && !error)) { 154 + if (!isReady) { 156 155 return null 157 156 } 158 157
+10 -9
src/alf/fonts.ts
··· 1 1 import {useFonts as defaultUseFonts} from 'expo-font' 2 2 3 - import {isNative, isWeb} from '#/platform/detection' 3 + import {isWeb} from '#/platform/detection' 4 4 import {Device, device} from '#/storage' 5 5 6 6 const FAMILIES = `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Liberation Sans", Helvetica, Arial, sans-serif` ··· 35 35 } 36 36 37 37 /* 38 - * Unused fonts are commented out, but the files are there if we need them. 38 + * IMPORTANT: This is unused. Expo statically extracts these fonts, but we load 39 + * them manually so that we can parallelize the loading along with the JS 40 + * bundle. 41 + * 42 + * See `#/alf/util/useFonts` for the actually used hooks. 43 + * 44 + * All used fonts MUST be configured here. Unused fonts are commented out, but 45 + * the files are there if we need them. 39 46 */ 40 - export function useFonts() { 41 - /** 42 - * For native, the `expo-font` config plugin embeds the fonts in the 43 - * application binary. But `expo-font` isn't supported on web, so we fall 44 - * back to async loading here. 45 - */ 46 - if (isNative) return [true, null] 47 + export function DO_NOT_USE() { 47 48 return defaultUseFonts({ 48 49 // 'Inter-Thin': require('../../assets/fonts/inter/Inter-Thin.otf'), 49 50 // 'Inter-ThinItalic': require('../../assets/fonts/inter/Inter-ThinItalic.otf'),
+99
web/index.html
··· 17 17 <link rel="preconnect" href="https://bsky.social"> 18 18 <link rel="preconnect" href="https://bsky.network"> 19 19 <title>%WEB_TITLE%</title> 20 + 21 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Regular.1f5ed03b6dd9fd1f9982.otf"> 22 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Italic.95778eb0c75dc956257e.otf"> 23 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Medium.296aa2d65964269836b3.otf"> 24 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-MediumItalic.0e57e17a6311368e2114.otf"> 25 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-SemiBold.2277990330981b8409bb.otf"> 26 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-SemiBoldItalic.f62fea3df3a521d6c8a7.otf"> 27 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Bold.8d330503e1d034ad68de.otf"> 28 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-BoldItalic.bb17e63f9baa0d861a20.otf"> 29 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-ExtraBold.ff2581a193bf6b7e0b06.otf"> 30 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-ExtraBoldItalic.0e50b40728d24d40fdf4.otf"> 31 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Black.66e9a87f1c921e844ed4.otf"> 32 + <link rel="preload" as="font" type="font/otf" href="/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf"> 33 + 20 34 <style> 35 + @font-face { 36 + font-family: "Inter-Regular"; 37 + src: local("Inter-Regular"), url(/static/media/Inter-Regular.1f5ed03b6dd9fd1f9982.otf) format("font/otf"); 38 + font-weight: 400; 39 + font-style: normal; 40 + font-display: swap; 41 + } 42 + @font-face { 43 + font-family: "Inter-Italic"; 44 + src: local("Inter-Italic"), url(/static/media/Inter-Italic.95778eb0c75dc956257e.otf) format("font/otf"); 45 + font-weight: 400; 46 + font-style: italic; 47 + font-display: swap; 48 + } 49 + @font-face { 50 + font-family: "Inter-Medium"; 51 + src: local("Inter-Medium"), url(/static/media/Inter-Medium.296aa2d65964269836b3.otf) format("font/otf"); 52 + font-weight: 500; 53 + font-style: normal; 54 + font-display: swap; 55 + } 56 + @font-face { 57 + font-family: "Inter-MediumItalic"; 58 + src: local("Inter-MediumItalic"), url(/static/media/Inter-MediumItalic.0e57e17a6311368e2114.otf) format("font/otf"); 59 + font-weight: 500; 60 + font-style: italic; 61 + font-display: swap; 62 + } 63 + @font-face { 64 + font-family: "Inter-SemiBold"; 65 + src: local("Inter-SemiBold"), url(/static/media/Inter-SemiBold.2277990330981b8409bb.otf) format("font/otf"); 66 + font-weight: 600; 67 + font-style: normal; 68 + font-display: swap; 69 + } 70 + @font-face { 71 + font-family: "Inter-SemiBoldItalic"; 72 + src: local("Inter-SemiBoldItalic"), url(/static/media/Inter-SemiBoldItalic.f62fea3df3a521d6c8a7.otf) format("font/otf"); 73 + font-weight: 600; 74 + font-style: italic; 75 + font-display: swap; 76 + } 77 + @font-face { 78 + font-family: "Inter-Bold"; 79 + src: local("Inter-Bold"), url(/static/media/Inter-Bold.8d330503e1d034ad68de.otf) format("font/otf"); 80 + font-weight: 700; 81 + font-style: normal; 82 + font-display: swap; 83 + } 84 + @font-face { 85 + font-family: "Inter-BoldItalic"; 86 + src: local("Inter-BoldItalic"), url(/static/media/Inter-BoldItalic.bb17e63f9baa0d861a20.otf) format("font/otf"); 87 + font-weight: 700; 88 + font-style: italic; 89 + font-display: swap; 90 + } 91 + @font-face { 92 + font-family: "Inter-ExtraBold"; 93 + src: local("Inter-ExtraBold"), url(/static/media/Inter-ExtraBold.ff2581a193bf6b7e0b06.otf) format("font/otf"); 94 + font-weight: 800; 95 + font-style: normal; 96 + font-display: swap; 97 + } 98 + @font-face { 99 + font-family: "Inter-ExtraBoldItalic"; 100 + src: local("Inter-ExtraBoldItalic"), url(/static/media/Inter-ExtraBoldItalic.0e50b40728d24d40fdf4.otf) format("font/otf"); 101 + font-weight: 800; 102 + font-style: italic; 103 + font-display: swap; 104 + } 105 + @font-face { 106 + font-family: "Inter-Black"; 107 + src: local("Inter-Black"), url(/static/media/Inter-Black.66e9a87f1c921e844ed4.otf) format("font/otf"); 108 + font-weight: 900; 109 + font-style: normal; 110 + font-display: swap; 111 + } 112 + @font-face { 113 + font-family: "Inter-BlackItalic"; 114 + src: local("Inter-BlackItalic"), url(/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf) format("font/otf"); 115 + font-weight: 900; 116 + font-style: italic; 117 + font-display: swap; 118 + } 119 + 21 120 /** 22 121 * Extend the react-native-web reset: 23 122 * https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/exports/StyleSheet/initialRules.js