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.
This commit is contained in:
Danila Poyarkov 2026-03-01 02:57:58 +03:00
parent 5ccae709a0
commit 326f5d194d
3 changed files with 27 additions and 8 deletions

View file

@ -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<String>,
}
#[tauri::command]
fn list_system_fonts() -> Vec<FontFamily> {
static FONT_CACHE: OnceLock<Vec<FontFamily>> = OnceLock::new();
fn enumerate_system_fonts() -> Vec<FontFamily> {
let source = SystemSource::new();
let mut families: Vec<FontFamily> = Vec::new();
@ -60,6 +62,11 @@ fn list_system_fonts() -> Vec<FontFamily> {
families
}
#[tauri::command]
fn list_system_fonts() -> Vec<FontFamily> {
FONT_CACHE.get_or_init(enumerate_system_fonts).clone()
}
#[tauri::command]
fn load_system_font(family: String, style: String) -> Result<Vec<u8>, String> {
let source = SystemSource::new();

View file

@ -13,15 +13,24 @@ function isTauri(): boolean {
return typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window
}
let tauriFontsPromise: Promise<TauriFontFamily[]> | null = null
async function getTauriFonts(): Promise<TauriFontFamily[]> {
if (tauriFontsCache) return tauriFontsCache
try {
const { invoke } = await import('@tauri-apps/api/core')
tauriFontsCache = await invoke<TauriFontFamily[]>('list_system_fonts')
return tauriFontsCache
} catch {
return []
if (!tauriFontsPromise) {
tauriFontsPromise = import('@tauri-apps/api/core')
.then(({ invoke }) => invoke<TauriFontFamily[]>('list_system_fonts'))
.then((fonts) => {
tauriFontsCache = fonts
return fonts
})
.catch(() => [])
}
return tauriFontsPromise
}
export function preloadFonts(): void {
if (isTauri()) getTauriFonts()
}
export async function listFamilies(): Promise<string[]> {

View file

@ -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')