perf(core): 资产预览改 TOS 公读直链 + 通知只取首页,减刷新开销与缓存失效
- 资产 preview_url 从「逐图签发预签名 URL」改为虚拟主机式公读直链 (https://{bucket}.{host}/{key})。桶公读已验证免签可访问;直链稳定可被浏览器/CDN 缓存,而签名链每次都变、1h 过期反而打不到缓存。boto3 也移出序列化热路径。 - allNotifications 不再逐页翻全部(原 O(N) 随消息增长拖慢每次刷新),只取首页 100 条 (侧边栏徽标 unread_count + 团队动态仅展示最近 6 条已足够);「共 N」改用后端真实 count。 - perf-probe:page_size 由 API 级硬闸确定性守住后,浏览器端「资产翻页」降为提示 (翻 1~2 页是资产真超 200 的合法分页,仅 ≥3 页才疑似 page_size 失效)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -45,13 +45,15 @@ class AssetFileSerializer(serializers.ModelSerializer):
|
||||
]
|
||||
|
||||
def get_preview_url(self, obj):
|
||||
# 存储字段优先(如外部已写入绝对 URL);否则用 object_key 实时签发 TOS 预签名 GET URL
|
||||
# 存储字段优先(如外部已写入绝对 URL);否则用 object_key 拼 TOS 公读直链。
|
||||
# TOS 桶公读,直链(虚拟主机式)免签名、且稳定可缓存——不再逐图签发预签名 URL
|
||||
# (签名是纯本地计算但每次都变、1h 过期会打不到浏览器/CDN 缓存;直链一劳永逸)。
|
||||
if obj.preview_url:
|
||||
return obj.preview_url
|
||||
if not obj.object_key or not settings.TOS.get("endpoint"):
|
||||
return ""
|
||||
try:
|
||||
return _tos().presigned_get_url(object_key=obj.object_key)
|
||||
return _tos().public_url(object_key=obj.object_key, bucket=obj.bucket or None)
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import BinaryIO
|
||||
from urllib.parse import quote, urlparse
|
||||
|
||||
import boto3
|
||||
from botocore.config import Config
|
||||
@@ -50,3 +51,10 @@ class TosStorage:
|
||||
Params={"Bucket": self.bucket, "Key": object_key},
|
||||
ExpiresIn=expires_in,
|
||||
)
|
||||
|
||||
def public_url(self, *, object_key: str, bucket: str | None = None) -> str:
|
||||
"""桶公读时的虚拟主机式直链:https://{bucket}.{host}/{key}。
|
||||
相比预签名 URL:不签名(省 boto3 客户端/签名开销)、且 URL 稳定可被浏览器/CDN 缓存
|
||||
(签名链每次都变、1h 过期,反而打不到缓存)。仅用于公开可读的预览图。"""
|
||||
host = urlparse(settings.TOS["endpoint"]).netloc
|
||||
return f"https://{bucket or self.bucket}.{host}/{quote(object_key, safe='/')}"
|
||||
|
||||
Reference in New Issue
Block a user