mobile safari
异步方法中聚焦输入框, 无法弹出输入法
重现方法:
button.onclick = async () => {
await someAsyncTask(); // 执行某个异步方法
inputElement.focus(); // 等待异步方法返回结果后再聚焦, 这时候聚焦正常,但是不会弹出输入法
}
解决方案:
button.onclick = async () => {
// 开始异步任务前,先使用临时的输入框聚焦,确保输入法弹出
const tempInput = document.createElement('input');
document.body.append(tempInput);
tempInput.focus(); // 输入法正常弹出
await someAsyncTask();
inputElement.focus(); // 输入焦点转移到目标输入框中
tempInput.remove();
}
WebAssembly.Memory.prototype.grow 方法申请内存触发浏览器崩溃
重现过程
const mem = new WebAssembly.Memory({
initial: 16 * 1024 * 1024 / 65536,
maximum: 2147483648 / 65536
})
mem.grow(16 * 1024 * 1024 / 65536); // 不断申请,大约达到 380~400 M 左右触发崩溃。不同版本和机型可能有差异
解决方法很简单,直接将初始内存设置为超过 400M 的数值, 最好结合应用场景设置一个合理初始值。
内存泄露问题
重现代码:
window.arr = new Uint8Array(1 * 1024 * 1024 * 1024); // 1GB
分配大内存,如果没有主动释放,就会出现“内存泄露”,问题表现就是用户多次刷新页面后, 这段代码就会报错。
解决方案:
- 用完之后立即释放
window.arr = new Uint8Array(1 * 1024 * 1024 * 1024); // 1GB
// ...
window.arr = null; // 加上这段就不会出现刷新多次后无法分配的问题
- 由于用户刷新行为不可控,而应用逻辑可能需要将这段内存保留一段时间,这时候就需要在 'pagehide' 事件中释放内存
window.arr = new Uint8Array(1 * 1024 * 1024 * 1024); // 1GB
// ...
window.addEventListener('pagehide', () => {
window.arr = null;
});
为什么不是 'beforeunload' ? 因为TMD IOS 不支持!
css mix-blend-mode 不生效
这是在 iphone8 下面发现的问题,重现方式如下:
<div style="mix-blend-mode:multiply;"> <canvas> </div>
解决方案: 将 mix-blend-mode 样式设置到 canvas 上,而不是容器
<div > <canvas style="mix-blend-mode:multiply;"></canvas> </div>
ImageBitmap close 了, 仍然触发 crash
重现代码:
function test() {
const ofc = new OffscreenCanvas(4096, 4096);
ofc.getContext('bitmaprenderer');
while(true) {
const bitmap = createImageBitmap(ofc);
await new Promise(resolve => setTimeout(resolve, 10)); // 模拟渲染
bitmap.close(); // 释放 bitmap
}
}
实际运行后很快就会触发 crash , chrome 上正常。
解决方案: 在 bitmap.close() 加入等待,确保下次创建 ImageBitmap 前没有残留
function test() {
const ofc = new OffscreenCanvas(4096, 4096);
ofc.getContext('bitmaprenderer');
while(true) {
const bitmap = createImageBitmap(ofc);
await new Promise(resolve => setTimeout(resolve, 10)); // 模拟渲染
bitmap.close(); // 释放 bitmap
await new Promise(resolve => setTimeout(resolve)); // 等待 bitmap 释放后再继续下一步操作
}
}
android chrome 130 白屏问题
问题现象
canvas 正常渲染后,经过一段时间的交互操作,Chrome 应用出现白屏;重启应用后可恢复。
重现方式
页面持续创建新的 canvas 用于显示内容,但旧的 canvas 未及时释放,最终导致内存持续增长并触发白屏。
解决方案
引入 canvas 对象池进行复用管理:
canvas 不再使用时,将 width/height 置为 0,并回收到对象池;
需要渲染时,优先从对象池中获取可复用的 canvas,避免频繁创建新实例。
浙公网安备 33010602011771号