直播小程序弹幕不见了?同层渲染来看看!
腾讯营销产品部研发工程师 rileycai 原创
riley!我在测试阶段没看到直播弹幕?
riley!我刚刚测试上架直播间产品,同事都说看不见!
riley!测试小哥哥反馈购物车消失了,急求解决办法
怎么会这样?!究竟是哪里出了问题?
随着小程序生态的蓬勃发展,小程序逐渐成为获客营销的新渠道,直播业务也能够通过小程序触达用户。然而,直播小程序开发并不是一件容易的事情,例如直播小程序变成 “纯净模式”,即只看到直播页面,却无法看到弹幕、产品链接、购物车等信息。这个难题应该如何解决呢?
经过技术检查,直播小程序 “纯净模式” 问题出现在对原生组件的层级应用,通过同层渲染的方法即可实现高效处理。
原生组件惹的祸?
在内置组件中,有一类组件较为特殊,它们并不完全在 Exparser 的渲染体系下,而是由客户端原生参与组件的渲染,这类组件称为 「原生组件」,例如小程序中的 live-player、canvas、map 等都是原生组件。
扩展 Web 的能力:例如输入框组件 input、textarea 有更好的控制键盘能力 减轻 WebView 的渲染工作:例如地图组件 map 这类较复杂的组件,其渲染工作不占用 WebView 线程,而交给更高效的客户端原生处理 绕过 setData、数据通信和重渲染流程,渲染性能更好:例如画布组件 canvas 可直接用一套丰富的绘图接口进行绘制
同层渲染来解惑!
为了解决原生组件的层级问题,同时尽可能保留原生组件的优势,微信团队提出 同层渲染,即控件并非绘制在原生组件贴片层,而是绘制在 WebView 所渲染的页面中,与其他 HTML 控件在同一层级。支持同层渲染后,原生组件与其它 H5 组件可以随意叠加,层级的限制将不复存在。
小程序前端在 webview 内创建一个 DOM 节点并设置其 CSS 属性为 overflow: hidden 且 -webkit-overflow-scrolling: touch,生成一个containerId,并将这个 WKChildScrollView 的位置信息通知给客户端 前端通知客户端递归搜索查找到该 DOM 节点对应的原生 WKChildScrollView 组件 将原生组件挂载到该 WKChildScrollView 节点上作为其子 View WebKit 内核已经处理了 WKChildScrollView 与对应 DOM 节点之间的层级关系
<embed id="web-plugin" type="plugin/video" width="750" height="600" />WebView 侧创建一个 embed DOM 节点并指定组件类型 chromium 内核会创建一个 WebPlugin 实例,并生成一个 RenderLayer Android 客户端初始化一个对应的原生组件 Android 客户端将原生组件的画面绘制到步骤 2 创建的 RenderLayer 所绑定的 SurfaceTexture 上 绘制完成后内核收到 SurfaceTexture 内容更新的通知,通知 chromium 内核渲染该 RenderLayer chromium 渲染该 embed 节点并上屏 当同层渲染的节点收到事件时,会将事件转发给 Native 组件模块处理。如果 Native 组件不消费事件,内核会再将事件向上冒泡
同层渲染常见问题
如果用户的设备没有微信自研的 chromium 内核,则会无法切换至同层渲染,此时会在组件初始化阶段触发 bindrendererror 事件。因此在必要时,根据该回调做好 UI 的 fallback。
iOS 端常见问题
如果在基础库创建同层节点时,节点发生了 WXSS 变化从而引起 WebKit 内核重排,此时可能会出现同层失败的现象。因此应尽量避免在原生组件上频繁修改节点的 WXSS 属性,尤其要尽量避免修改节点的 position 属性。如需对原生组件进行变换,建议使用 transform 而非修改节点的 position 属性。
由于原生组件层级比所有在 Webview 层渲染的普通组件都要高,因此通过同层渲染实现将原生组件直接渲染到 Webview 层级上,最终实现小程序层级的正确显示。关于原生组件的更多内容,请点击 官方文档 了解更多。