From 38a5c67d944cd78e297cb209a5e3b0b1cfe674aa Mon Sep 17 00:00:00 2001 From: Kresna <13603341+slaveofcode@users.noreply.github.com> Date: Sat, 12 Sep 2026 22:00:23 +0700 Subject: [PATCH] perf(build): split neural-tts voices from the engine to fix Rollup chunking TextToSpeech statically imported NEURAL_VOICES from neural-tts.engine while also dynamically importing the engine, so Rollup kept the heavy engine in the island chunk and emitted a 'dynamic import will not move module into another chunk' warning. Move the voice catalogue to a lightweight neural-tts.voices module the island imports statically; the engine is now purely dynamically imported and splits into its own 1.6 kB chunk. Removes the warning and the pathological chunk that sat right where the Cloudflare production build was freezing during 'rendering chunks'. --- src/islands/media/TextToSpeech.tsx | 2 +- src/tools/media/neural-tts.engine.ts | 21 ++++++--------------- src/tools/media/neural-tts.voices.ts | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 src/tools/media/neural-tts.voices.ts diff --git a/src/islands/media/TextToSpeech.tsx b/src/islands/media/TextToSpeech.tsx index 8acac64..8188c68 100644 --- a/src/islands/media/TextToSpeech.tsx +++ b/src/islands/media/TextToSpeech.tsx @@ -3,7 +3,7 @@ import { Button } from '@/components/ui/Button'; import { Alert } from '@/components/ui/Alert'; import { splitIntoChunks } from '@/tools/media/tts.lib'; import { floatToWav } from '@/tools/media/tts-audio.lib'; -import { NEURAL_VOICES } from '@/tools/media/neural-tts.engine'; +import { NEURAL_VOICES } from '@/tools/media/neural-tts.voices'; import { downloadService } from '@/services/download'; import type { Lang } from '@/i18n/config'; diff --git a/src/tools/media/neural-tts.engine.ts b/src/tools/media/neural-tts.engine.ts index d52b1f7..271e59a 100644 --- a/src/tools/media/neural-tts.engine.ts +++ b/src/tools/media/neural-tts.engine.ts @@ -6,22 +6,13 @@ * through the same-origin /hf proxy, matching the Whisper setup. */ import { concatWithSilence, floatToPcm16, splitForPause } from './tts-audio.lib'; +import type { NeuralVoice } from './neural-tts.voices'; -export interface NeuralVoice { id: string; label: string; model: string; } - -// MMS-TTS is multilingual with one small model per language and needs no speaker -// embedding. A curated set that has ONNX ports on the Hugging Face hub. -export const NEURAL_VOICES: NeuralVoice[] = [ - { id: 'eng', label: 'English', model: 'Xenova/mms-tts-eng' }, - { id: 'ind', label: 'Bahasa Indonesia', model: 'Xenova/mms-tts-ind' }, - { id: 'spa', label: 'Español', model: 'Xenova/mms-tts-spa' }, - { id: 'fra', label: 'Français', model: 'Xenova/mms-tts-fra' }, - { id: 'deu', label: 'Deutsch', model: 'Xenova/mms-tts-deu' }, - { id: 'por', label: 'Português', model: 'Xenova/mms-tts-por' }, - { id: 'rus', label: 'Русский', model: 'Xenova/mms-tts-rus' }, - { id: 'ara', label: 'العربية', model: 'Xenova/mms-tts-ara' }, - { id: 'hin', label: 'हिन्दी', model: 'Xenova/mms-tts-hin' }, -]; +// Re-exported for compatibility; the catalogue lives in a lightweight module so +// the TextToSpeech island can import the voice list without pulling this heavy +// engine into its chunk (see neural-tts.voices.ts). +export { NEURAL_VOICES } from './neural-tts.voices'; +export type { NeuralVoice } from './neural-tts.voices'; /* eslint-disable @typescript-eslint/no-explicit-any */ let cached: { model: string; synth: any } | null = null; diff --git a/src/tools/media/neural-tts.voices.ts b/src/tools/media/neural-tts.voices.ts new file mode 100644 index 0000000..fdeaf3b --- /dev/null +++ b/src/tools/media/neural-tts.voices.ts @@ -0,0 +1,25 @@ +/** + * Voice catalogue for neural TTS, split out from `neural-tts.engine.ts` so the + * TextToSpeech island can list voices without statically importing the engine + * (which is heavy and must stay dynamically imported / code-split — a static + + * dynamic import of the engine made Rollup keep it in the island chunk). + */ +export interface NeuralVoice { + id: string; + label: string; + model: string; +} + +// MMS-TTS is multilingual with one small model per language and needs no speaker +// embedding. A curated set that has ONNX ports on the Hugging Face hub. +export const NEURAL_VOICES: NeuralVoice[] = [ + { id: 'eng', label: 'English', model: 'Xenova/mms-tts-eng' }, + { id: 'ind', label: 'Bahasa Indonesia', model: 'Xenova/mms-tts-ind' }, + { id: 'spa', label: 'Español', model: 'Xenova/mms-tts-spa' }, + { id: 'fra', label: 'Français', model: 'Xenova/mms-tts-fra' }, + { id: 'deu', label: 'Deutsch', model: 'Xenova/mms-tts-deu' }, + { id: 'por', label: 'Português', model: 'Xenova/mms-tts-por' }, + { id: 'rus', label: 'Русский', model: 'Xenova/mms-tts-rus' }, + { id: 'ara', label: 'العربية', model: 'Xenova/mms-tts-ara' }, + { id: 'hin', label: 'हिन्दी', model: 'Xenova/mms-tts-hin' }, +];