← 返回题目列表

Tomcat 怎么处理静态资源?GZIP 压缩是怎么回事、有什么用?

简单 第 17 / 23 题 更新于 2026/07/28
静态资源GZIP压缩Tomcat性能

简化版

静态资源(HTML、CSS、JS、图片、字体等不变的文件)和 GZIP 压缩,是 Web 性能优化的两个基础话题。静态资源处理——Tomcat 有一个内置的 DefaultServlet 负责处理静态资源(读文件、返回、支持缓存头如 Last-Modified/ETag、支持 range 断点续传);但生产环境通常不让 Tomcat 处理静态资源,而是交给 Nginx/CDN——因为 Nginx 处理静态文件更高效、还能做缓存和 CDN 加速,让 Tomcat 专注处理动态请求。② GZIP 压缩——把响应体(文本类如 HTML/CSS/JS/JSON)用 GZIP 算法压缩后再传,能大幅减小传输体积(文本压缩率常达 70%~90%),加快传输、省带宽;工作方式:客户端请求头带 Accept-Encoding: gzip(表示我支持 gzip),服务端压缩响应、加 Content-Encoding: gzip 头,客户端解压。Tomcat 配置 GZIP:Connector 上配 compression="on" + 压缩的类型/最小大小。注意:GZIP 只压缩文本(HTML/CSS/JS/JSON),不压缩已经压缩过的(图片 JPG/PNG、视频、zip)(再压没意义、反而浪费 CPU);且压缩有 CPU 开销(用带宽换 CPU)。核心:静态资源用 DefaultServlet(生产常交给 Nginx/CDN),GZIP 压缩文本响应减小体积(客户端 Accept-Encoding 协商、只压文本、CPU 换带宽)。

详细版

GZIP 压缩的协商流程

客户端 → 请求头:Accept-Encoding: gzip, deflate, br   ← 我支持这些压缩
服务端 → 判断:响应是文本、支持 gzip、大小够大 → 压缩
服务端 → 响应头:Content-Encoding: gzip              ← 我用了 gzip
       → 响应体:<gzip 压缩后的数据>
客户端 → 解压(看到 Content-Encoding: gzip 就解压)
<!-- Tomcat 配置 GZIP(server.xml Connector)-->
<Connector port="8080"
    compression="on"                    // 开启压缩
    compressionMinSize="2048"           // 大于 2KB 才压(小的压了没意义)
    noCompressionUserAgents="gozilla"   // 某些 UA 不压
    compressibleMimeType="text/html,text/css,application/javascript,application/json" />
    <!-- 只压这些文本类型 -->
# Spring Boot 配置 GZIP(application.properties)
server.compression.enabled=true
server.compression.mime-types=text/html,text/css,application/javascript,application/json
server.compression.min-response-size=2048

⚠️ GZIP 压缩的关键原则是「只压该压的、压该压的场景」——用 CPU 开销换带宽/传输速度,用错了反而更糟只压文本类(HTML、CSS、JS、JSON、XML 等)——文本有大量重复字符,压缩率高(常压到原来的 10%~30%);绝对不要压已经压缩过的二进制(JPG/PNG/GIF 图片、MP4 视频、zip/gz 文件)——它们已经是压缩格式,再用 GZIP 压不但几乎没效果、还白白消耗 CPU(甚至可能变大)。设置最小压缩大小(如 2KB)——太小的响应压缩的收益还不够压缩本身的开销(协商、压缩、加头)。权衡:GZIP 是「用 CPU 换带宽」——压缩要消耗服务端 CPU、解压要消耗客户端 CPU,但换来的是传输体积大幅减小、传输更快、省带宽;对文本响应通常划算(带宽是瓶颈、CPU 富余)。现代还有更好的压缩算法 Brotli(br)——压缩率比 GZIP 更高,很多 CDN/Nginx 支持。生产中静态资源+压缩通常在 Nginx/CDN 层做(更高效),Tomcat 只处理动态请求。

