GIF 一开始为什么会这么大
GIF 用 LZW 压缩,逐行扫描重复的字节序列并用更短的编码替换。它在平坦色块上表现极好,在噪点上很差,而且——这一点最关键——它完全没有"运动"这个概念。每一帧都是各自独立压缩的。
现代视频编码做的是相反的事:存一整帧,然后描述后面的帧和它有什么差别。这就是为什么一段大部分静止的录屏做成视频很小,做成 GIF 就不小。GIF 确实支持跳过帧间未变化的区域,但那是比运动补偿弱得多的机制,而且任何噪点、抖动或镜头移动都会让它失效。
控制 GIF 体积的杠杆有四个,而它们的力量并不相等。按效果排序:尺寸、帧数、颜色数、抖动。理解它们为什么是这个顺序,才是你能砍掉 70% 而看不出被砍过的原因。
2026 年 9 月 12 日 · 约 8 分钟
GIF 用 LZW 压缩,逐行扫描重复的字节序列并用更短的编码替换。它在平坦色块上表现极好,在噪点上很差,而且——这一点最关键——它完全没有"运动"这个概念。每一帧都是各自独立压缩的。
现代视频编码做的是相反的事:存一整帧,然后描述后面的帧和它有什么差别。这就是为什么一段大部分静止的录屏做成视频很小,做成 GIF 就不小。GIF 确实支持跳过帧间未变化的区域,但那是比运动补偿弱得多的机制,而且任何噪点、抖动或镜头移动都会让它失效。
体积随像素总量变化,而像素总量随线性尺寸的平方变化。从 640px 宽降到 480px,在动任何编码参数之前就先去掉了约 44% 的像素。降到 320px 则去掉 75%。
这几乎总是第一个该试的,因为 GIF 几乎总是以小于制作尺寸的样子被看到——在聊天窗口里、在文档页面里、在工单里。按它实际显示的尺寸导出在视觉上不花钱,是能拿到的最便宜的一次大幅收益。
字节数几乎随帧数线性变化,所以帧率减半,文件大致也减半。裁掉头尾的空转时间更划算,因为那些帧本来就什么都没贡献。
看一遍你的片段,数数真正承重的帧有几个。一段八秒的演示,通常开头有两秒是在找鼠标,结尾有一秒什么都没发生。砍掉它们是免费的。
要在抽帧之前裁剪,不是之后。为一段马上就要扔掉的范围解码,白白花掉时间和内存。
比大家想的更不线性。256 降到 128 往往在视觉上是免费的,能省 20% 到 30%。32 降到 16 通常明显变难看,绝对收益却小得多,因为到那时调色板已经不是主要开销了。
素材类型比数字更重要。有大片平坦区域的东西经得起激进的削减;有渐变的东西——天空、皮肤、阴影、文字后面的柔和投影——会很快垮掉,需要抖动才能维持在可接受范围。
| 素材 | 颜色数 | 抖动 |
|---|---|---|
| 录屏、界面 | 32–64 | 关 |
| 扁平插画、Logo | 16–32 | 关 |
| 实拍视频 | 128 | Floyd–Steinberg |
| 照片幻灯片 | 128–256 | Floyd–Steinberg |
| 文字多的画面 | 保持高位 | 关——改缩尺寸 |
抖动用现有颜色混成细密的图案来近似缺失的颜色。它消除断层,同时让平坦区域变成噪点——而这恰好是 LZW 最不擅长压缩的东西。用在不合适的素材上,它会一边把文件撑大一边让画面更花。
有序(Bayer)抖动用固定图案,因此会重复,比误差扩散型压得更好。Floyd–Steinberg 在照片上更平滑,但产生的是不重复的噪点。在扁平图形上,干脆不抖动,既更小也更干净。
假设一个 4MB 的 GIF 需要压到 1MB 以内,按清单往下走,而不是去拽一根"压缩"滑杆。
这四步叠加下来远低于原始体积的四分之一。之所以要按这个顺序,是因为每一步都在降低下一步的成本,而视觉上最贵的那根杠杆被放到了最后。
如果你已经裁过、减半过、缩过,它还是太大,那这素材是在告诉你一件事。长片段、镜头移动和照片渐变,都是 GIF 在结构上就不擅长的东西。
MP4 和 WebM 处理的恰好就是这几种情况,而且好一个数量级,如今几乎所有去处都收。把 GIF 留给"必须内联自动播放且没有播放器"是硬要求的场合,其余时候用视频。