系统性排障React Native · Hermes · WebView
战役一:真机地图黑屏,四层洋葱剥到底
iPhone 真机上,创建聚会页的高德地图是一个纯黑框——没有报错、没有搜索框, 而同一份代码在电脑浏览器里一切正常。
第一层 · 现象与假设淘汰
先后排除了高德域名白名单(WebView 内嵌页面来源是 about:blank,白名单必拒——但清空后依旧黑)、 手机代理拦截(脚本实际加载成功)。教训:给黑框装上「错误自述层」,让界面自己说出错原因, 不再靠猜。
第二层 · Hermes 的 [bytecode]
错误自述层报出
Can't find variable: bytecode。 根因:地图代码靠 Function.toString() 把渲染函数注入 WebView,而 Hermes 引擎默认不保留函数源码,注入的是 [bytecode] 占位废码—— 只在真机炸、电脑永不复现。官方逃生门 "show source" 在 Expo Go 下也不生效。第三层 · 无 WebGL 的「无错全黑」
改为托管页架构后仍黑:网络面板显示零瓦片请求——高德 JSAPI 自动升级到矢量渲染引擎, 在禁 WebGL/无 GPU 环境下「不报错但一个像素也不画」。强制
layers: [new AMap.TileLayer()] 走经典栅格瓦片(纯 img,任何设备可渲染)。第四层 · 一行 CSS 的真凶
还是黑。逐项检查 DOM 发现容器
clientHeight = 0: 高德初始化会把容器重置为 position: relative, 靠 absolute + inset 撑尺寸的容器被塌成 0 高—— 「地图创建成功,但没有一个像素可画」,全设备全版本成立。显式宽高一行修复。架构决策
最终形态:App 内地图 = WebView 加载自有域名的托管页(/amap/picker、/amap/view), 渲染函数被 Web 与 App 直接 import——全仓库一份地图代码,行为与真实浏览器完全一致, 还天然兼容未来的域名白名单。每层排查都沉淀成页面上的阶段水印与错误自述,下次问题会自己开口。