判断两张图是否真正重复,需先明确“重复”是人定义的语义概念:物理层面(MD5一致)才算真重复;分辨率、格式、水印、路径不同但内容一致的属于合理变体,不可盲目删除。

直接删掉重复文件前,先确认它们是不是真“重复”——很多看似相同的图片,实际是不同分辨率、不同压缩质量、或带不同水印的变体,盲目删除可能破坏响应式逻辑或设计意图。
怎么判断两张图算不算真正重复
浏览器不会自动比对像素或哈希,所谓“重复”必须由人定义。常见误判场景:
- 同一张图被导出为
logo@2x.png和logo.svg:不是重复,是适配策略 -
banner-home.jpg和banner-home-webp.webp:现代项目中这是正常格式 fallback,不应删除任一 - 路径不同但内容一致(如
/assets/img/hero.jpg和/public/images/hero.jpg):这才是真重复,需统一引用路径 - CDN 上的
https://cdn.example.com/v1/logo.png和本地./src/assets/logo.png:若内容一致且版本未同步,本地文件已失效,应删本地、只留 CDN 引用
用命令行快速找出物理重复图片
别靠肉眼翻文件夹。在项目根目录运行:
fd '\.(jpg|jpeg|png|webp|gif)$' | xargs -I{} sh -c 'identify -format "%f %m %wx%h %b %#" {} 2>/dev/null' | sort -k5 | uniq -w32 -D
说明:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
立即学习“前端免费学习笔记(深入)”;
-
fd比find更快,只搜常见图片后缀 -
identify(来自 ImageMagick)提取文件名、格式、宽高、体积、MD5 哈希(%#) -
sort -k5按第 5 列(MD5)排序,uniq -w32 -D只比对前 32 字符(MD5 长度),输出所有重复行 - 注意:WebP 和 PNG 即使视觉相同,哈希也不同;此法只适用于完全二进制一致的副本
HTML 中引用重复图时的维护陷阱
即使文件物理不重复,HTML 层面的引用混乱也会导致“逻辑重复”:
- 多个
<img src="icon-menu.png">分散在不同组件里,但实际路径不一致(./icons/vs/static/icons/)→ 后期改图要修 5 处,极易漏 - 用 CSS
background-image复用同一图,但两个容器没设width/height→ 一个显示,一个塌陷不可见,误以为图丢了 - JS 动态创建
img元素时,用同一个 DOM 节点反复appendChild()→ 图只出现在最后一个位置,前面的消失 - SVG 内联时滥用
<use href="#logo">,但 ID 在多页间冲突或跨 iframe 失效 → 某些页面图标空白
长期避免重复的根本动作
不是工具问题,是协作规范问题。最常被跳过的一步是:在构建流程里加校验。
- Webpack/Vite 插件如
duplicate-package-checker-webpack-plugin不适用图片,但可用rollup-plugin-duplicates(配合自定义资源解析) - 更轻量做法:CI 阶段跑一次
fd . -e png -e jpg | xargs md5sum | sort | uniq -w32 -D,有输出就 fail 构建 - 团队约定图片命名规则,比如
[模块]-[用途]-[尺寸].[ext](user-avatar-48x48.png),避免出现avatar-small.png和user-icon-48.png这种语义重叠 - 静态资源全部走构建时 hash(
logo.a1b2c3.png),打包后自动去重;但需确保 HTML 模板里引用的是构建后生成的文件名,而非手写原始名
真正难的不是发现重复,而是判断“该不该删”。一张图出现在三个地方,可能是因为 A 处要高清、B 处要 WebP、C 处要裁剪,此时删掉任意一个都会引发线上问题。动手前,先看它被谁用、为什么这么用。


















