订阅业界RSS CSDN首页> 业界

【必看干货】快应用开发体验与技术架构深度解析!

发表于2018-07-06 18:16| 来源互联网| 作者广告代理

摘要:快应用是基于手机硬件平台的新型应用形态,它根植于ROM级别,具备传统APP完整的应用体验。第三方应用基于这种形态可以更为直接的触达用户,为用户带来高效愉快的体验。

背景介绍

快应用是基于手机硬件平台的新型应用形态,它根植于ROM级别,具备传统APP完整的应用体验。第三方应用基于这种形态可以更为直接的触达用户,为用户带来高效愉快的体验。

快应用的目标是:

1. 即点即用:无需漫长的下载,无需安装等待;

2. 重视体验:用户使用流畅无阻,用完即走。

当然,要实现这样的美好目标,还需要和众多友商众志成城、齐心协力把新的分发形态做起来。所以,今年(2018年)3月20号,小米等国内众多主流手机厂商成立了快应用联盟,共同宣布快应用的诞生。同时在技术规范层面统一标准,实现资源共享,能力输出;最终把快应用框架的能力覆盖到国内主流厂商的手机硬件平台上。目前,快应用已在众多手机设备中上线与使用,且快应用已拥有非常多系统级流量入口:浏览器搜索,全局搜索,应用商店,小爱语音唤醒等。

那么快应用技术架构如何选型呢?

我们调研了当前移动端应用存在的两大形态:移动网页、原生应用。两者各有以下优缺点:移动网页无需安装,但用户体验较差,同时很多系统功能缺失。原生应用用户体验较好,但由于应用通常是一次性下发的,且体积很大。对用户而言,获取的成本比较高,等待时间过长,体验不好;也导致应用的孤岛现象十分严重,互联互通程度非常低,用户很难无缝跳转衔接到各个应用。对开发者而言,版本碎片化程度较高,增加了维护成本。

快应用在做技术架构的选型时,充分对比了现有生态在技术上的优势和不足,采用了全新的技术架构,从根本上解决了现有生态在技术上的不足。因此,快应用介于移动网页和原生应用之间,第三方应用以移动网页的形式进行开发,最终得到原生渲染的效果体验。

开发体验

听过deno项目的开发者,应该会了解下面的配图,这也从侧面反映了开发者对于新技术的担心与疲倦。所以,我们借助于国内庞大的前端开发者群体,用前端开发的形式,来提高开发效率。也就是说,快应用的开发从前端入手,作为解决方案的起点。

