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
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAudioUrl(attId) {
|
// 短路:内存里已有 blob URL → 同步返回;未启用 cache → 直接网络 URL 不查 IDB;
|
||||||
const cached = await getCachedBlobUrl(STORE_AUDIO, attId)
|
// 只有启用 cache 且内存没 cache 命中才掏 IDB
|
||||||
return cached || attachmentUrl(attId)
|
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) {
|
export function getImageUrl(attId) {
|
||||||
const cached = await getCachedBlobUrl(STORE_IMAGE, attId)
|
if (blobUrlCache.has(attId)) return blobUrlCache.get(attId)
|
||||||
return cached || attachmentUrl(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(
|
event.waitUntil(
|
||||||
(async () => {
|
(async () => {
|
||||||
const cache = await caches.open(CACHE)
|
const cache = await caches.open(CACHE)
|
||||||
// 串行避免一次性请求过多
|
// 并发 addAll,HTTP/2 多路复用,一次过;失败回退串行
|
||||||
|
try {
|
||||||
|
await cache.addAll(URLS)
|
||||||
|
} catch {
|
||||||
for (const u of URLS) {
|
for (const u of URLS) {
|
||||||
try {
|
try {
|
||||||
const r = await fetch(u, { cache: 'reload' })
|
const r = await fetch(u, { cache: 'reload' })
|
||||||
if (r.ok) await cache.put(u, r)
|
if (r.ok) await cache.put(u, r)
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
await self.skipWaiting()
|
await self.skipWaiting()
|
||||||
})(),
|
})(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -773,8 +773,8 @@ async function loadPiece(id) {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
const first = audioAttachments.value[0]
|
const first = audioAttachments.value[0]
|
||||||
if (first && audioEl.value) {
|
if (first && audioEl.value) {
|
||||||
// 优先用 IDB 缓存的 blob URL,没有再走网络
|
// 优先用 IDB 缓存的 blob URL(cache 关时同步返回网络 URL,零延迟)
|
||||||
audioEl.value.src = await getAudioUrl(first.id)
|
audioEl.value.src = getAudioUrl(first.id)
|
||||||
if (wasPlaying) audioEl.value.play().catch(() => {})
|
if (wasPlaying) audioEl.value.play().catch(() => {})
|
||||||
} else if (audioEl.value) {
|
} else if (audioEl.value) {
|
||||||
audioEl.value.removeAttribute('src')
|
audioEl.value.removeAttribute('src')
|
||||||
|
|||||||
Reference in New Issue
Block a user