NView模板概述 - wap2app教程

什么是subNView

subNView,字面拆开理解就是sub native view,有两个核心点:

  • native:subNView是一种原生绘制的View,和HTML5的DOM无关
  • sub:subNView属于webview的一部分,并不替代完整Webview。和所属webview保持同样的生命周期,跟随webview的close、hide、zindex变化而变化。

subNView作为webview的子控件,一个webview可以包含多个subNView,一个subNView上可以绘制多个图片(包括图片轮播)、文字、区域、按钮等。

subNView希望解决什么问题

web页面加载渲染速度相比原生App,有较大的体验差距,以至于在移动设备上严重影响业务体验。这些体验差距是如何造成的呢?原因大致有如下几个:

  • 渲染时机:web app需要等待服务端Document下载完成后才可启动渲染工作,无法分区域渲染;而原生App作为C/S结构的应用,仅向服务端请求业务数据,其它布局、样式大多在本地,故可以在用户触发打开新窗口时,立即渲染新窗口部分区域布局,服务端响应数据后,再更新对应区域的内容;
  • 图片资源请求时机:web app需要先下载Document,然后再根据Document中的标签的src属性去异步加载图片资源,故在web app中总是先看到文字,然后再逐渐看到图片;而原生App则无需任务等待,可以直接加载图片资源,故原生App的图片显示会早于web app中的图片显示;
  • 业务数据请求时机:web app的实现若是前后端分离,则需要先下载封装业务逻辑的js文件,下载完毕后,再由js发起ajax请求;而原生App,则大多将业务逻辑封装在本地,无需等待下载js文件,可以更早的发起HTTP业务请求

如何提升web页面的渲染速度,很多公司都在尝试,比如Google主导的AMP技术,AMP技术以阅读类网页加速为主,适用范围有限。

而subNView,则是一种更为通用、可增强任意web页面渲染体验的技术;subNView在保留HTML5优势的基础上,在webview中增加了一个原生view子控件,利用原生View发挥原生渲染优势;当用户触发时,webview按照原有逻辑,继续加载Document,渲染页面;但无需等待Document加载完成,可同时在原生View上完成如下工作:

  • 绘制固定内容区域,或可从前页获取数据的区域,例如固定地址图片、购物车按钮等,而无需等待Document下载完毕后再去请求加载图片
  • 直接发起业务数据ajax请求,ajax响应后直接在原生View上绘制数据,无需等待业务封装的JS下载

如下为一个使用subNView增强后的商品详情页示例:概述 - 图1

从上图可看出:

  • webview按照原有逻辑,加载Document,渲染页面,刚开始内容未加载时还是白屏(中间空白区域)
  • webview同时创建了2个subNView作为webview的子控件
  • subNView 1展示商品详情轮播图及商品价格,是通过ajax动态获取的;轮播图片支持滑动、点击放大预览,用户可提前查看商品详情
  • subNView 2展示购物车相关功能,属于固定显示内容,可直接渲染
  • 购物车按钮点击后事件透传给Webview里的购物车按钮,HTML页面的所有逻辑,仍然复用。subNView只是简单的侵入动画渲染过程,不引发业务逻辑的重新编写。

如何使用subNView

开发者可以通过webview的subNViews属性创建或修改subNview控件,这里需要传入复杂的json对象;为简化开发,DCloud提供了NView模板技术。

NView模板

NView模板类似于vue的single-file components(单文件组件),HBuilder中新建NView模板文件,默认代码如下:

  1. <template>
  2. <nviews cachemaxage="86400">
  3. </nviews>
  4. </template>
  5. <script>
  6. module.exports = {
  7. data: {
  8. //默认数据
  9. },
  10. init: function(url) {
  11. //动态初始化数据
  12. },
  13. methods: {
  14. //方法
  15. }
  16. };
  17. </script>

需要注意的是,在节点下仅可以使用受限制的NView HTML,详细参考后续章节介绍

FAQ

Q: 既然有了nview机制,为何不使用nview完成所有业务,而是作为HTML5的补充?A:其实这就是subNView前缀是sub的原因之一。DCloud认为HTML5虽然有功能和性能问题,但面对问题进行强化即可,无需推翻HTML5重新来一套。在HTML5生态中,有太多精彩的、现成的东西,开发者想要复用之前的HTML5,自然也应该使用subNView强化。而完全使用nview将导致重写所有业务逻辑,后续也要维护多套版本。总结一下:subNView的定位就是解决HTML5页面渲染慢的问题,做些简单的界面显示工作,在动画期间就给用户显示部分内容。而完整的业务逻辑处理,仍然在HTML页面里处理。

Q: 为何在wap2app里能使用nview模板,而5+app里不能使用?A:首先nview在5+里是一直存在的,wap2app是基于5+的上层框架,没有脱离5+范畴。参考plus.nativeObj.nview的api。但通过5+的js api写titleNView很简单,但写复杂的subnview,开发体验不太好,于是我们在wap2app里对subnview引入了nview模板式写法,提升开发体验。所以其实5+app也可以使用nview,只是暂时不能通过模板式写法来写,要写js api。5+里引入nview模板写法,我们后续会补充,但这个工作优先级不高。开发者可能误以为5+里也应该大量使用subNView提升体验,但其实不需要。但nview在5+app里最常用的是title和tab,中间使用subnview的场景很少。为啥5+app不太需要使用subnview呢?因为如果你的代码写的不烂,本地的HTML页面加载是非常快的,在新窗体载入时,只是联网取ajax数据,和cs的原生应用一致。这种情况下引入subnview,不会对内存、流畅度提供帮助,反而增加了工程的复杂度、降低了界面的灵活度(nview的排版灵活性比HTML还是差很多的)。但在wap2app里,HTML不是本地的,在线加载HTML并渲染的速度太慢了,所以subnview的加持非常必要。没仔细研究的人,肯定认为原生部分越多越好,其实事实并非如此,HTML5已经解决好的问题,引入原生多此一举。所以在5+app里,nview更重要的用途是做标题栏和底部tab,减少双Webview的使用。