Nginx 通过压缩、缓存和 HTTP/2 优化 JS 资源交付,间接缓解 JS 阻塞:启用 Gzip/Brotli 压缩减小体积;配置 expires 与 immutable 实现强缓存;升级 HTTP/2 提升并行加载效率;配合前端 async/defer 属性发挥最佳效果。

JS脚本在页面加载时引发的阻塞,本质是浏览器默认同步解析执行造成的,Nginx 本身不执行 JS,也不控制脚本执行顺序,但它可以通过优化资源交付方式,间接缓解因 JS 加载慢、未合理分发导致的“伪阻塞”问题。关键在于让 JS 更快、更合理地到达浏览器,并配合前端策略(如 async 或 defer)协同生效。
启用 Gzip/Brotli 压缩,减小 JS 文件体积
传输体积越小,下载越快,阻塞窗口自然缩短。Nginx 支持 Gzip(广泛兼容)和 Brotli(压缩率更高,需编译支持)。
示例配置(Gzip):
gzip on; gzip_types application/javascript text/css text/xml; gzip_min_length 1024; gzip_comp_level 6; gzip_vary on;
- 确保
application/javascript在gzip_types中,否则 .js 文件不会被压缩 -
gzip_vary on让 CDN 或代理知道响应可能因 Accept-Encoding 不同而不同,避免缓存错乱 - Brotli 需额外模块(
ngx_brotli),启用后可与 Gzip 共存,优先返回 Brotli(需客户端支持)
设置合理的缓存头,复用已加载的 JS
避免重复请求同一 JS 文件,尤其对长期不变的第三方库或打包后的 vendor.js,强缓存能彻底消除后续加载耗时。
示例配置(按文件后缀区分缓存策略):
location ~* \.js$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
-
expires 1y发送Expires和Cache-Control: max-age=31536000 -
immutable告诉浏览器该资源在过期前绝不会变,可跳过条件请求(如 If-None-Match),进一步提速 - 注意:仅适用于带哈希指纹的文件(如
app.a1b2c3.js),否则更新后用户可能无法获取新版本
启用 HTTP/2,提升多 JS 并行加载效率
HTTP/1.1 下多个 JS 会排队或受限于域名并行连接数(通常 6 个),HTTP/2 的多路复用可让多个 <script> 请求共享一个 TCP 连接,无队头阻塞。
启用前提:Nginx ≥ 1.9.5 + TLS(HTTP/2 只在 HTTPS 下生效)
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# ... 其他 SSL 配置
}
- 确认 Nginx 编译时启用了
--with-http_v2_module - 搭配
ssl_buffer_size 4k等调优参数可进一步改善首屏 JS 加载延迟 - 浏览器开发者工具 Network 标签页中,Protocol 列显示
h2即表示生效
配合前端:Nginx 不替代 async/defer,但可保障其效果
Nginx 无法改变 HTML 中 script 标签的解析行为,但若 JS 文件本身加载缓慢(如未压缩、无缓存、走 HTTP/1.1),即使写了 async,也会因网络延迟拉长整体等待时间。
- 关键 JS(如首屏依赖)建议用
<script defer src="main.js">,确保 DOM 解析完成后再执行 - 非关键 JS(如统计、埋点)用
<script async src="analytics.js">,下载不阻塞,执行时机不可控 - Nginx 的压缩、缓存、HTTP/2 都是在为这些属性“托底”——让 async/defer 真正跑得起来,而不是卡在下载阶段










