少女祈祷中...
ATIN

一个微信小程序的8个版本,我踩了哪些坑

一个微信小程序的 8 个版本,我踩了哪些坑

「确实佷难压缩」是一个微信图片压缩小程序。从 v1.0.1 到 v2.0.1,8 个版本迭代,每次以为稳了都会冒出新问题。这篇文章记录每个版本的核心改动和踩过的坑。

扫码体验小程序:

确实佷难压缩小程序码

v1.0.1:能用就行

第一个版本只做了一件事:选图片 → 压缩 → 保存。

核心能力: - Canvas 本地压缩,图片不上传服务器 - 基础的 JPG/PNG 格式支持

上线第一天就发现:微信会审核图片内容。纯本地压缩不走微信 API,违规图片直接能保存出去。于是加了 imgSecCheck 云函数,压缩后先过一遍微信内容安全审查。

踩坑:审查是异步的,用户看到红色呼吸灯会本能等待,不知道能不能点保存。后来加了"边审边存"提示。

v1.0.4:压缩算法重写

最初的压缩逻辑很粗暴:直接降 quality。结果发现一个问题——选 20KB 压不出来,选 100KB 能压,选 50KB 也能压,再选 20KB 又能压了。不稳定。

原因:单次 quality 调整无法精确控制输出大小。

重写方案:二分搜索 + 两点采样。 - 先在 quality=0.5 和 quality=0.1 各压一次,得到两个点 - 线性插值估算目标 quality - 最多修正 2 轮,最大 Canvas 调用 4 次

顺便把 UI 改成了深色毛玻璃风格。

v1.0.5:大图压不到目标

5000 万像素的大图,原始数据 150MB。二分搜索在 quality 空间里找,但 quality 再低也就那样——像素数太多了。

修复:大图先等比缩小到 4096px 以内,再走二分搜索。4096 是微信 Canvas 的安全上限,再大就崩。

最低 quality 也从 0.1 降到了 0.05,给极端情况多留余地。

v1.0.6:页面闪白

用户反馈:页面切换时会闪一下白屏。

原因:微信小程序的页面背景默认是白色。深色毛玻璃 UI 在页面切换瞬间,新页面还没渲染完就露出了白色底层。

修复:给所有页面的 JSON 配置补上 navigationBarBackgroundColorbackgroundColor,消除视觉断裂。

v1.0.7:进度条 + 自定义裁剪

两个大功能:

压缩进度条:之前压缩时只有一个 loading 动画,用户不知道压到哪了。改成百分比 + 状态文字("压缩中 60%" → "审查中 90%" → "完成")。

自定义裁剪尺寸:用户可以手动输入宽高(如 295×413 一寸照)。加了最小值 30px 的限制——输入太小会弹提示。

v1.0.8:Canvas 2D 升级

微信旧版 Canvas API 性能差,大图操作卡顿。升级到 Canvas 2D(type="2d"),速度提升 2-3 倍。

但升级带来了新坑: - drawImage 必须用 9 参数形式 (img, 0, 0, img.w, img.h, 0, 0, w, h),不然会截取图片 - canvasToTempFilePath 在 Canvas 2D 下不能传 x/y/width/height,只传 destWidth/destHeight - 改 canvas 宽高后上下文会重置,必须重新 getContext('2d')

还修了一个 bug:裁剪后输出体积反而变大了。原因是裁剪输出格式没跟随用户选择——选了 PNG 就强制输出 PNG,但 PNG 的 Canvas 重编码体积控制很差。改成跟随格式选择。

v1.0.9:裁剪框大修

这是改动最大的一个版本,问题也最多。

根因:坐标系不一致

裁剪框的四角拖拽在自定义尺寸模式下完全失灵。拖左下角,右下角在动。

真正原因不是判定逻辑,而是坐标系偏移touch.clientX/Y 是 WebView 坐标,frameX/frameY 是 crop-area 内部坐标。两者差了一个 crop-arealeft/top 偏移。

修法:在 onReadyboundingClientRect 缓存偏移量,触摸时统一减掉。

横图变竖条

16:9 的横构图照片,裁剪框显示成了一个竖条。

原因:之前用高度占满 areaH 来定裁剪框尺寸。横图高度小、宽度大,高度占满意味着宽度溢出被 overflow:hidden 切掉左右,只剩中间一条。

修法:横构图改用宽度上限 areaW*0.96,再反推高度。

其他修复

  • 角判定热区从无下限改为 44-64px(触控标准)
  • 比例锁定:边界钳制时以宽度为基准驱动高度,不再双向独立钳制把比例搞歪
  • _ready 守卫:图片没加载完就禁止触摸,避免 frame 为 0 误判

踩过的最严重的坑

debug 版在 onTouchStart 里引用了 initImage 作用域的局部变量 imgW。一跑就 ReferenceError: imgW is not defined,所有拖拽全部失效。

教训:console.log 埋点用的变量如果跨作用域,发布前必须删干净。

v2.0.0:对比页全新改版

从"压完就完"变成"压完还能看"。

滑动分割线对比:压缩前后并排,中间一条分割线左右拖动。比之前切换原图/效果图直观得多。竖图横图统一用垂直分割线,不搞两套交互。

一键重新裁剪:对比页不满意?不用返回首页重来。直接点"重新裁剪",弹出预设/自定义/自由裁剪选项,闭环操作。

裁剪输出优化:裁剪不再降画质(quality 保持 0.92),格式标注文案也修正了——之前显示"PNG"但实际输出 JPG,误导用户。

v2.0.1:自定义尺寸修正

用户反馈:指定 632×532 的裁剪尺寸,输出却是约 1000×900。

原因:自定义尺寸输入后,canvasToTempFilePathdestWidth/destHeight 没有严格取用户输入值,而是走了默认的缩放逻辑。

修复:自定义尺寸模式下,输出尺寸严格按用户输入值,不做任何缩放。

版本一览

版本 核心改动 踩坑
v1.0.1 基础压缩 + 内容审查 审查异步导致用户困惑
v1.0.4 二分搜索压缩算法 quality 空间不稳定
v1.0.5 大图先缩小再压缩 5000万像素直接崩
v1.0.6 修复页面闪白 页面背景色未配置
v1.0.7 进度条 + 自定义裁剪 最小值限制
v1.0.8 Canvas 2D 升级 API 参数差异、格式不跟随
v1.0.9 裁剪框全面重写 坐标系偏移、横图比例、跨作用域变量
v2.0.0 对比重塑 + 重新裁剪闭环 分割线交互统一
v2.0.1 自定义尺寸精确输出 destWidth/destHeight 缩放逻辑

写在后面

8 个版本,核心功能其实没变——选图、压缩、保存。但每个版本都有"以为修好了其实没有"的时刻。

最有意思的教训是:大部分 bug 不是逻辑错,而是假设错。假设坐标系一致、假设高度占满就行、假设 debug 代码不影响正式版。每一个"假设"都变成了一个线上 bug。

如果你也在做小程序,记住两件事:真机测试不能省,debug 代码发布前必须删。

由ai协助

评论