Skip to content

common Introduction

zhangyanqiang edited this page Apr 26, 2018 · 1 revision

爱奇艺小程序框架优化

WebView 和 Native 开发的问题

在移动应用程序开发中,我们一直以来用各种方式追求动态性和用户体验的平衡。

Web View 加载纯Web前端页面的方案是动态性的极端体现,能够保证完全的动态性,但是加载速度受到很多方面的限制。

  • WebView 加载的网页和资源需要从前端服务器下载
  • WebView 启动时需要进行加载浏览器内核等操作
  • WebView 加载的网页业务一般和前端框架一起加载,其中框架部分是大部分冗余的
  • WebView 业务逻辑运行和网页渲染是串行的,较重的业务逻辑会造成卡顿

纯 Native 开发和 ReactNative 等混合框架的开发则遇到动态性不足的问题。

  • 纯 Native 动态加载,在 Android 和 IOS 商店中不允许上架
  • ReactNative 不能灵活选用前端框架,既有前端代码无法使用
  • 没有权限限制,与第三方联合开发时无法防御来自第三方的攻击

我们设计了爱奇艺小程序框架,尝试平衡动态性和加载速度,目标是通过合理的架构设计,使用非首次加载时的户体验达到和原生开发类似的性能,同时支持业务逻辑与框架代码的动态发布和选用,在少量工程结构调整后移植复用既有前端代码。

加载优化-框架预载式容器缓存

大多数 Webview 基础的容器技术重点在于缓存,在我们对容器业务的优化中,把容器本身的优化放在重要位置。主要承担加载过程优化指标。

静态缓存

静态缓存指 WebView 需加载资源的提前下载。主流方法分为程序包维度的缓存和文件维度的缓存。在我们的应用场景中,包维度的缓存在体验上和发布效率上有明显的优势

  • 包维度缓存支持灰度测试,版本管理比文件维度方便
  • 包维度缓存可以做到后端渲染预置,例如随包预置用户头像主题
  • 框架规定小程序包统一使用一个前端框架版本,有效防止框架碎片化

结合既有的前端发布管理系统,(我们在开源版本中提供了定制接口)我们能够简单地实现小程序包缓存和版本管理。

动态缓存

动态缓冲指运行时 WebView 本身和内部逻辑的提前加载与运行。请结合小程序生命周期架构理解。我们在开发过程中首先进行 WebView 自身提前加载,在低端Android机上将页面启动时间缩短到 200 ms 内。

我们进一步注意到,在WebView自身加载到业务逻辑执行间,有一段 50 ms 左右的时间用来加载前端框架。而在小程序包运行中,我们可以大致地推定下一个页面所使用的前端框架大概率与之前页面的前端框架是一个版本。因此,我们在容器动态缓冲过程中也执行前端框架的加载。

业务-框架版本管理

框架不可能不变,在传统前端开发中,站点往往在不同部分使用不同版本的框架,最终导致网站架构碎片话,大量加载冗余代码。在小程序框架中,我们允许小程序包指定自身需要的框架包,当框架包本地已有时直接复用既有框架包,当本地没有对应框架时才从包管理系统网络获取框架包。理论上一个App集成小程序框架后应该又一个框架版本主线,各个小程序业务尽快跟随主线升级,在主线顶点的框架版本可以享受到框架提前加载的动态缓存加速。

执行优化-业务逻辑执行器

独立的业务逻辑执行器是小程序框架的另一个创新,主要解决在页面运行时或加载时执行繁重业务逻辑的卡顿问题。我们剥离了前端框架的API部分,并放置到一个单独运行的 Javascript 执行器中。这一优化解决了页面 JS 执行时滑动操作卡顿的问题,并且使得 Native 开发者可以直接向 Javascript 执行器添加 Bridge 方法或对象,而不需要考虑 Web View 平台差异性,保证了 IOS 和 Android 原生调用接口统一。

Patch-Diff 模式

当前流行的前端框架使用Patch-Diff模式驱动页面。这一模式允许业务逻辑和页面渲染的简单分离。我们选择 PatchDispatch 切面分离代码执行器和WebView渲染器。从而封装比较完整的前端框架。业务开发方仅需改变打包方式,即可兼容既有前端代码。

推荐框架

我们在Demo中使用 Vue 框架改造的小程序框架,因此完全兼容 Vue 语法,可以复用 Vue 既有代码开发小程序。

并发启动

在Patch-Diff模式中,我们在实现时缓存 Patch 到 PatchQueue,等待 Web View 渲染器中的框架加载完毕后再逐个读取 Patch 并执行,这一改造,使得小程序启动的两个重要组件,业务逻辑执行器和 WebView 渲染器可以分别并行加载,甚至在 Web View 启动前就执行业务逻辑并给出 Patch。

Clone this wiki locally