feat(图片缓存功能): 发现单图版本参数方案更改版本号后仍命中旧图,因此取消这部分功能,仅用改图片名来更新单图片

This commit is contained in:
hzj 2026-05-15 17:57:01 +08:00
parent fd0a3a6202
commit 4746fb38c7
5 changed files with 11 additions and 62 deletions

View File

@ -80,15 +80,9 @@
- 默认最多缓存 120 张图片。
- 最大缓存体积为 80MB。
- 普通发版不更新全局缓存版本。
- 单张图片替换且不改名时,在 `assetVersions` 中给该图片加版本
- 单张图片替换时,优先上传新文件名并同步修改 H5 引用
示例:
```js
assetVersions: {
'Activities/LuckyDollars/Season6/bg0.png': '20260514',
}
```
说明:之前评估过 `assetVersions` 单图版本参数方案,但在只改 H5 和 OSS 图片、无法稳定控制 CDN/浏览器缓存链路的情况下,容易出现发布后仍命中旧图的问题,因此已取消。
### 5. 构建产物收口
@ -173,7 +167,7 @@ npm run preview
- `Activities` / `Ranking` 页面是否仍能正常展示。
- 受保护图片是否仍能正常显示。
- 运行时 DOM 和构建产物中是否更少直接暴露真实图链。
- 替换同名图片时,`assetVersions` 是否能让用户看到新图
- 替换图片后,新文件名引用是否能在用户端稳定加载
### 性能验证

View File

@ -156,23 +156,14 @@ cacheLimits: {
原因是低端机内存有限,过大的本地图片缓存会增加内存和存储管理压力。
同时新增 `assetVersions` 单图/目录版本机制:
```js
assetVersions: {
'Activities/LuckyDollars/Season6/bg0.png': '20260514',
}
```
这会让该图片 URL 自动加上 `?iv=20260514`。用户端不会继续命中旧图缓存,也不需要全量清空所有图片缓存。
曾评估过 `assetVersions` 单图/目录版本机制,让图片 URL 自动追加 `?iv=版本号`。但当前我们只能处理 H5 项目和 OSS 图片替换,无法稳定控制 CDN/浏览器缓存链路如果服务端、CDN 或 WebView 仍返回旧对象,这个功能会给维护带来误判。因此该方案已取消。
使用建议:
- 普通发版:不要改全局 `version`
- 单张图片替换且不改文件名:只在 `assetVersions` 中加或改该图片版本
- 单张图片替换:上传新文件名,并同步修改页面中的图片引用,例如 `top1RewardBg_20260515`
- 大批量图片迁移、缓存污染:才更新全局 `version`
- `updateTime` 只作为人工记录,不参与实际缓存命中逻辑,不是每次改 `assetVersions` 都必须更新。
- 单图版本不要下次发版立刻删除,至少保留超过静态资源最长缓存周期,当前建议不少于 30 天。
- `updateTime` 只作为人工记录,不参与实际缓存命中逻辑。
### 4. 图片预加载改为限流和 idle

View File

@ -1,8 +1,8 @@
// 图片缓存版本控制。
//
// 推荐用法:
// 1. 普通发保持 version 不变。
// 2. 只替换单张图片且不改文件名时,在 assetVersions 中添加对应图片版本
// 1. 普通发保持 version 不变。
// 2. 替换单张图片时,优先使用新文件名并同步修改页面引用
// 3. 只有大批量资源迁移或缓存污染时,才更新 version 触发清理旧缓存。
export const IMAGE_CACHE_VERSION = {
version: '1.0.19',
@ -10,12 +10,6 @@ export const IMAGE_CACHE_VERSION = {
updateReason: 'Initial image cache version for major release',
updateTime: '2026-05-14T00:00:00.000Z',
// 精确资源路径或目录前缀 -> 资源版本。
// 示例:
// 'Activities/LuckyDollars/Season6/bg0.png': '20260514',
// 'Activities/LuckyDollars/Season6/': 'season6-20260514',
assetVersions: {},
cacheLimits: {
maxItems: 120,
maxSizeMB: 80,

View File

@ -1,40 +1,10 @@
import { protectAssetUrl } from '@/utils/protectedAssets.js'
import { IMAGE_CACHE_VERSION } from '@/config/imageCacheVersion.js'
export const OSS_BASE_URL =
process.env.NODE_ENV === 'development' ? '/oss/h5/Azizi/' : 'https://cdn.azizichat.com/h5/Azizi/'
function buildAssetUrl(imagePath, filename, extension) {
const assetPath = `${imagePath}${filename}.${extension}`
const url = `${OSS_BASE_URL}${assetPath}`
const version = getAssetVersion(assetPath)
if (!version) {
return url
}
const separator = url.includes('?') ? '&' : '?'
return `${url}${separator}iv=${encodeURIComponent(version)}`
}
function getAssetVersion(assetPath) {
const versions = IMAGE_CACHE_VERSION.assetVersions || {}
if (versions[assetPath]) {
return versions[assetPath]
}
let bestPrefix = ''
let bestVersion = ''
Object.entries(versions).forEach(([prefix, version]) => {
if (assetPath.startsWith(prefix) && prefix.length > bestPrefix.length) {
bestPrefix = prefix
bestVersion = version
}
})
return bestVersion
return `${OSS_BASE_URL}${imagePath}${filename}.${extension}`
}
export const getRawPngUrl = (imagePath, filename) => buildAssetUrl(imagePath, filename, 'png')

View File

@ -1133,7 +1133,7 @@ const changeRanking = (type) => {
}
const topImg = ref([
imageUrl('top1RewardBg'),
imageUrl('top1RewardBg_20260515'),
imageUrl('top2_4RewardBg'),
imageUrl('top5_7RewardBg'),
imageUrl('top8_10RewardBg'),
@ -1362,7 +1362,7 @@ const preloadOtherImages = async () => {
imageUrl(getImgName('historyTopBg')),
imageUrl('historyTopFrame'),
imageUrl(getImgName('specialRewardsNew')),
imageUrl('top1RewardBg'),
imageUrl('top1RewardBg_20260515'),
imageUrl('top2_4RewardBg'),
imageUrl('top5_7RewardBg'),
imageUrl('top8_10RewardBg'),