From 326f5d194da4710cb8dd69acea1aa7b91564a9de Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Sun, 1 Mar 2026 02:57:58 +0300 Subject: [PATCH] Preload system fonts on app startup Cache font list in Rust via OnceLock, fire preload request from main.ts so the font list is ready before user opens the picker. --- desktop/src/lib.rs | 11 +++++++++-- src/engine/fonts.ts | 21 +++++++++++++++------ src/main.ts | 3 +++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/desktop/src/lib.rs b/desktop/src/lib.rs index f8fe33a4b..3158e2183 100644 --- a/desktop/src/lib.rs +++ b/desktop/src/lib.rs @@ -5,6 +5,7 @@ use tauri::{ use font_kit::source::SystemSource; use serde::Serialize; +use std::sync::OnceLock; #[derive(Serialize, Clone)] struct FontFamily { @@ -12,8 +13,9 @@ struct FontFamily { styles: Vec, } -#[tauri::command] -fn list_system_fonts() -> Vec { +static FONT_CACHE: OnceLock> = OnceLock::new(); + +fn enumerate_system_fonts() -> Vec { let source = SystemSource::new(); let mut families: Vec = Vec::new(); @@ -60,6 +62,11 @@ fn list_system_fonts() -> Vec { families } +#[tauri::command] +fn list_system_fonts() -> Vec { + FONT_CACHE.get_or_init(enumerate_system_fonts).clone() +} + #[tauri::command] fn load_system_font(family: String, style: String) -> Result, String> { let source = SystemSource::new(); diff --git a/src/engine/fonts.ts b/src/engine/fonts.ts index 3204df388..e23746f53 100644 --- a/src/engine/fonts.ts +++ b/src/engine/fonts.ts @@ -13,15 +13,24 @@ function isTauri(): boolean { return typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window } +let tauriFontsPromise: Promise | null = null + async function getTauriFonts(): Promise { if (tauriFontsCache) return tauriFontsCache - try { - const { invoke } = await import('@tauri-apps/api/core') - tauriFontsCache = await invoke('list_system_fonts') - return tauriFontsCache - } catch { - return [] + if (!tauriFontsPromise) { + tauriFontsPromise = import('@tauri-apps/api/core') + .then(({ invoke }) => invoke('list_system_fonts')) + .then((fonts) => { + tauriFontsCache = fonts + return fonts + }) + .catch(() => []) } + return tauriFontsPromise +} + +export function preloadFonts(): void { + if (isTauri()) getTauriFonts() } export async function listFamilies(): Promise { diff --git a/src/main.ts b/src/main.ts index c58bd1b6a..5b83bee06 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,9 @@ import { createApp } from 'vue' import './app.css' +import { preloadFonts } from '@/engine/fonts' + import App from './App.vue' +preloadFonts() createApp(App).mount('#app')