CI/CD 流水线中的图像优化自动化 - GitHub Actions 与 Sharp 实战配置
为什么在 CI/CD 中优化图像 - 手动工作流的局限
手动图像优化依赖开发者记忆和纪律,不可避免地出现遗漏。CI/CD 自动化确保每张图像都经过一致的优化处理,消除人为因素。
手动工作流的问题:
- 开发者忘记压缩或转换格式
- 不同团队成员使用不同的压缩设置,质量不一致
- 大型项目中难以追踪哪些图像已优化
- 新加入的团队成员不了解优化流程
CI/CD 自动化的优势:
- 每次提交自动检查和优化图像
- 统一的质量标准,无论谁提交
- 文件大小超标时自动阻止合并
- 生成优化报告,可视化节省的带宽
GitHub Actions 图像优化工作流 - 基础配置
使用 GitHub Actions 构建图像优化工作流的基础配置,在每次 PR 或推送时自动处理图像。
工作流触发条件: 监听包含图像文件变更的 PR 和推送事件。使用路径过滤器仅在图像目录有变更时触发,避免不必要的运行。
基础工作流结构:
name: Image Optimizationon: pull_request: paths: ['src/images/**', 'public/images/**']jobs: optimize: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 - run: npm ci - run: node scripts/optimize-images.js
缓存策略: 使用 actions/cache 缓存 node_modules 和已优化的图像哈希,避免重复处理未变更的图像。
Sharp 图像转换脚本 - WebP 和 AVIF 自动生成
使用 Sharp 库编写图像转换脚本,自动生成 WebP 和 AVIF 格式的优化版本。
基础转换脚本:
const sharp = require('sharp');const glob = require('glob');const path = require('path');const images = glob.sync('src/images/**/*.{jpg,png}');for (const img of images) { const base = path.parse(img).name; const dir = path.parse(img).dir; await sharp(img).webp({ quality: 80 }).toFile(`${dir}/${base}.webp`); await sharp(img).avif({ quality: 65 }).toFile(`${dir}/${base}.avif`);}
多尺寸生成: 同时生成多个宽度的变体用于响应式图像。典型配置: [640, 960, 1280, 1920] 像素宽度。Sharp 的 resize() 方法自动保持宽高比。
增量处理: 通过比较文件修改时间或内容哈希,仅处理新增或变更的图像。大型项目中这可将构建时间从分钟级降到秒级。
文件大小阈值检查与报告生成 - 实现质量门禁
设置文件大小阈值作为质量门禁,超标图像阻止 PR 合并,并生成优化报告。
阈值设置建议:
- 单张图像最大: 200KB (WebP) / 150KB (AVIF)
- 首屏 LCP 图像: 100KB 以下
- 缩略图: 30KB 以下
- 图标/Logo: 10KB 以下
检查脚本: 遍历所有图像文件,检查大小是否超过阈值。超标时输出详细报告并以非零退出码终止工作流。
PR 评论报告: 使用 GitHub API 在 PR 中自动添加评论,展示:
- 优化前后的文件大小对比
- 总节省的字节数和百分比
- 超标文件的列表和建议
- 格式转换的结果统计
缓存策略与构建时间优化 - 大型项目的扩展
大型项目可能包含数千张图像,需要智能缓存和增量处理来保持合理的构建时间。
内容哈希缓存: 计算每张源图像的 SHA-256 哈希,与已处理图像的哈希对比。仅哈希变更的图像需要重新处理。缓存文件 (.image-cache.json) 提交到仓库或存储在 CI 缓存中。
并行处理: 使用 Node.js 的 worker_threads 或 Promise.all 并行处理多张图像。GitHub Actions 的 ubuntu-latest 提供 2 核 CPU,可并行处理 2-4 张图像。
分层缓存:
- 第一层: Git LFS 追踪原始大图像
- 第二层: CI 缓存存储已优化的输出
- 第三层: CDN 缓存最终分发的图像
构建时间基准: 100 张图像 (各生成 WebP + AVIF + 4 种尺寸) 约需 30-60 秒。使用缓存后,仅处理变更图像,通常 5-10 秒。
实用配置模式与运营技巧 - 团队采用
将图像优化流水线推广到团队的实用建议和常见配置模式。
渐进式采用策略:
- 第一阶段: 仅报告 (不阻止合并),让团队了解现状
- 第二阶段: 对新增图像强制优化,存量图像逐步处理
- 第三阶段: 全量强制,所有图像必须通过质量门禁
配置文件化: 将优化参数 (质量、尺寸、阈值) 集中在配置文件中,便于调整和审查。示例: image-optimization.config.js 导出所有设置。
常见问题处理:
- 动画 GIF: 转换为 WebP 动画或 MP4 视频。Sharp 不支持动画,使用 gifsicle 或 ffmpeg
- 透明 PNG: WebP 支持透明通道,可直接转换。AVIF 同样支持
- SVG: 不进行光栅化转换,使用 SVGO 优化
监控与告警: 跟踪每次构建的图像总大小趋势。设置告警: 当总大小增长超过 10% 时通知团队。定期生成月度报告展示优化成果。