公众号排版工具老是卡死?别忍了,两个改动就能救命
你肯定遇到过这种场面:
- 正在写 5000+ 字长文,手速一快,输入框开始“慢半拍”,再快点就直接卡住。
- 上传 5~10 张手机原图,页面风扇狂转,内存飙升,最后白屏或假死。
- 一边写长文一边插图,体验像在拖着沙袋走路。
这种卡顿大概率不是“你电脑不行”,而是编辑器的 输入触发太频繁 + 图片太大没处理。
下面这套修复方案很克制:只加不改。不动你原来的功能逻辑,也不推翻现有结构,直接把卡死点掐掉。
目标:让它回到“正常人类软件”的手感 😅
预期效果对标这三条:
- 5000+ 字长文 + 快速打字:不再卡顿
- 上传 5~10 张手机原图:内存占用从 25~50MB 降到 2~5MB(常见量级)
- 长文 + 多图同时进行:不再卡死
改动 1:输入防抖(别每敲一个字就全量计算)
很多排版工具的“卡”,不是渲染能力差,是你每次按键都会触发一堆事:
- 解析内容(HTML/Markdown)
- 重新计算样式/节点
- 触发预览区重渲染
- 保存草稿/同步状态
你打字越快,这些操作越像机关枪一样扫射 CPU。
怎么做
把“输入事件”拆成两层:
- 即时层:输入框里展示你正在打的字(保证手感)
- 计算层:解析、预览渲染、草稿保存等重活(延迟一点点再做)
核心就是防抖:
function debounce(fn, delay = 200) {
let timer = null;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
const heavyUpdate = debounce((value) => {
// 这里放:解析、预览渲染、草稿保存等
updatePreview(value);
saveDraft(value);
}, 200);
inputEl.addEventListener('input', (e) => {
const value = e.target.value;
// 输入框即时更新交给浏览器本身即可
heavyUpdate(value);
});
参数怎么选
- 150~300ms:大部分场景够用,打字顺滑,预览也不会“慢到看不见”。
- 你要是预览特别重,直接拉到 300~500ms,体感依然正常。
你会立刻看到的变化
- CPU 峰值明显下降
- 快速输入不再掉帧
- “越写越卡”会缓解很多
改动 2:图片自动压缩(手机原图就是内存刺客)
手机随手一拍就是 3000~6000px 宽度、几 MB 一张。
在编辑器里,你一口气塞 5~10 张,常见结果:
- 图片解码占内存
- base64/Blob 处理再占一份
- 渲染到 DOM 里又占一份
你感觉是“上传图片卡”,实际是 内存被顶爆,浏览器开始疯狂 GC(垃圾回收),然后就假死。
压缩策略(别瞎压,按规则来)
一套好用又稳的策略:
- 宽度 ≤ 800px 的小图:跳过压缩,保持原样(别画蛇添足)
- 大图:压到一个合理宽度(例如 1600px 或 2000px),质量 0.7~0.85
- 输出格式优先用 JPEG/WebP(看你兼容要求)
实现示例(浏览器端 Canvas 压缩)
async function compressImage(file, {
maxWidth = 1600,
quality = 0.8,
skipWidth = 800,
mimeType = 'image/jpeg'
} = {}) {
const img = await loadImage(file);
// 小图直接放行
if (img.width <= skipWidth) return file;
const scale = Math.min(1, maxWidth / img.width);
const w = Math.round(img.width * scale);
const h = Math.round(img.height * scale);
const canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, w, h);
const blob = await new Promise((resolve) =>
canvas.toBlob(resolve, mimeType, quality)
);
return new File([blob], file.name.replace(/\.[^.]+$/, '.jpg'), { type: mimeType });
}
function loadImage(file) {
return new Promise((resolve, reject) => {
const url = URL.createObjectURL(file);
const img = new Image();
img.onload = () => {
URL.revokeObjectURL(url);
resolve(img);
};
img.onerror = reject;
img.src = url;
});
}
把它接到上传流程里:
async function handleUpload(files) {
const compressed = [];
for (const f of files) {
compressed.push(await compressImage(f));
}
// 用 compressed 替换原 files 继续走你的上传/插入逻辑
await uploadAndInsert(compressed);
}
你会立刻看到的变化
- 多图上传不再“卡到怀疑人生”
- 内存占用能降一个数量级(10 倍级别很常见)
- 同时编辑长文 + 多图,稳定性提升非常明显
避坑清单(踩一次就够了)
- 别把防抖加在输入框 value 更新上:你会得到“打字延迟”的灾难体验。重活防抖就行。
- 压缩别无脑转 base64:base64 比二进制更占内存,还可能拖慢渲染。
- 记得释放对象 URL:
URL.revokeObjectURL(url)不写,图片越多越容易内存泄漏。 - 小图别压:比如二维码、截图、icon,压了反而糊,还浪费 CPU。
快速自测:你修复到位没
拿两组场景测就够:
- 长文压测:粘贴 5000+ 字,疯狂连续输入 20 秒,观察是否掉帧/延迟。
- 多图压测:上传 5~10 张手机原图,打开浏览器任务管理器/性能面板看内存峰值。
你看到“输入顺滑 + 内存没爆”,这事基本就成了。
一句话结论
编辑器卡死通常不是“复杂功能太多”,而是两个最常见的硬伤:输入触发太频繁、图片没做体积控制。
把输入防抖和图片自动压缩补上,体验会像换了个工具一样。