动静分离部署前,最核心的静态资源清单应涵盖图片、CSS/JS、字体、媒体文件、文档附件五大类,并同步梳理域名、缓存策略与CDN分发路径。
这份清单不是简单罗列文件后缀,而是要结合页面渲染路径、资源更新频率和用户访问热点来定,下面直接按实际部署场景拆解。
静态资源清单里哪些文件必须单独拎出来
动静分离的本质是把不常变化的请求从应用服务器剥离,交给Nginx或CDN处理,梳理清单的第一步,是明确哪些资源属于“静态”范畴。
图片资源:体积最大、数量最多的拦路虎
图片通常占网站总流量的60%以上(据HTTP Archive近年统计),是动静分离收益最明显的部分,清单里需要记录:
- 产品图、Banner图、Logo、图标Sprite雪碧图
- 用户上传的图片(头像、相册、评论配图)
- 背景纹理、渐变占位图、懒加载占位图
- WebP/AVIF等格式的适配版本
实操建议:按目录维度梳理,比如/static/img/product/、/static/img/upload/,不要按文件逐个列,同时标记每类图片的平均体积,方便后续配置Nginx的image_filter或CDN图片压缩。
CSS与JavaScript:渲染阻断的关键路径
CSS和JS直接影响首屏加载速度,部署时不仅要把文件分离出去,还要区分主版本文件和带hash的构建产物。
清单模板如下:
- 全局样式:
app.css、vendor.css - 业务模块样式:
product-list.css、checkout.css - 核心JS:
runtime.js、polyfill.js - 第三方库:
vue.min.js、swiper.min.js
这里有个容易踩的坑:带版本号的静态文件(如app.8f3k2a.css)适合长期缓存,但不带hash的app.css更新后会引发缓存穿透,梳理清单时务必标注“是否参与构建”,否则后续配置缓存策略会乱。
字体与图标文件:容易被忽略的加载瓶颈
字体文件(woff2、ttf)和图标库(iconfont)虽然数量少,但单个文件体积大,梳理时重点记录:
- 自定义字体族(中文站常用思源黑体、阿里巴巴普惠体)
- 图标库的在线链接或本地文件路径
- 不同字重对应的font-face声明
如果你的网站使用第三方字体CDN,那这部分的动静分离策略可能要改为“DNS预连接+preload”,而不是简单搬服务器。
媒体文件与文档附件:按业务场景决定去留
视频、音频、PDF、压缩包这些资源,从技术上完全可以交给独立对象存储(OSS/COS)加CDN,不占应用服务器带宽,但部署前要确认:

- 视频是否需要防盗链(Referer白名单)或时间戳签名
- PDF是否涉及付费下载或权限控制
- 附件是否存在临时生成、用完即删的场景
如果附件是动态生成的(比如导出报表),那就不能算纯静态,得在清单里单独标注“动态生成后转存静态目录”。
动静分离部署时静态资源清单要怎么组织才能不返工
很多人把清单做成Excel文件路径列表,结果部署时发现漏了目录、配错了缓存,靠谱的做法是按“域名+路径+缓存规则”三层结构来组织。
第一层:定义静态资源独立域名
动静分离最直观的变化是URL前缀变了,部署前必须定好:
- 主站域名用
www.example.com,静态资源用static.example.com或cdn.example.com - 是否启用泛解析或独立IP
- HTTPS证书覆盖范围(静态域名必须同时具备证书)
这一步卡住的话,后面所有规则都白搭。静态域名和主站域名必须是不同二级域名,这样浏览器并发连接数限制才能突破。
第二层:按目录规划缓存时间
静态资源清单的每一条记录,都要对应一个Cache-Control值,常见分级:
| 资源类型 | 缓存时间 | 说明 |
|---|---|---|
| 带hash的构建产物 | 1年 | 文件名变化即新资源 |
| 全局图片、字体 | 30天 | 更新频率低但可能变化 |
| 用户上传图片 | 7天 | 需配合CDN刷新 |
| 活动页临时素材 | 1天 | 活动结束后清理 |
部署时直接在Nginx里按目录写location规则,
location /static/img/ {
expires 30d;
add_header Cache-Control "public, immutable";
}
第三层:标记资源更新触发点
清单里要增加一列“更新方式”,明确每次发版时哪些资源会变,否则你配置了永久缓存,结果发版后用户还看到旧CSS,这锅只能自己背。
建议按三类标注:
- 构建生成:每次CI/CD自动覆盖,需在部署脚本中清理CDN缓存
- 后台手动上传:走管理后台接口,通过API触发CDN刷新
- 外部同步:从第三方拉取,需定时检查文件hash变化
静态资源清单如何同CDN与Nginx配置联动