完整版教学

一、Tomcat 处理静态资源

先理解 Tomcat 怎么处理静态资源:

静态资源:不变的文件——HTML、CSS、JS、图片、字体、视频等
  (相对"动态请求":需要程序处理、生成响应的)

Tomcat 处理静态资源——DefaultServlet:
  Tomcat 有一个内置的 DefaultServlet(在 web.xml 里映射到 /)
  → 负责处理静态资源请求(读文件、返回)
  功能:
    ① 读取静态文件、返回
    ② 支持缓存头:Last-Modified、ETag
       → 浏览器缓存,没变返回 304 Not Modified(省流量)
    ③ 支持 Range 请求(断点续传、视频拖动)
    ④ 目录列表(可配置)

缓存机制(静态资源优化):
  Last-Modified:文件最后修改时间
    → 浏览器带 If-Modified-Since,没变返回 304
  ETag:文件的标识(如内容 hash)
    → 浏览器带 If-None-Match,没变返回 304
  Cache-Control/Expires:缓存时长
    → 浏览器直接用缓存,不请求服务端

生产的做法(不让 Tomcat 处理静态资源):
  ★ 通常交给 Nginx / CDN 处理静态资源
  原因:
    ① Nginx 处理静态文件更高效(专门优化的)
    ② CDN 就近分发(用户从最近的节点拿,快)
    ③ 让 Tomcat 专注动态请求(别占 Tomcat 的线程/资源)
  → 静态资源 Nginx/CDN、动态请求 Tomcat

所以 Tomcat 用 DefaultServlet 处理静态资源,但生产常交给 Nginx/CDN

Tomcat 处理静态资源——内置 DefaultServlet(映射到 /,处理静态资源请求),功能:读文件返回、支持缓存头(Last-Modified/ETag,没变返回 304 省流量)、支持 Range 请求(断点续传/视频拖动)、目录列表。缓存机制:Last-Modified(+If-Modified-Since)、ETag(+If-None-Match)、Cache-Control(缓存时长)。生产做法:通常交给 Nginx/CDN(Nginx 处理静态文件更高效、CDN 就近分发快、让 Tomcat 专注动态请求)。理解「Tomcat 用 DefaultServlet 处理静态资源(读文件+缓存头 Last-Modified/ETag 返回 304+Range 断点续传);生产常交给 Nginx/CDN(更高效+就近分发+Tomcat 专注动态)」,就掌握了 Tomcat 处理静态资源。

二、GZIP 压缩是什么

理解 GZIP 压缩:

GZIP 压缩:
  把响应体用 GZIP 算法压缩后再传输
  → 减小传输体积、加快传输、省带宽

为什么压缩有用:
  文本类响应(HTML、CSS、JS、JSON)有大量重复内容
  → 压缩率高(常压到原来的 10%~30%)
  例:100KB 的 JS 文件,GZIP 后可能只有 20~30KB
  → 传输更快、省带宽

压缩率(文本):
  HTML/CSS/JS/JSON:压缩率高(70%~90% 减小)
  → 因为文本有很多重复字符、空格、关键字

工作原理(协商):
  ① 客户端请求头:Accept-Encoding: gzip
     → 告诉服务端"我支持 gzip 解压"
  ② 服务端判断:响应是文本、支持 gzip、够大 → 压缩响应
  ③ 服务端响应头:Content-Encoding: gzip
     → 告诉客户端"响应用了 gzip"
  ④ 客户端解压:看到 Content-Encoding: gzip → 解压

  → 协商:客户端说支持、服务端压缩并声明、客户端解压

代价(用 CPU 换带宽):
  ① 服务端压缩要 CPU
  ② 客户端解压要 CPU
  → 换来传输体积减小、传输更快、省带宽
  → 通常划算(带宽是瓶颈、CPU 富余)

所以 GZIP = 压缩文本响应减小体积(协商、Content-Encoding、CPU 换带宽)

