perf: 头像增加缓存时间

This commit is contained in:
xiaojunnuo
2026-05-15 00:39:35 +08:00
parent 3b72ca09c6
commit 7015b1b232
6 changed files with 66 additions and 7 deletions
@@ -396,7 +396,7 @@ const userAvatar = computed(() => {
return userInfo.value.avatar;
}
return `api/basic/file/download?token=${userStore.getToken}&key=${userInfo.value.avatar}`;
return `api/basic/file/download?key=${userInfo.value.avatar}`;
});
onMounted(async () => {
@@ -0,0 +1,6 @@
export function shouldSetDefaultNoCache(path: string, cacheControl?: string) {
if (cacheControl) {
return false;
}
return path === '/' || path === '/index.html' || path.startsWith('/api');
}
@@ -0,0 +1,22 @@
/// <reference types="mocha" />
/// <reference types="node" />
import assert from "node:assert/strict";
import { shouldSetDefaultNoCache } from "./configuration-cache.js";
describe("shouldSetDefaultNoCache", () => {
it("sets default no-cache for html and api responses without cache headers", () => {
assert.equal(shouldSetDefaultNoCache("/"), true);
assert.equal(shouldSetDefaultNoCache("/index.html"), true);
assert.equal(shouldSetDefaultNoCache("/api/basic/file/download"), true);
});
it("keeps explicit cache headers from file responses", () => {
assert.equal(shouldSetDefaultNoCache("/api/basic/file/download", "public,max-age=259200"), false);
});
it("ignores non-html and non-api paths", () => {
assert.equal(shouldSetDefaultNoCache("/static/images/logo.svg"), false);
});
});
@@ -20,6 +20,7 @@ import * as commercial from '@certd/commercial-core';
import * as upload from '@midwayjs/upload';
import { setLogger } from '@certd/acme-client';
import {HiddenMiddleware} from "./middleware/hidden.js";
import { shouldSetDefaultNoCache } from './configuration-cache.js';
// import * as swagger from '@midwayjs/swagger';
//@ts-ignore
// process.env.UV_THREADPOOL_SIZE = 2
@@ -123,7 +124,7 @@ export class MainConfiguration {
this.app.getMiddleware().insertFirst(async (ctx: IMidwayKoaContext, next: NextFunction) => {
await next();
if (ctx.path === '/' || ctx.path === '/index.html' || ctx.path.startsWith("/api")) {
if (shouldSetDefaultNoCache(ctx.path, ctx.response.get('Cache-Control'))) {
ctx.response.set('Cache-Control', 'public,max-age=0');
}
});
@@ -3,7 +3,7 @@
import assert from "node:assert/strict";
import { isImageFile } from "./file-controller.js";
import { getImageDownloadOptions, isImageFile } from "./file-controller.js";
describe("FileController.isImageFile", () => {
it("detects uploaded logo image files", () => {
@@ -17,4 +17,23 @@ describe("FileController.isImageFile", () => {
assert.equal(isImageFile("data/upload/public/user/cert.pem"), false);
assert.equal(isImageFile("data/upload/public/user/logo"), false);
});
it("builds koa-send options that keep image cache headers at 3 days", () => {
const options = getImageDownloadOptions("data/upload/public/user/logo.png");
assert.equal(options?.maxage, 259200000);
const headers: Record<string, string> = {};
options?.setHeaders({
setHeader(key: string, value: string) {
headers[key] = value;
},
});
assert.equal(headers["Cache-Control"], "public,max-age=259200");
});
it("does not build cache options for non-image files", () => {
assert.equal(getImageDownloadOptions("data/upload/private/user/cert.pem"), undefined);
});
});
@@ -12,6 +12,18 @@ export function isImageFile(filePath: string) {
return imageExtSet.has(filePath.substring(filePath.lastIndexOf('.')).toLowerCase());
}
export function getImageDownloadOptions(filePath: string) {
if (!isImageFile(filePath)) {
return undefined;
}
return {
maxage: imageCacheSeconds * 1000,
setHeaders(res: any) {
res.setHeader('Cache-Control', `public,max-age=${imageCacheSeconds}`);
},
};
}
/**
*/
@Provide()
@@ -47,11 +59,10 @@ export class FileController extends BaseController {
userId = this.getUserId();
}
const filePath = this.fileService.getFile(key, userId);
if (isImageFile(filePath)) {
this.ctx.response.set('Cache-Control', `public,max-age=${imageCacheSeconds}`);
} else {
const sendOptions = getImageDownloadOptions(filePath);
if (!sendOptions) {
this.ctx.response.attachment(filePath);
}
await send(this.ctx, filePath);
await send(this.ctx, filePath, sendOptions);
}
}