---
id: rsync-images
title: 一条 rsync 管好全站图片
date: 2026-11-01
updated: 2026-11-01
category: 工具
tags: rsync, Shell
minutes: 6
---

截图和配图是静态站最容易失控的地方。我原来的目录里躺着 200 多张 PNG，平均 800KB，一张首页要吃掉 6MB。

现在往 `inbox/` 里丢原图，跑一条命令，输出就是压缩好的 WebP，并按年月归档。

## 脚本

```
#!/usr/bin/env bash
# images.sh —— 原图丢 inbox/，跑一次生成 WebP 到 assets/img/
set -euo pipefail

SRC="${1:-inbox}"
DST="${2:-assets/img}"
mkdir -p "$DST"

find "$SRC" -maxdepth 1 -type f \( -iname '*.png' -o -iname '*.jpg' -o -iname '*.jpeg' \) |
while read -r f; do
  base="$(basename "${f%.*}")"
  # 长边压到 1600，质量 82，体积和观感基本是平衡点
  cwebp -quiet -q 82 -resize 1600 0 "$f" -o "$DST/$base.webp"
  echo "✓ $base.webp  $(du -h "$DST/$base.webp" | cut -f1)"
done

# 顺手统计一下
printf '共 %s 个文件，合计 %s\n' \
  "$(ls -1 "$DST"/*.webp 2>/dev/null | wc -l)" \
  "$(du -sh "$DST" | cut -f1)"
```

需要 `cwebp`：Debian 上是 `apt install webp`。

## 为什么是 1600 / 82

我试过几组参数：

- 原图 2400 宽、质量 90：一张 400KB，肉眼和 1600/82 几乎没区别
- 1600 宽、质量 82：一张 90–140KB
- 1200 宽、质量 78：手机上看没问题，桌面大屏开始糊

博客正文最大显示宽度 672px，两倍屏就是 1344。1600 留了点余量给封面图。

## 保留原图，但别上传

原图留在 `assets/img-src/`（不进部署目录），需要重新生成或者换尺寸时有源可依。`rsync --delete` 只同步 `assets/img/`，源图永远不会上服务器。

## 一个副作用

换成 WebP 之后，Cloudflare 的缓存命中率明显上去了——同一个页面第二次访问基本全是 `cf-cache-status: HIT`。理由很简单：资源变小了，边缘节点更容易把它留在缓存里，回源次数直接降下来。

:::注意
WebP 在 2020 年之后的浏览器全支持，不用再准备 fallback。真遇到老设备，图片不显示比装一堆 `<picture>` 更少见。
:::
