fix: work around broken WebAssembly streaming compile in Android WebView - #26
Open
sunbird89629 wants to merge 1 commit into
Open
fix: work around broken WebAssembly streaming compile in Android WebView#26sunbird89629 wants to merge 1 commit into
sunbird89629 wants to merge 1 commit into
Conversation
Some Android System WebView builds throw on WebAssembly.compileStreaming / instantiateStreaming even when the .wasm is fetched correctly (200 application/wasm). This breaks sites that load a wasm video decoder for 4K playback, while the same URL plays fine in Chrome. Inject a small shim (assets/wasm-streaming-shim.js) in onPageStarted, before custom.js, that tries native streaming first and only falls back to fetch -> arrayBuffer -> compile on failure. Healthy engines keep the fast path; affected ones auto-recover.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
部分网站在播放高码率 / 4K 视频时,会加载一个 wasm 软解码器(wasm-bindgen 生成的 glue),通过
WebAssembly.instantiateStreaming/compileStreaming(流式编译)来实例化。在一部分 Android System WebView 上,这条「流式编译」管线有缺陷:即使
.wasm文件本身已经200 application/wasm正常下载,流式编译仍然抛出:结果就是用 PakePlus 打包出来的 App 里,这类站点 4K 视频黑屏、播放器报错;而同一个网址在桌面 / 移动版 Chrome 里播放完全正常。
根因
我在一台 Pixel 8(Android 16 / WebView 150.0.7871.124)上,通过 WebView 远程调试(chrome://inspect)在页面上下文里做了实测对比:
fetch(wasm)application/wasm,Response 正常loadingFailed)WebAssembly.compileStreaming(fetch(...))fetch → arrayBuffer → WebAssembly.compile(buffer)结论:根因是该 WebView 的流式编译实现有缺陷,与网络、UA、WebView 版本新旧都无关。而非流式路径(先把 wasm 下载成
ArrayBuffer再compile)在同一个 WebView 上完全正常。Chrome 用的是完整引擎,所以流式编译不受影响。改动
新增一个很小的 shim(
app/src/main/assets/wasm-streaming-shim.js),在onPageStarted里、custom.js注入之前注入。它覆盖compileStreaming/instantiateStreaming,采用 「先试原生、抛错再降级」 策略:fetch → arrayBuffer → compile/instantiate。只在真正失败时才兜底,不牺牲正常设备的性能。注入用的是仓库已有的
assets.open(...).evaluateJavascript(...)套路(和现有custom.js/vConsole.js同款),不引入新依赖、不改打包流程。改动只涉及两个文件:
app/src/main/assets/wasm-streaming-shim.js(新增)app/src/main/java/com/app/pakeplus/MainActivity.kt(+3 行)验证
在 Pixel 8 上用打包出的 release APK 做了双向验证(冷启动,无任何调试注入):
WebAssembly报错遮罩,视频正常播放(video.readyState === 4、paused === false、进度正常推进)。compileStreaming,编译成功、未进入 fallback 分支——说明「先试原生」确实生效,正常设备不会被无谓降级。截图对比
修复前(报错遮罩):
修复后(4K 正常播放):
复现环境