music(perf): 切歌延迟修 — getAudioUrl 同步短路 + SW install 并发
deploy music / build-and-deploy (push) Successful in 2m4s
deploy music / build-and-deploy (push) Successful in 2m4s
诊断:之前 loadPiece 链上加了 `audio.src = await getAudioUrl(...)`,await IDB 即使 cache disabled 也排队个 microtask;叠加 SW install 串行 23 个 fetch 让首次部署后明显卡。 修法: - getAudioUrl 改同步:内存 blob 命中 / cache 关 → 立返;启用 cache 时内存没 → 仍返网络 URL,后台 warm IDB 下次用 - audio.src = getAudioUrl(id) 不再 await,零等待 - SW install 改 cache.addAll 并发(HTTP/2 多路),失败回退串行
This commit is contained in:
@@ -124,14 +124,29 @@ export async function getCachedBlobUrl(store, attId) {
|
||||
return url
|
||||
}
|
||||
|
||||
export async function getAudioUrl(attId) {
|
||||
const cached = await getCachedBlobUrl(STORE_AUDIO, attId)
|
||||
return cached || attachmentUrl(attId)
|
||||
// 短路:内存里已有 blob URL → 同步返回;未启用 cache → 直接网络 URL 不查 IDB;
|
||||
// 只有启用 cache 且内存没 cache 命中才掏 IDB
|
||||
export function getAudioUrl(attId) {
|
||||
if (blobUrlCache.has(attId)) return blobUrlCache.get(attId)
|
||||
if (!isCacheEnabled()) return attachmentUrl(attId)
|
||||
// 启用了但内存没缓存:网络立返,后台尝试 IDB 命中后下次会用上
|
||||
warmCachedBlob(STORE_AUDIO, attId)
|
||||
return attachmentUrl(attId)
|
||||
}
|
||||
|
||||
export async function getImageUrl(attId) {
|
||||
const cached = await getCachedBlobUrl(STORE_IMAGE, attId)
|
||||
return cached || attachmentUrl(attId)
|
||||
export function getImageUrl(attId) {
|
||||
if (blobUrlCache.has(attId)) return blobUrlCache.get(attId)
|
||||
if (!isCacheEnabled()) return attachmentUrl(attId)
|
||||
warmCachedBlob(STORE_IMAGE, attId)
|
||||
return attachmentUrl(attId)
|
||||
}
|
||||
|
||||
function warmCachedBlob(store, attId) {
|
||||
idbGet(store, attId).then((blob) => {
|
||||
if (blob && !blobUrlCache.has(attId)) {
|
||||
blobUrlCache.set(attId, URL.createObjectURL(blob))
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
// ---- 状态 ----
|
||||
|
||||
@@ -20,13 +20,17 @@ self.addEventListener('install', (event) => {
|
||||
event.waitUntil(
|
||||
(async () => {
|
||||
const cache = await caches.open(CACHE)
|
||||
// 串行避免一次性请求过多
|
||||
// 并发 addAll,HTTP/2 多路复用,一次过;失败回退串行
|
||||
try {
|
||||
await cache.addAll(URLS)
|
||||
} catch {
|
||||
for (const u of URLS) {
|
||||
try {
|
||||
const r = await fetch(u, { cache: 'reload' })
|
||||
if (r.ok) await cache.put(u, r)
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
await self.skipWaiting()
|
||||
})(),
|
||||
)
|
||||
|
||||
@@ -773,8 +773,8 @@ async function loadPiece(id) {
|
||||
await nextTick()
|
||||
const first = audioAttachments.value[0]
|
||||
if (first && audioEl.value) {
|
||||
// 优先用 IDB 缓存的 blob URL,没有再走网络
|
||||
audioEl.value.src = await getAudioUrl(first.id)
|
||||
// 优先用 IDB 缓存的 blob URL(cache 关时同步返回网络 URL,零延迟)
|
||||
audioEl.value.src = getAudioUrl(first.id)
|
||||
if (wasPlaying) audioEl.value.play().catch(() => {})
|
||||
} else if (audioEl.value) {
|
||||
audioEl.value.removeAttribute('src')
|
||||
|
||||
Reference in New Issue
Block a user