139-8950-0275

绍兴云远网络热线
首页 >> 小程序 >>小程序专业知识 >> 直播小程序弹幕不见了?同层渲染来看看!-绍兴抖音短视频直播商城开发为你呈现
详细内容

直播小程序弹幕不见了?同层渲染来看看!-绍兴抖音短视频直播商城开发为你呈现

时间:2022-05-23     作者:绍兴抖音短视频直播商城开发【转载】   来自:微信派

腾讯营销产品部研发工程师 rileycai 原创



riley!我在测试阶段没看到直播弹幕?


riley!我刚刚测试上架直播间产品,同事都说看不见!


riley!测试小哥哥反馈购物车消失了,急求解决办法

怎么会这样?!究竟是哪里出了问题?图片


随着小程序生态的蓬勃发展,小程序逐渐成为获客营销的新渠道,直播业务也能够通过小程序触达用户。然而,直播小程序开发并不是一件容易的事情,例如直播小程序变成 “纯净模式”,即只看到直播页面,却无法看到弹幕、产品链接、购物车等信息。这个难题应该如何解决呢?


经过技术检查,直播小程序 “纯净模式” 问题出现在对原生组件的层级应用,通过同层渲染的方法即可实现高效处理。






原生组件惹的祸?


在内置组件中,有一类组件较为特殊,它们并不完全在 Exparser 的渲染体系下,而是由客户端原生参与组件的渲染,这类组件称为 「原生组件」,例如小程序中的 live-player、canvas、map 等都是原生组件。



引入原生组件主要有 3 个好处:


  1. 扩展 Web 的能力:例如输入框组件 input、textarea 有更好的控制键盘能力
  2. 减轻 WebView 的渲染工作:例如地图组件 map 这类较复杂的组件,其渲染工作不占用 WebView 线程,而交给更高效的客户端原生处理
  3. 绕过 setData、数据通信和重渲染流程,渲染性能更好:例如画布组件 canvas 可直接用一套丰富的绘图接口进行绘制



然而原生组件也存在一定的限制。由于原生组件脱离在 Webview 渲染流程外,因此其层级是最高的。页面中的其他组件无论设置 z-index 为多少,都无法盖在原生组件上面。后插入的原生组件可以覆盖之前的原生组件。

例如下左图所示,非原生组件位于 WebView 层,而原生组件及 cover-view、cover-image 位于另一个较高的层级。所以 live-player 组件把其他业务组件都覆盖了,导致部分用户只能看到 “纯净模式”。


image.png

明晰原理后,解决这个问题的方法就是需要把原生组件直接渲染到 WebView 层级上面,即通过微信团队制定的「同层渲染」解决方案实现层级合理安排。例如正如上右图所示,通过同层渲染,原生组件层已经不存在,原生组件被直接挂载到 WebView 节点上。






同层渲染来解惑!


为了解决原生组件的层级问题,同时尽可能保留原生组件的优势,微信团队提出 同层渲染,即控件并非绘制在原生组件贴片层,而是绘制在 WebView 所渲染的页面中,与其他 HTML 控件在同一层级。支持同层渲染后,原生组件与其它 H5 组件可以随意叠加,层级的限制将不复存在。

了解同层渲染的优势后,如何合理应用同层渲染,实现层级合理应用?基于同层渲染在 iOS 和 Android 平台下的实现不同,以下分别介绍两个平台的实现方案。



iOS 端实现方案
小程序 iOS 端的同层渲染基于 WKChildScrollView 实现,原生组件在 attached 之后会直接挂载到预先创建好的 WKChildScrollView 容器下,大致的流程如下:


  1. 小程序前端在 webview 内创建一个 DOM 节点并设置其 CSS 属性为 overflow: hidden 且 -webkit-overflow-scrolling: touch,生成一个containerId,并将这个 WKChildScrollView 的位置信息通知给客户端
  2. 前端通知客户端递归搜索查找到该 DOM 节点对应的原生 WKChildScrollView 组件
  3. 将原生组件挂载到该 WKChildScrollView 节点上作为其子 View
  4. WebKit 内核已经处理了 WKChildScrollView 与对应 DOM 节点之间的层级关系

通过上述流程,小程序的原生组件就被插入到 WKChildScrollView,即是在步骤 1 创建的 DOM 节点映射的原生 WKChildScrollView 节点。此时,修改这个 DOM 节点的样式属性同样也会应用到原生组件上。因此,同层渲染的原生组件与普通的 H5 组件表现并无二致。



Android 端实现方案
Android 端需要经历「解析-排版-绘制-合成」的内核渲染过程,从构建 DOM Tree到最终将 Layer 按照一定的顺序合成在一起,交给系统的 Frame Buffer,实现输出到屏幕上。


Android 端内核渲染过程


从内核渲染流程可以看出,实现原生组件同层渲染,需要将原生组件作为一个Layer 插入到 Layer Tree。如果能够将原生组件渲染到内核提供的 Texture 上,就可达到同层渲染的目的。Android 端的同层渲染就是基于 <embed /> 标签结合 chromium 内核扩展来实现的, 大致流程如下:


  1. WebView 侧创建一个 embed DOM 节点并指定组件类型
  2. chromium 内核会创建一个 WebPlugin 实例,并生成一个 RenderLayer
  3. Android 客户端初始化一个对应的原生组件
  4. Android 客户端将原生组件的画面绘制到步骤 2 创建的 RenderLayer 所绑定的 SurfaceTexture 上
  5. 绘制完成后内核收到 SurfaceTexture 内容更新的通知,通知 chromium 内核渲染该 RenderLayer
  6. chromium 渲染该 embed 节点并上屏
  7. 当同层渲染的节点收到事件时,会将事件转发给 Native 组件模块处理。如果 Native 组件不消费事件,内核会再将事件向上冒泡

通过以上流程,实现把一个原生组件渲染到 WebView 上,相当于给 WebView 添加一个外置的插件。






同层渲染常见问题

Android 端常见问题


如果用户的设备没有微信自研的 chromium 内核,则会无法切换至同层渲染,此时会在组件初始化阶段触发 bindrendererror 事件。因此在必要时,根据该回调做好 UI 的 fallback。


iOS 端常见问题

如果在基础库创建同层节点时,节点发生了 WXSS 变化从而引起 WebKit 内核重排,此时可能会出现同层失败的现象。因此应尽量避免在原生组件上频繁修改节点的 WXSS 属性,尤其要尽量避免修改节点的 position 属性。如需对原生组件进行变换,建议使用 transform 而非修改节点的 position 属性。

由于原生组件层级比所有在 Webview 层渲染的普通组件都要高,因此通过同层渲染实现将原生组件直接渲染到 Webview 层级上,最终实现小程序层级的正确显示。关于原生组件的更多内容,请点击 官方文档 了解更多。



如有其他小程序应用相关的问题,可在 微信开放社区小程序交流专区 发帖互动,技术专员将为大家解答及进行深度交流。

技术支持: 杭州云远科技有限公司 | 管理登录
seo seo