wip: optimizations
This commit is contained in:
@@ -35,15 +35,23 @@ export const DEFAULT_VOICE_SETTINGS: VoiceSettings = {
|
||||
};
|
||||
|
||||
export function loadVoiceSettingsFromStorage(): VoiceSettings {
|
||||
if (cachedSettings) {
|
||||
return { ...cachedSettings };
|
||||
}
|
||||
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY_VOICE_SETTINGS);
|
||||
|
||||
if (!raw)
|
||||
return { ...DEFAULT_VOICE_SETTINGS };
|
||||
if (!raw) {
|
||||
cachedSettings = { ...DEFAULT_VOICE_SETTINGS };
|
||||
return { ...cachedSettings };
|
||||
}
|
||||
|
||||
return normaliseVoiceSettings(JSON.parse(raw) as Partial<VoiceSettings>);
|
||||
cachedSettings = normaliseVoiceSettings(JSON.parse(raw) as Partial<VoiceSettings>);
|
||||
return { ...cachedSettings };
|
||||
} catch {
|
||||
return { ...DEFAULT_VOICE_SETTINGS };
|
||||
cachedSettings = { ...DEFAULT_VOICE_SETTINGS };
|
||||
return { ...cachedSettings };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,11 +61,60 @@ export function saveVoiceSettingsToStorage(patch: Partial<VoiceSettings>): Voice
|
||||
...patch
|
||||
});
|
||||
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY_VOICE_SETTINGS, JSON.stringify(nextSettings));
|
||||
} catch {}
|
||||
cachedSettings = nextSettings;
|
||||
schedulePersist(nextSettings);
|
||||
|
||||
return nextSettings;
|
||||
return { ...nextSettings };
|
||||
}
|
||||
|
||||
let cachedSettings: VoiceSettings | null = null;
|
||||
let pendingSettings: VoiceSettings | null = null;
|
||||
let persistScheduled = false;
|
||||
|
||||
function schedulePersist(settings: VoiceSettings): void {
|
||||
pendingSettings = settings;
|
||||
|
||||
if (persistScheduled) {
|
||||
return;
|
||||
}
|
||||
|
||||
persistScheduled = true;
|
||||
|
||||
const runner = (): void => {
|
||||
persistScheduled = false;
|
||||
|
||||
if (!pendingSettings) {
|
||||
return;
|
||||
}
|
||||
|
||||
const toPersist = pendingSettings;
|
||||
|
||||
pendingSettings = null;
|
||||
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY_VOICE_SETTINGS, JSON.stringify(toPersist));
|
||||
} catch {
|
||||
// ignore quota / privacy errors
|
||||
}
|
||||
};
|
||||
|
||||
type IdleCallbackHandle = number;
|
||||
interface IdleDeadline {
|
||||
didTimeout: boolean;
|
||||
timeRemaining(): number;
|
||||
}
|
||||
type IdleRequest = (cb: (deadline: IdleDeadline) => void, opts?: { timeout: number }) => IdleCallbackHandle;
|
||||
interface MaybeIdleGlobal {
|
||||
requestIdleCallback?: IdleRequest;
|
||||
}
|
||||
|
||||
const idleGlobal = (typeof globalThis === 'undefined' ? {} : globalThis) as MaybeIdleGlobal;
|
||||
|
||||
if (typeof idleGlobal.requestIdleCallback === 'function') {
|
||||
idleGlobal.requestIdleCallback(() => runner(), { timeout: 1000 });
|
||||
} else {
|
||||
setTimeout(runner, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function normaliseVoiceSettings(raw: Partial<VoiceSettings>): VoiceSettings {
|
||||
|
||||
Reference in New Issue
Block a user