WebWorker中用OffscreenCanvas缩放图片在Playwright的WebKit环境失效
问题分析
本地Firefox、Chrome、Safari中基于WebWorker的图片压缩代码运行正常,但GitHub Actions里Playwright 1.44.0的WebKit测试失败,核心原因是WebKit在Web Worker环境下对createImageBitmap处理File对象存在支持限制,同时原代码存在消息监听逻辑bug。
解决方案
一、修改代码实现兼容与逻辑修复
1. 兼容WebKit的createImageBitmap调用
WebKit无法直接在Worker中对File对象调用createImageBitmap,可通过FileReader将File转为ArrayBuffer后再处理:
// worker.ts onmessage = async (msg: MessageEvent<File>) => { const img: File = msg.data; // 用FileReader读取File为ArrayBuffer,规避WebKit兼容性问题 const arrayBuffer = await new Promise<ArrayBuffer>((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result as ArrayBuffer); reader.onerror = reject; reader.readAsArrayBuffer(img); }); // 从ArrayBuffer创建ImageBitmap const imageBitmap = await createImageBitmap(new Blob([arrayBuffer])); const offscreenCanvas = new OffscreenCanvas(imageBitmap.width / 2, imageBitmap.height / 2); const ctx = offscreenCanvas.getContext('2d'); if (!ctx) return; ctx.drawImage(imageBitmap, 0, 0, offscreenCanvas.width, offscreenCanvas.height); const blob = await offscreenCanvas.convertToBlob({ type: img.type, quality: 0.8 }); const resizedImg = new File([blob], img.name, { type: img.type }); postMessage(resizedImg); };
2. 修复Worker消息监听的逻辑bug
原代码循环绑定onmessage会覆盖之前的回调,导致多图片处理时结果丢失,改为使用一次性事件监听:
// compress.ts async function compressImages(images: FileList): Promise<File[]> { const files: File[] = []; if (!window.Worker) { console.log("您的浏览器不支持Web Worker。"); return files; } const myWorker = new Worker(new URL('./worker.ts', import.meta.url)); // 用Promise数组并行处理所有图片 const promises = Array.from(images).map((image) => { return new Promise<File>((resolve) => { const handleMessage = (e: MessageEvent<File>) => { myWorker.removeEventListener('message', handleMessage); resolve(e.data); }; myWorker.addEventListener('message', handleMessage); myWorker.postMessage(image); }); }); files.push(...await Promise.all(promises)); myWorker.terminate(); // 处理完成后终止Worker return files; } export { compressImages };
二、调整GitHub Actions的Playwright配置
如果暂时不想修改代码,可通过以下方式让CI/CD正常运行:
- 强制安装最新版WebKit,覆盖默认版本:
npx playwright install webkit --force - 对WebKit环境跳过该测试(临时方案):
test('图片压缩功能', async ({ page, browserName }) => { if (browserName === 'webkit') { test.skip(); } // 测试逻辑 });
内容的提问来源于stack exchange,提问作者Theiaz
相关产品推荐
相关产品推荐

