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

分配大内存,如果没有主动释放,就会出现“内存泄露”,问题表现就是用户多次刷新页面后, 这段代码就会报错。

解决方案:

  1. 用完之后立即释放
window.arr = new Uint8Array(1 * 1024 * 1024 * 1024); // 1GB
// ...
window.arr = null;  // 加上这段就不会出现刷新多次后无法分配的问题
  1. 由于用户刷新行为不可控,而应用逻辑可能需要将这段内存保留一段时间,这时候就需要在 '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,避免频繁创建新实例。

posted on 2026-05-12 11:55  y1j2x34  阅读(7)  评论(0)    收藏  举报