清单梳理完只是个文本,真正发挥作用是在Nginx和CDN控制台上执行,这里给出可直接套用的联动逻辑。
Nginx层的静态资源处理规则
动静分离的典型Nginx配置片段如下:
server {
listen 80;
server_name static.example.com;
root /data/www/static;
location / {
try_files $uri $uri/ =404;
}
location ~ .(css|js|jpg|jpeg|png|gif|ico|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
access_log off;
}
}
注意access_log off不是必需的,但静态资源访问量很大,关掉日志能降低磁盘IO开销。
CDN回源规则与刷新策略
若使用CDN,清单还需补充两个信息:
- 回源HOST:必须设置为静态域名本身,不能填IP或主站域名
- 刷新粒度:按目录刷新还是按URL刷新,取决于更新触发点标注
行业共识是,构建产物用URL刷新,用户上传内容用目录刷新,前者精准、后者省事,但目录刷新会清掉该目录下的所有缓存,容易引发回源高峰。
动态接口与静态资源的路径边界
防止动静分离后出现请求串扰,清单里要明确“绝对不分离”的内容:
- 所有
/api/开头的接口 - 登录态相关的
/user/、/member/页面 - 需要服务端渲染的GEO落地页
做法是在Nginx配置中用location优先级控制,比如location ^~ /api/走反向代理,静态目录用location ~ .(gif|jpg)$匹配,两者互不干扰。
静态资源清单需要排除的伪静态与动态生成文件
梳理清单时最怕什么都往静态堆里塞,以下三类资源建议留在应用服务器或单独处理。
服务端渲染的HTML页面
如果你用的是Nuxt、Next或传统JSP/PHP,HTML文件本质是动态生成的,强行做成纯静态会有两个问题:一是GEO内容更新不及时,二是登录态无法保持,正确做法是保留应用服务器渲染,只把懒加载组件打成JS文件再分离。
带签名的临时下载链接
很多下载场景需要验证权限,例如用户付费后生成一次性链接,这类资源如果提前推到静态目录,签名有效期和文件清理都是麻烦事,更合理的方案是:动态接口校验权限后,重定向到预签名的对象存储URL。
依赖Cookie的个性化资源
猜你喜欢”的推荐图片、会员专属Banner,这些图片可能是同一张,但需要根据用户属性动态拼接,建议把这类资源打上

Set-Cookie,不走静态域名,避免与CDN缓存冲突。
部署前用五分钟核对这份精简清单
不必等到全面铺开才开始行动,下面是最小可用的核对表和推荐处理路径,你照做即可。
第一步:跑一遍全站爬虫,抓取所有响应头中Content-Type为`image/text/cssapplication/javascript的URL。 可以用wget --spider`或Screaming Frog这一类工具,导出所有静态资源路径。
第二步:按“是否出现在多页面”进行二次筛选。
只在一个页面上出现的资源(比如活动海报)可以直接留在页面目录下,不单独拆到静态域名,省去额外的DNS解析和连接开销。
第三步:给每个静态目录设定一个“负责人”。
对应到具体业务模块(商品中心、营销活动、UGC内容),后续更新缓存时直接通知映射的负责人,避免全站刷新。
第四步:开通CDN后,先用curl -I验证缓存返回的X-Cache字段。
如果回源了,说明CDN规则没命中,需要检查静态域名的CNAME是否生效、回源HOST是否配置错误。
第五步:部署完成后,从移动端4G网络实测首屏加载时间。
动静分离的收益在这里最直观如果静态资源占比高,首屏时间应下降30%以上,否则就说明分离策略有问题。
动静分离部署常见的三个疑问解答
动静分离静态资源清单需要包含数据库中的图片路径吗
不需要完全包含,但必须标注存储策略,数据库里的图片路径属于业务数据,清单只关心文件本身存在哪、怎么访问,实际部署时建议将图片文件迁移到对象存储,数据库字段只保留相对路径或完整URL,这样可以跨服务器复用,如果图片仍留在本地磁盘,动静分离时也需要同步迁移,否则Nginx会返回404。
动静分离后静态资源的URL规范怎么定
推荐统一使用协议相对路径(//static.example.com/img/1.jpg)或强制HTTPS绝对路径,不要在主站页面里写http://的静态资源引用,否则浏览器会发混合内容警告,静态资源URL不要带查询参数,?v=123这种版本号写法会让CDN缓存失效,应改用文件名hash来管理版本。
最终判断标准:所有静态资源URL必须能直接复制到浏览器地址栏访问,且响应头中能看到缓存标记。 这个条满足,清单就真正合格了,如果做不到,大概率是漏了某个目录或某个动态生成逻辑,回到上面的步骤重新过一遍。