GZIP 压缩——把响应体用 GZIP 算法压缩后传输(减小体积、加快传输、省带宽)。为什么有用:文本类响应有大量重复内容、压缩率高(常压到原来 10%~30%)(100KB JS 可能压到 20~30KB)。工作原理(协商)① 客户端请求头 Accept-Encoding: gzip(我支持解压)→ ② 服务端判断是文本/支持/够大就压缩 → ③ 响应头 Content-Encoding: gzip(我用了 gzip)→ ④ 客户端解压代价(用 CPU 换带宽):压缩/解压要 CPU、换传输体积减小(通常划算,带宽瓶颈、CPU 富余)。理解「GZIP 压缩文本响应减小体积;文本压缩率高(10%~30%);协商:客户端 Accept-Encoding: gzip→服务端压缩+Content-Encoding: gzip→客户端解压;代价 CPU 换带宽通常划算」,就掌握了 GZIP 压缩。

三、只压该压的

GZIP 有个关键原则——「只压该压的」:

只压文本类(该压的):
  HTML、CSS、JS、JSON、XML、SVG、纯文本
  → 有大量重复、压缩率高(该压)

绝对不压已压缩的(不该压的):
  ① 图片:JPG、PNG、GIF、WebP(已经是压缩格式)
  ② 视频:MP4、WebM(已压缩)
  ③ 压缩包:zip、gz、rar
  ④ 其他二进制压缩格式
  → 它们已经压过了,再 GZIP:
    - 几乎没效果(压不动)
    - 白白消耗 CPU(压缩开销)
    - 甚至可能变大(压缩头开销)
  → 绝对不要压!

设置最小压缩大小:
  太小的响应不压(如小于 1~2KB)
  → 小响应压缩的收益 < 压缩本身的开销(协商、压缩、加头)
  compressionMinSize=2048(2KB)

配置压缩的类型(白名单):
  compressibleMimeType="text/html,text/css,application/javascript,
                        application/json,..."
  → 只压这些类型(文本类)
  → 图片视频等不在列表(不压)

所以只压文本、大于阈值的,别压已压缩的和太小的

GZIP 的关键原则「只压该压的」:只压文本类(HTML/CSS/JS/JSON/XML/SVG,有大量重复、压缩率高)绝对不压已压缩的(图片 JPG/PNG、视频 MP4、压缩包 zip——已压过、再 GZIP 几乎没效果+白耗 CPU+可能变大)设置最小压缩大小(太小的不压,小响应收益<压缩开销,compressionMinSize=2048)。配置压缩类型白名单compressibleMimeType 只压文本类)。理解「只压该压的:压文本类(HTML/CSS/JS/JSON 压缩率高)、绝对不压已压缩的(图片/视频/压缩包,再压没效果+白耗 CPU+可能变大)、设最小压缩大小(太小不压)、配压缩类型白名单」,就掌握了这个关键原则。

四、Tomcat 配置 GZIP

理解 Tomcat 怎么配 GZIP:

Tomcat 配 GZIP(server.xml Connector):
  <Connector port="8080"
    compression="on"                  // 开启(on/off/force)
    compressionMinSize="2048"         // 最小压缩大小(字节)
    compressibleMimeType="text/html,text/css,application/javascript,
                          application/json,application/xml"  // 压的类型
    noCompressionUserAgents="..." />  // 某些 UA 不压

关键参数:
  compression:
    on:满足条件才压(推荐)
    force:强制压(不判断,一般不用)
    off:不压
  compressionMinSize:最小压缩大小(小的不压)
  compressibleMimeType:压缩的 MIME 类型(文本类白名单)

Spring Boot 配置(内嵌 Tomcat):
  server.compression.enabled=true
  server.compression.mime-types=text/html,text/css,application/javascript,
                                application/json
  server.compression.min-response-size=2048

