基于小程序技术栈的微信客户端跨平台实践

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、前言

小程序自诞生以来,经过两年多的发展,成为了微信开发者生态中最具有生命力的一环,为外部开发者开辟了全新的想象空间。然而,小程序带来的改变绝不仅限于微信之外,小程序技术栈的确立,又对微信客户端的研发产生了怎样的影响?

二、微信客户端的跨平台实践

微信客户端团队,早在 2012 年的时候就已经开始使用跨平台技术进行研发,从最初为了应对多平台客户端代码逻辑不统一的问题,到后续面向业务和 UI 开发,一直在尝试研发跨平台的解决方案。

最早的跨平台组件是基于 C99 开发的 mmnet,在 2012 年 10 月份的时候为了解决多平台客户端出现的一系列不一致问题而打造的基础网络组件,后续经过不断的迭代优化,尤其是在应对弱网络做了深度的优化,并且加入了安全、容灾等各种网络策略。mmnet 的通用部分逻辑代码于 2016 年以 mars 的名字在 github 开源,在业界获得了广泛的认可,完成了一个内部实验的跨平台组件到最终升华为所有人可用的开源项目。同样在 github 受到欢迎的还有相似思路完成的 wcdb、mmkv 等跨平台组件。

在完成基础组件的跨平台之后,随之而来的是面向业务和 UI 开发的跨平台尝试。为了面对内部快速变化的创新业务,微信客户端团队不得不去寻求在多端上快速迭代的开发模式。在业务开发的过程中,能否可以做到像使用基础跨平台组件那样,只写一次代码就能在多端上得到体验一致的 UI 功能界面呢?

在尝试了不同的方案之后,我们将目光放到了小程序上。在微信小程序快速发展的两年内,各内部业务团队开始基于小程序去做创新业务的开发。借助微信小程序框架,这些业务可以获得相比于纯原生客户端开发周期短、上线快的优势,同时可以满足较强的运营需求。这种基于微信小程序的业务开发模式在内部逐渐的受到认可。

我们认为好的跨平台开发模式必须要达到以下的四个目标:

∙减少平台差异性:应该最大限度减少不同平台上开发的差异性,尽可能减少各平台特有的开发负担;

∙提高研发效率:从研发效率的角度看,在提高人效比的同时,应该尽可能提升开发人员在开发过程中的效率,包括编码、调试、运行、测试等多个环节;

∙原生的性能和体验:从最终的研发产物看,应该有和分平台原生技术开发一样的性能表现和用户体验,让用户无法感知出差距;

易学的可控技术栈:跨平台的技术栈应该具有较好的学习曲线,能够让更多原生开发的同学快速学习并掌握,且无论从技术还是商业角度看,都应该是可控、安全的

技术栈。

那么,小程序技术栈是否能够满足这些要求呢?

三、小程序与微信客户端

微信小程序采用了以前端技术栈为主的方案,框架上面抹平了许多平台差异性,同时业务也可以随时动态部署更新,而体验和性能也比较接近原生。随着小程序生态的发展,还出现了更多丰富的插件扩展机制、自定义组件机制和第三方开发框架。同时,小程序作为微信团队内部自主研发的框架,小程序已经是一个非常优秀的跨平台框架,满足一般的业务开发是没有问题的。

然而,当我们以“小程序技术栈作为客户端跨平台开发技术”这一命题展开,关注其中的一些细节时,也发现了问题。

附近的餐厅就是微信团队内部基于小程序开发的一个类似原生体验的业务。通过小程序实现了一次开发运行在 iOS、Android 两个客户端上的功能。整个开发的过程都主要以微信小程序的开发工具和开发标准为主,配合客户端实现部分额外增补能力,在基本功能完成之后我们也发现了一些在 Android 平台上出现的问题,这里举两个比较典型的例子。

第一个是字体一致性体验问题。微信小程序使用 WebView 渲染,与原生客户端的是两套不同的视图渲染体系,在 Android 平台上出现了无法跟随系统字体保持一致的问题,体验上会有较为明显的割裂感。

第二个在大量的图片和视频混排的场景下,会出现一些掉帧现象,在 Android 中低端机上较为明显。如下图所示,在图片滑动等连续过程中,会偶尔出现 LAG 的情况。并且受目前小程序框架所限,视频、图片的全屏显示效果也不够理想。

正是因为微信小程序框架在面对复杂业务的场景下还会存在一些体验和性能不尽人意的地方,在性能和体验上虽然接近原生,但仍不能达到原生体验效果,我们决定针对这些细节尝试进

行一步步的优化。

先来看看小程序目前的系统架构。

四、基于小程序技术栈的跨平台开发

微信小程序的系统架构相信今天大部分的读者都比较熟悉了,总体来讲分为两部分:

1.View 视图端通过小程序的框架将用户采用 Wxmxxxxl 和 WXSS 描述的UI信息处理

成 H5 元素,最终交给 WebView 去渲染;

2.App Service 端运行用户编写的 jaxxxxvascxxxxript 逻辑,并且可以调用具有微信开放

能力的 JSAPI。逻辑和视图分离,通过事件和数据彼此之间建立联系。

回到我们上面的问题,在中低端机和稍复杂的业务上,受制于 Web 庞大而复杂的体系,要达到原生视图体系这样简单设计的体验,难度很高。那么是否能够使用平台原生的视图渲染体系来解决问题呢?

1. 基于原生渲染优化

原理上我们可以将用户描述的 UI,转换成系统原生的组件,行业里面早有实践,受到ReactNative 这类框架的启发,我们将小程序的视图端进行了一些改造,在 Android 平台上我们 dump 出小程序框架中 Virtual DOM 的信息和所有的 CSS 样式,在 Java 层逐一的去解析映射成原生的组件。但原生体系并不能完全的表达过于复杂的 CSS 样式,因此前期只支持了部分的 WXSS 特性。

2. LV-CPP

我们初步方案当中有太多的实现一开始是用 Java 去做的,考虑平台兼容问题,为了方便移植到其他平台以及可以更低成本的更换渲染模块,我们就将原来解析 DOM 和 CSS 样式的实现单独抽离了出来,形成一个独立的跨平台模块。最终选择了 C++ 实现的 LV-CPP 模块,由LV-CPP 去做跨平台的小程序 UI 体系处理器,完成 DOM 和 CSS 的解析、布局计算,同时执行 JS 的功能由 V8 或者 JSCore 来完成。

当 Wxmxxxxl/WXSS 描述的 UI 发生改变时,小程序前端公共库(WXA frxxxxamework)通过内部计算,将 Virtual DOM 树 Diff 的结果以操作指令的形式提交到 LV-CPP。LV-CPP 接收指令后,更新相应的节点,进行 CSS 的匹配、CSS 属性的转换以及布局的计算,计算好之后再调用 Native View 进行界面的渲染。

CSS 匹配上,目前支持了 ID 选择器(#id)、标签选择器(button)、类选择器(.class)、组合选择器(AB、A B、A>B、A+B、A~B)。为了提高性能,其中组合选择器的匹配使用了 WebKit 的逆序解析方案。

之所以在 LV-CPP 中进行 CSS 属性的转换以及布局计算,目的是为了尽量抹平以后即使使用不同的渲染模块所带来的属性和布局上的差异。最典型的是颜色的转换。CSS 中颜色有各种表示方法,最常见的有:

1.十六进制颜色,如:#0000ff

2.RGB 颜色,如:rgb(00255)

3.RGBA 颜色,如:rgba(255000.5)

4.HSL 颜色,如:hsl(12065%75%)

相关文档
最新文档