![4f8209e2f9d93824e8e3ace7f3b08ce9.png](https://i-blog.csdnimg.cn/blog_migrate/efc4b728024574e625299f4180276cd3.png)
效果展示
先看Demo视频,对比App内常规的H5播放体验和使用同层渲染视频组件后的H5页面播放体验:
常规H5 <video/>播放体验
![8cdd602b3bc0227e0ecd7fd285294bda.png](https://i-blog.csdnimg.cn/blog_migrate/ba3de5658cfad40048ee7167244cf8c6.jpeg)
使用同层渲染视频组件后H5页面的播放体验
![eabc0cf0faf7f6b15a99b6cbffd31ba0.png](https://i-blog.csdnimg.cn/blog_migrate/544366d7e22f3da2ce50241708a7eb4a.png)
使用同层渲染视频组件后H5页面播放器手势交互
![c75e4b3e310591a2686a5f4dcd28a8d2.png](https://i-blog.csdnimg.cn/blog_migrate/f78502d2af6b2e7ad1350f0c20260408.jpeg)
众所周知,H5 <video/> 标签的播放体验有诸多限制:iPhone设备上不能自动播放,全屏时无法横屏播放,退出全屏时播放自动暂停了,能响应的手势有限。 和原生端实现的播放器相比,交互和体验确差距很大。
小程序在刚问世时,就提供了原生组件,针对强交互场景,如视频播放,文本输入框、地图组件等,原生组件为小程序带来了更丰富的特性和更高的性能。既然微信小程序框架可以通过同层渲染原生组件,提升小程序页面的交互体验,那作为H5容器的开发者,可否让普通H5页面像小程序页面一样,也能具有使用原生组件的能力呢?
这就引入了本文的主题:支持原生组件同层渲染的H5容器。
技术实现
微信团队公开了小程序同层渲染原理:《微信小程序同层渲染原理剖析》,iOS端主要原理如下:
当把一个 DOM 节点的 CSS 属性设置为 overflow: scroll 之后,WKWebView 会为其生成一个 WKChildScrollView,与 DOM 节点存在映射关系,这是一个原生的 UIScrollView的子类,也就是说 WKWebView 里的滚动实际上是由真正的原生滚动组件来承载的。小程序 iOS 端的「同层渲染」也正是基于 WKChildScrollView 实现的,原生组件在 attached 之后会直接挂载到预先创建好的 WKChildScrollView 容器下,大致的流程如下:
1. 创建一个 DOM 节点并设置其 CSS 属性为 overflow: scroll ;
2. 通知客户端查找到该 DOM 节点对应的原生 WKChildScrollView 组件
3. 将原生组件挂载到该 WKChildScrollView 节点上作为其子 View。
其中第1步是JS做的,第2步是小程序webview容器自行处理,第3步是 JS 和 webview 容器协作完成。
// TODO 未完待续
一些关键细节:
- 捕获WKChildScrollView实例,并和网页 DomTree 中具体设置了overflow:sroll;属性的DOM节点一一关联
- 让原生播放器 PlayerView 接收Touch事件并解决与WKWebView 上的手势冲突问题
- 原生播放器PlayerView 生命周期管理
Demo 运行时 HTMLDOMTree
![c71086380a7ff0f08b7227b87f3c021c.png](https://i-blog.csdnimg.cn/blog_migrate/c3d5db0406b31eaf27a609dc1f26ca4a.jpeg)
Demo 运行时 iOSViewHierarchy
![593e8fe9fb0e0c09168ac485c8267bfc.png](https://i-blog.csdnimg.cn/blog_migrate/6122d4072a55112c83b9a7c096fb50be.jpeg)
产品化开发需要按照 Web Component 规范将同层渲染播放器组件暴露给JS 同学使用。如下图所示百度小程序运行时DOM 树截图,虽然小程序开发者使用的仍然是<video/>标签,但最终生成的DOM树中使用的是自定义标签<swan-video>节点:
![374653e04aaab4fcd72b1617674206f5.png](https://i-blog.csdnimg.cn/blog_migrate/a32446601b28f539f831f379acc849ca.jpeg)
从上图也可以看出,小程序组件其实都是使用Web Component封装的。所以给H5页面开发同学提供 同层渲染Video组件时,将会提供一个新的自定义标签。
除了视频播放器,H5 页面的 input/textarea 组件交互体验也很差,使用同层渲染来技术桥接原生UITextField/UITextView 组件将会明显提升H5页面上用户和软键盘交互体验。