生产的做法(GZIP 在哪做):
  ① Tomcat 直接压(配 Connector)
  ② 在 Nginx/CDN 压(gzip on; gzip_types ...)
     → 常见:Nginx 处理静态资源 + 压缩、Tomcat 处理动态
     → 或 CDN 压缩缓存
  → 生产常在 Nginx/网关层做压缩(更高效、集中管理)

所以 Tomcat 配 GZIP:compression=on + minSize + compressibleMimeType
  生产常在 Nginx/CDN 做

Tomcat 配 GZIP(server.xml Connector):compression="on"(开启)、compressionMinSize(最小压缩大小)、compressibleMimeType(压的文本类型白名单)。关键参数:compression(on 满足条件才压/force 强制/off 不压)、compressionMinSizecompressibleMimeTypeSpring Bootserver.compression.enabled+mime-types+min-response-size生产做法:Tomcat 直接压或在 Nginx/CDN 压(常见 Nginx 处理静态资源+压缩、Tomcat 处理动态)。理解「Tomcat 配 GZIP:compression=on+compressionMinSize+compressibleMimeType(文本类白名单);Spring Boot server.compression.*;生产常在 Nginx/CDN 做压缩(更高效)」,就掌握了 Tomcat 配 GZIP。

五、其他压缩与优化

理解其他压缩算法和优化:

其他压缩算法:
  ① GZIP:最通用、支持最广
  ② Brotli(br):Google 出的,压缩率比 GZIP 更高(10%~20% 更小)
     → 很多 CDN/Nginx 支持,现代浏览器支持
     → Accept-Encoding: br
  ③ deflate:较老,用得少

静态资源的其他优化(配合压缩):
  ① 缓存(Cache-Control、ETag)——浏览器缓存,不重复请求
  ② CDN——就近分发、边缘缓存
  ③ 合并/压缩资源(构建时 minify JS/CSS)——减小文件本身
  ④ 图片优化(WebP、懒加载、响应式图片)
  ⑤ HTTP/2(多路复用、头压缩)

压缩 vs minify(区分):
  minify(构建时):去掉 JS/CSS 的空格、注释、缩短变量名
    → 减小文件本身(源文件层面)
  GZIP(传输时):传输时压缩
    → 减小传输体积(传输层面)
  → 两者配合:minify 后的文件再 GZIP(都用)

现代前端优化的完整链路:
  minify(构建)→ 静态资源放 CDN → CDN 压缩(GZIP/Brotli)+ 缓存
  → 用户从 CDN 就近拿压缩后的文件(快)

所以除 GZIP 还有 Brotli(压缩率更高)、配合缓存/CDN/minify/HTTP2 优化

其他压缩和优化:其他压缩算法(GZIP 最通用、Brotli/br 压缩率更高 CDN 支持、deflate 较老)静态资源其他优化(缓存 Cache-Control/ETag、CDN 就近分发、minify 减小文件本身、图片优化 WebP、HTTP/2)压缩 vs minify:minify(构建时去空格注释减小文件本身)、GZIP(传输时压缩减小传输体积)——两者配合。现代前端优化链路:minify→CDN→CDN 压缩+缓存。理解「其他压缩:GZIP 通用/Brotli 压缩率更高/deflate 老;优化:缓存/CDN/minify/图片/HTTP2;压缩(传输)vs minify(构建减小文件本身)配合;现代链路 minify→CDN 压缩+缓存」,就掌握了其他压缩与优化。

六、实践与总结

总结静态资源和 GZIP 的实践:

静态资源实践:
  ① 生产静态资源交给 Nginx/CDN(Tomcat 专注动态)
  ② 用缓存头(Cache-Control、ETag、Last-Modified)
  ③ CDN 就近分发

GZIP 实践:
  ① 开启 GZIP 压缩文本响应(HTML/CSS/JS/JSON)
  ② 只压文本、别压已压缩的(图片/视频/压缩包)
  ③ 设最小压缩大小(如 2KB)
  ④ 生产常在 Nginx/CDN 层做压缩
  ⑤ 考虑 Brotli(压缩率更高)