接下来,我们以前端最为著名的TodoMVC需求为例,展示对应的快应用实现;整个页面的源代码只有不到200行,可在GitHub(地址:https://github.com/quickappcn/todos)下载查看。

传统的H5页面开发,开发者先利用脚手架生成项目,然后经历如下的过程:

1. 根据设计稿,编写静态页面;

2. 为页面添加样式;

3. 编写JS,增加交互逻辑;

4. 利用mock数据渲染模板;

5. 自测无误后,与后端同学联调,调试代码;

最后多次迭代后完成项目的开发。

快应用的开发流程与H5非常相似,大概对比如下图:

案例分享

以TodoMVC为例,大概介绍快应用的开发流程:

首先,准备一个初始项目,这块可以使用脚手架工具直接生成项目。

仅需三大步:安装NodeJS;全局npm安装hap-toolkit;运行命令hap init、npm install以及npm run build,就可以构建出一个rpk文件;手机的快应用平台即可安装运行这个rpk文件,呈现为应用。

01、编写静态页面

快应用的静态页面与传统H5页面类似,由template模板、style样式和script脚本3个部分组成。

02、补充页面样式

快应用为开发者提供了flex布局模型,也支持常用的CSS属性,如:width, color等,可以在<style>中使用简单与后代选择器快速定位到元素。

需要开发者注意的是:为了做到高效布局,快应用暂不支持其它的布局模型;同时并不像浏览器一样,支持全部的CSS属性,如:table布局。

03、系统能力

传统H5开发中,开发者通过AJAX请求向服务器获取数据。在快应用中,开发者可以通过ES6的import语法来引入一项系统能力,称为native接口,并调用接口方法完成功能实现,这里支持同步、异步、订阅三种类型的操作。

04、模板渲染

快应用的<template>中用于定义模板片段,可通过使用for、if、show等指令实现循环、条件等逻辑,也可以使用block、slot等占位节点实现更为灵活的模板复用。

05、事件响应

当页面需要响应用户操作(如:click)时,开发者可以在对应的元素上注册事件,并绑定监听函数。

为了方便开发者,快应用提供了MVVM形式的编程模式,做到数据驱动式的开发方式。

同时由于快应用涉及到页面之间数据传递,因此定义了数据访问权限的模型,如:public代表属性对外公开可被覆盖,protected代表仅应用内页面可覆盖,private代表不可覆盖。

06、生命周期

快应用中的每个页面都有创建、销毁、可见性等生命周期,方便资源的请求与释放,同时也提供一些手机按键的操作响应,如:返回。

07、组件化

当一个页面的业务逻辑变得复杂时,就需要将页面拆成多个模块,完成解耦。所以,快应用提供了自定义组件的能力,定义自定义组件与开发页面一致,开发者可以通过import标签引入自定义组件达到目的。

08、原生组件

为了更好的体验与性能,快应用提供了很多高阶组件,浏览器不会直接提供这些组件,如:list组件、tabs组件、refresh组件。相当于平台内置了一套成熟的UI组件库,开发者可通过合理使用这些组件,提高开发效率、优化用户体验。 

09、引入动画

当然,开发者也可以使用动画来优化交互体验。

至此,我们就足以开发一款简单的快应用产品。

为了方便发现问题、解决问题,开发者可以使用devtools工具来调试代码,这块与浏览器调试很相似:

1. 通过Elements查看DOM结构;

2. 通过Style面板修改样式;

3. 通过Source调试JS代码;

4. 开发者也可以在console中查看日志输出。

开发者仅需上面的几个步骤就可以完成TodoMVC的开发,这些步骤是渐进式的,每一步都可以实时看到效果。

总结来说,开发者只需要有一些:前端基本概念、MVVM编程模式、组件化思维即可上手快应用的开发。

架构概述

那么面对上述的诸多功能,快应用团队是如何实现的呢?

整体上,我们将快应用实现划分为编译时、运行时两个方面;ux页面源码经过编译时得到JS,然后经过运行时得到界面UI;每一个页面由HTML+CSS+JS组成,编译运行后得到内存中的DOM树;多个页面组成一个项目,编译后得到rpk文件,最终运行时以应用形态呈现。

编译时,我们对外提供一个hap-toolkit工具,内部会包含多个模块:

1. 脚手架:提供脚手架的模板,用作项目初始化以及全局命令;

2. 编译器:解析页面的模板、样式等,完成数据校验、转换,最终拼接生成JS文件;

3. 调试器,服务器:提供HTTP服务器,完成与手机运行平台的交互,如:下载rpk包。

运行时内部是一个庞大的系统,简单来说,大致会分为以下几个模块(自底向上):

1. JS引擎:负责开发者JS代码的执行;

2. 渲染引擎:也称为布局引擎,承担原生组件的布局计算;

3. UI组件库:很多个原生组件,以及相互配合组成原生UI组件库;

4. 原生接口:提供系统能力与第三方服务,如:fetch请求,微信支付等;

5. 框架层面:提供应用与页面管理,数据驱动的能力等。

JS层位于运行时的框架顶层,也是开发者可感知的模块,在JS层的框架内部,又细分了多个层次(自底向上):

1. 基础能力:提供日志、组件、接口的元信息管理与通信机制,如:组件与接口包装,回调机制,序列化;

2. 应用管理:提供可以复用的模块,如:应用与页面管理、生命周期、DOM模型、样式计算等;

3. 框架输出:提供一般常见框架的基本能力建设,如:MVVM模式、数据驱动、组件化语义化等。

快应用与主流框架在DOM渲染上存在差异:

传统运行主流前端框架(如:React、Vue、Angular)的浏览器,其实拥有两个DOM模型:

1.  浏览器自身的DOM结构:用于后面页面的布局、绘制;

2.  框架实现的VDOM结构:用于实现数据驱动能力;

快应用将两个DOM模型合二为一,降低复杂度的同时也实现了数据驱动的能力。简单来说:开发者看到的源码中DOM层次结构并非框架所提供的DOM层次结构,如下图所示。

当模板中存在for、if指令或占位节点时,快应用的DOM中会拥有逻辑控制节点,这些节点不参与底层渲染,但会作为DOM树中的一个节点存在。这些节点类似于浏览器中的DocumentFragment,是一段DOM片段,但DocumentFragment不存在于DOM树中,所以为了区别开来,我们称之为Figment。

此外,与其它主流框架不一致的地方在于,快应用拥有样式计算的能力;在支持CSS基础选择器(如:tag、class、id、inline)的同时,增加了对后代选择器的支持;提高开发者效率的同时摒弃了性能上可能带来影响的其他类型,如:兄弟选择,通用选择等。

快应用的Android底层不支持样式计算,某个节点最终拥有的样式,由JS层计算并告知底层。

实现主要分为三步:

1. 样式表初始化:解析样式对象,并确定各个样式规则的优先级;

2. 元素更新记录:元素更新时,重新计算元素对应的样式,为了减少性能损耗,我们会使用一系列的缓存与计算规则来处理,如:修改class不会触发对该节点在tag/id/inline的计算,缓存元素子节点上的样式规则;

3. 合并元素样式:只有在元素序列化时才触发最终的合并操作,避免中间多次修改带来的重复计算。

关于快应用是如何渲染页面的过程,主要包括四个步骤,他们是由JS与UI两个线程完成的:

1. 创建页面:完成路由能力,管理页面栈;这部分主要发生在native的UI线程;

2. 建立DOM模型:创建Document,数据驱动化,模板编译,DOM节点生成与序列化;这部分发生在JS线程;

3. 节点转换布局:完成节点到native view的映射,并进行布局模型的计算;这部分发生在native端的UI线程;

4. 绘制渲染:脏标识,绘制视图,并最终完成渲染能力;这部分发生在Android OS层。

总结来讲,快应用的JS框架,对外主要完成三件事:

1. 数据驱动:输出MVVM的开发能力;

2. DOM模型:提供元素管理的能力,并计算样式;

3. 应用管理:提供针对应用级别、页面级别的生命周期等。

结尾

以上为本次分享的全部内容。

回顾一下,前者主要介绍快应用的开发形态,为感兴趣的开发者提供具体的例子来逐步阐述开发方式;后者主要围绕实现架构做一个简单概述,并介绍JS框架的核心功能与其它主流框架的异同点,为以后的项目创新提供思路,也希望今后的新型平台也能向声明式开发、容易上手、性能体验优异的角度去发展。

感兴趣并想深入了解的开发者,可以通过本公众号联系我们,感谢支持!

0
0