优化pagetype列表页缓存机制

This commit is contained in:
jingrow 2025-11-01 15:14:07 +08:00
parent e57ee5189d
commit 589640baa7

View File

@ -291,46 +291,125 @@ const cardBadges = computed(() => {
const metaFields = ref<any[]>([])
const linkTitleCache = ref<Record<string, string>>({})
const pageTypeConfigCache = ref<Record<string, any>>({})
const cacheAccessOrder = ref<string[]>([]) // 访LRU
let saveCacheTimer: ReturnType<typeof setTimeout> | null = null
const CACHE_EXPIRY_DAYS = 7 //
const MAX_CACHE_SIZE = 500 //
// localStorage
function loadCacheFromStorage() {
try {
const cached = localStorage.getItem(`linkTitleCache:${entity.value}`)
const cached = localStorage.getItem('linkTitleCache')
if (cached) {
const parsed = JSON.parse(cached)
//
Object.keys(parsed).forEach(key => {
if (!linkTitleCache.value[key]) {
linkTitleCache.value[key] = parsed[key]
}
})
const { data, timestamp } = parsed
//
const now = Date.now()
const expiryTime = CACHE_EXPIRY_DAYS * 24 * 60 * 60 * 1000
if (timestamp && now - timestamp < expiryTime && data) {
//
Object.keys(data).forEach(key => {
if (!linkTitleCache.value[key]) {
linkTitleCache.value[key] = data[key]
// 访
if (!cacheAccessOrder.value.includes(key)) {
cacheAccessOrder.value.push(key)
}
}
})
}
}
} catch (error) {
console.error('加载缓存失败:', error)
}
}
// localStorage
// 访LRU
function updateCacheWithLRU(key: string, value: string) {
// 访
if (linkTitleCache.value[key]) {
const index = cacheAccessOrder.value.indexOf(key)
if (index > -1) {
cacheAccessOrder.value.splice(index, 1)
}
}
// 使
if (cacheAccessOrder.value.length >= MAX_CACHE_SIZE && !linkTitleCache.value[key]) {
const oldestKey = cacheAccessOrder.value.shift()
if (oldestKey) {
delete linkTitleCache.value[oldestKey]
}
}
// /
linkTitleCache.value[key] = value
cacheAccessOrder.value.push(key)
}
// localStorage
function saveCacheToStorage() {
if (saveCacheTimer) {
clearTimeout(saveCacheTimer)
}
saveCacheTimer = setTimeout(() => {
try {
// 1000
const cacheEntries = Object.entries(linkTitleCache.value)
if (cacheEntries.length > 1000) {
// 1000
const recentEntries = cacheEntries.slice(-1000)
linkTitleCache.value = Object.fromEntries(recentEntries)
saveCacheImmediately()
}, 500) // 500ms
}
//
function saveCacheImmediately() {
if (saveCacheTimer) {
clearTimeout(saveCacheTimer)
saveCacheTimer = null
}
try {
// 访
if (cacheAccessOrder.value.length > MAX_CACHE_SIZE) {
const toRemove = cacheAccessOrder.value.slice(0, cacheAccessOrder.value.length - MAX_CACHE_SIZE)
toRemove.forEach(key => {
delete linkTitleCache.value[key]
})
cacheAccessOrder.value = cacheAccessOrder.value.slice(-MAX_CACHE_SIZE)
}
//
localStorage.setItem('linkTitleCache', JSON.stringify({
data: linkTitleCache.value,
timestamp: Date.now()
}))
} catch (error) {
//
if (error instanceof DOMException && error.code === 22) {
try {
localStorage.removeItem('linkTitleCache')
// 100
const recentKeys = cacheAccessOrder.value.slice(-100)
const recentCache: Record<string, string> = {}
recentKeys.forEach(key => {
recentCache[key] = linkTitleCache.value[key]
})
localStorage.setItem('linkTitleCache', JSON.stringify({
data: recentCache,
timestamp: Date.now()
}))
linkTitleCache.value = recentCache
cacheAccessOrder.value = recentKeys
} catch (e) {
console.error('保存缓存失败:', e)
}
localStorage.setItem(`linkTitleCache:${entity.value}`, JSON.stringify(linkTitleCache.value))
} catch (error) {
} else {
console.error('保存缓存失败:', error)
}
saveCacheTimer = null
}, 1000) // 1
}
}
//
if (typeof window !== 'undefined') {
window.addEventListener('beforeunload', saveCacheImmediately)
window.addEventListener('pagehide', saveCacheImmediately)
}
async function loadMeta() {
@ -410,7 +489,7 @@ async function preloadLinkTitles() {
recordNames.forEach(name => {
const cacheKey = `${pagetype}_${name}`
if (!linkTitleCache.value[cacheKey]) {
linkTitleCache.value[cacheKey] = name
updateCacheWithLRU(cacheKey, name)
}
})
return
@ -438,20 +517,20 @@ async function preloadLinkTitles() {
withCredentials: true
})
//
// 使LRU
const records = result.data?.data || []
records.forEach((record: any) => {
const name = record.name
const titleValue = record[titleField] || name
const cacheKey = `${pagetype}_${name}`
linkTitleCache.value[cacheKey] = titleValue
updateCacheWithLRU(cacheKey, titleValue)
})
// API
namesToLoad.forEach(name => {
const cacheKey = `${pagetype}_${name}`
if (!linkTitleCache.value[cacheKey]) {
linkTitleCache.value[cacheKey] = name
updateCacheWithLRU(cacheKey, name)
}
})
@ -463,7 +542,7 @@ async function preloadLinkTitles() {
namesToLoad.forEach(name => {
const cacheKey = `${pagetype}_${name}`
if (!linkTitleCache.value[cacheKey]) {
linkTitleCache.value[cacheKey] = name
updateCacheWithLRU(cacheKey, name)
}
})
}