配置位置的选择:
  Tomcat 直接配(compression):简单、内嵌场景
  Nginx/CDN 配:生产常见(更高效、集中管理、配合缓存)
  → 有 Nginx/CDN 就在那层做(压缩 + 缓存 + 静态资源)

核心总结:
  静态资源:Tomcat 用 DefaultServlet(缓存头/Range),生产交给 Nginx/CDN
  GZIP:压缩文本响应减小体积(客户端 Accept-Encoding 协商、Content-Encoding)
  只压文本(HTML/CSS/JS/JSON)、别压已压缩的(图片/视频)、设最小大小
  用 CPU 换带宽,生产常在 Nginx/CDN 做,Brotli 压缩率更高

静态资源实践:生产交给 Nginx/CDN、用缓存头、CDN 就近分发。GZIP 实践:开启压缩文本响应、只压文本别压已压缩的、设最小压缩大小、生产常在 Nginx/CDN 做、考虑 Brotli。配置位置:Tomcat 直接配(简单/内嵌)或 Nginx/CDN 配(生产常见、更高效、配合缓存)——有 Nginx/CDN 就在那层做(压缩+缓存+静态资源)。理解「静态资源:生产交给 Nginx/CDN+缓存头;GZIP:压文本+别压已压缩+设最小大小+Nginx/CDN 层做+Brotli;有 Nginx/CDN 就在那层做压缩缓存静态资源」,就掌握了实践与总结。

记忆钩子:「①静态资源:Tomcat 内置 DefaultServlet 处理(读文件+缓存头 Last-Modified/ETag 返回 304 省流量+Range 断点续传),★生产通常交给 Nginx/CDN(更高效+就近分发+Tomcat 专注动态)②GZIP 压缩:把文本响应压缩后传减小体积(文本压缩率 70%~90%);协商:客户端请求头 Accept-Encoding: gzip(我支持)→服务端压缩+响应头 Content-Encoding: gzip(我用了)→客户端解压;★只压该压的:压文本类(HTML/CSS/JS/JSON),绝对不压已压缩的(图片 JPG/PNG/视频 MP4/zip,再压没效果+白耗 CPU+可能变大),设最小压缩大小(太小不压);代价 CPU 换带宽(通常划算);Tomcat 配 compression=on+compressibleMimeType,生产常在 Nginx/CDN 做;Brotli(br)压缩率更高;minify(构建减小文件本身)vs GZIP(传输压缩)配合」

