关键不是选最强算法,而是让算法匹配资源本质特征和使用场景:图片按视觉保真分层处理,文本代码重冗余识别轻语法破坏,结构化数据看用途定压缩强度,音视频按传输路径动态编码。

不同资源类型在结构、用途和感知敏感度上差异很大,统一用一个压缩算法或参数只会导致“该压的没压透,不该损的却画质崩了”。关键不是选最强的算法,而是让算法匹配资源的本质特征和使用场景。
图片类:按视觉保真需求分层处理
图片压缩的核心矛盾是“人眼是否可察觉失真”。不能一刀切用JPEG质量70——图标和截图完全不是一回事:
- PNG/JPEG大图(如产品主图):先检测实际展示尺寸与原始分辨率比值,若超2倍,优先降采样而非仅调质量;含透明通道的PNG转WebP时启用lossless模式,不损失alpha精度
- 纯色图标/矢量素材:直接转SVG,再用SVGO移除编辑器元数据、合并路径、精简ID命名,体积常比PNG小60%以上且无限缩放不失真
- 用户上传图(如头像):服务端接收到后,自动判断是否为手机直出高DPI图,若是,生成两版:WebP(质量82,含渐进加载)用于网页,AVIF(CRF 35)用于支持设备,不存原图
文本与代码类:重冗余识别,轻语法破坏
JS/CSS/HTML不是靠“压得狠”见效,而是靠剔除无意义重复。Vite默认的esbuild压缩适合开发,但生产环境要更进一步:
- 启用Terser的
compress.drop_console和compress.pure_funcs,但避开console.table等调试强依赖方法 - 对CSS做
cssnano处理时,禁用mergeLonghand(避免将margin: 0 10px合并为margin: 0 10px 0 10px引发兼容问题) - 多语言JSON资源(如
zh-CN.json)用esbuild插件扫描实际引用的key,未使用的翻译项直接剔除,不打包进最终bundle
结构化数据与二进制文件:看用途定压缩强度
缓存中的JSON、数据库里的Parquet块、上传的PDF——它们不是“越小越好”,而是“在用途约束下最小”:
- Redis缓存对象:JSON先转MessagePack(体积减30%~50%),再用LZ4压缩(解压快、CPU低),避免ZSTD——千万QPS下每毫秒CPU都算钱
- Apache Doris表存储:时间序列数值列用LZ4(解压吞吐高),用户行为日志文本列用ZSTD level 3(兼顾压缩率与延迟),冷数据分区自动切换到ZSTD level 12归档
- PDF文档:先OCR识别文字层,再剥离扫描图像中低DPI冗余页;字体只嵌入实际用到的字形子集,不用全量嵌入
视频与音频:按传输路径动态编码
同一段视频,在APP内播放、微信分享、邮件附件三种场景,压缩逻辑完全不同:
- APP内播放:H.265编码,CRF 23~25,关键帧间隔设为2s,启用B帧,保留原始宽高比,黑边不裁剪(适配不同屏占比)
- 微信/钉钉分享:转H.264 baseline profile + AAC-LC,分辨率硬限720p,码率封顶1.2Mbps,确保低端机也能软解
- 邮件附件:抽帧生成GIF(限制128色+抖动关闭)或WebM(VP9,无音频,尺寸≤480p),体积控制在5MB内,避免被邮箱拦截


