七、常见误区与追问

  • 误区:所有响应都应该 GZIP 压缩。 只压文本类(HTML、CSS、JS、JSON 等,压缩率高);绝对不要压已经压缩过的二进制(图片 JPG/PNG、视频 MP4、zip 文件)——它们已经是压缩格式,再 GZIP 几乎没效果、还白白消耗 CPU、甚至可能变大;要配置压缩类型白名单只压文本。
  • 误区:GZIP 压缩没有代价、越多越好。 有代价——GZIP 是「用 CPU 换带宽」:服务端压缩要消耗 CPU、客户端解压也要 CPU;对文本响应通常划算(带宽是瓶颈、压缩率高),但太小的响应压缩收益不够压缩开销(要设最小压缩大小如 2KB),已压缩的二进制压了白耗 CPU(别压)。
  • 误区:生产环境应该让 Tomcat 处理静态资源。 通常不——生产环境一般把静态资源交给 Nginx/CDN 处理:Nginx 处理静态文件更高效、CDN 能就近分发和边缘缓存,让 Tomcat 专注处理动态请求(别占 Tomcat 的线程和资源);Tomcat 的 DefaultServlet 能处理静态资源,但不是生产的最优选择。
  • 误区:GZIP 压缩和 minify(代码压缩)是一回事。 不同——minify 是构建时去掉 JS/CSS 的空格、注释、缩短变量名,减小文件本身(源文件层面);GZIP 是传输时用压缩算法压缩响应体,减小传输体积(传输层面);两者配合使用(minify 后的文件再 GZIP 传输),一个减小文件、一个减小传输。
  • 追问:GZIP 压缩是怎么工作的? 通过内容协商:① 客户端在请求头带 Accept-Encoding: gzip,告诉服务端「我支持 gzip 解压」;② 服务端判断响应是否适合压缩(是文本类、支持 gzip、大小超过阈值),如果适合就用 GZIP 算法压缩响应体;③ 服务端在响应头加 Content-Encoding: gzip,告诉客户端「响应用了 gzip」;④ 客户端看到 Content-Encoding: gzip 就解压响应体;这样传输的是压缩后的小体积数据、加快传输、省带宽,代价是服务端压缩和客户端解压的 CPU 开销。
  • 追问:为什么图片、视频不用 GZIP 压缩? 因为图片(JPG、PNG、GIF、WebP)、视频(MP4、WebM)、压缩包(zip、gz)本身已经是压缩格式了——它们内部已经用了专门的压缩算法(JPEG 压缩、H.264 等),数据已经很紧凑、几乎没有可压缩的冗余;再用 GZIP 压缩,几乎压不动(没效果)、还白白消耗服务端和客户端的 CPU、甚至可能因为 GZIP 的头部开销而变大;所以 GZIP 只压文本类(有大量重复内容、压缩率高),配置压缩类型白名单排除已压缩的二进制。
  • 追问:静态资源和动态请求生产上怎么分工? 生产上通常:静态资源(HTML、CSS、JS、图片、字体)交给 Nginx/CDN 处理——Nginx 处理静态文件高效、支持缓存和压缩,CDN 就近分发、边缘缓存,用户从最近的节点拿;动态请求(需要程序处理、生成响应的 API、页面)转发给后端 Tomcat 处理;这样静态资源不占 Tomcat 的线程和资源、Tomcat 专注动态请求;架构是「用户 → CDN(静态)/ Nginx(反向代理)→ Tomcat(动态)」。

八、加强记忆

静态资源处理和 GZIP 压缩是 Web 性能优化的基础① 静态资源(HTML、CSS、JS、图片等不变的文件)——Tomcat 内置 DefaultServlet 处理(读文件、缓存头 Last-Modified/ETag 没变返回 304 省流量Range 断点续传);但生产通常交给 Nginx/CDN(Nginx 处理静态文件更高效、CDN 就近分发和边缘缓存、让 Tomcat 专注动态请求)。② GZIP 压缩——把响应体用 GZIP 算法压缩后传输,大幅减小体积(文本压缩率 70%~90%);协商流程:客户端请求头 Accept-Encoding: gzip(我支持)→ 服务端压缩 + 响应头 Content-Encoding: gzip(我用了)→ 客户端解压。关键原则「只压该压的」只压文本类(HTML/CSS/JS/JSON,压缩率高)绝对不压已压缩的(图片 JPG/PNG、视频 MP4、zip——再压没效果 + 白耗 CPU + 可能变大)设最小压缩大小(太小的不压)。GZIP 是「用 CPU 换带宽」(通常划算)。Tomcat 配 compression="on" + compressibleMimeType(Spring Boot 用 server.compression.*);生产常在 Nginx/CDN 层做压缩(更高效);Brotli(br)压缩率比 GZIP 更高。minify(构建时减小文件本身)和 GZIP(传输时压缩)配合。一句话「静态资源:Tomcat DefaultServlet(缓存头/Range),生产交给 Nginx/CDN;GZIP 压缩文本响应减小体积(Accept-Encoding 协商、Content-Encoding);只压文本(HTML/CSS/JS/JSON)、别压已压缩的(图片/视频)、设最小大小;CPU 换带宽,生产在 Nginx/CDN 做,Brotli 压缩率更高」。