乐趣区

关于程序员:百度智能小程序框架性能优化实践

浏览原文

导读:明天给大家讲的题目是《百度开源小程序框架架构演进和性能优化实际》。本次分享蕴含两局部,第一局部是百度智能小程序整体的框架及演进,次要讲百度小程序开发全流程详情、百度智能小程序框架,以及百度小程序多宿主运行保障;第二局部是百度小程序框架的性能优化,次要讲整个小程序的启动过程,以及从开发者角度,有哪些重要的优化点。

一、百度智能程序整体框架及演进

整个挪动互联网始终是在 NA 和 H5 之间寻找衡量,NA 的性能好、能力强;H5 灵活性更高。我认为渲染分为两派,一派就是 NA 渲染派,一派叫做 H5 渲染派。

NA 渲染派,比拟有代表性的如 RN、Flutter;Web 渲染派,比方百度的轻利用,以及之后做的小程序。

1. 开发全流程概览

百度已经做过的 Web 渲染派的三个代表产品,别离是轻利用、中转号和小程序。

  • 轻利用,是 H5 + 端能力。它是一个规范的 H5,减少了一些 NA 的 API,比方定位等。
  • 中转号,在技术层面跟轻利用是一样的。
  • 小程序,实质上是一个受限的 H5 + 大量丰盛的 API + UI 组件。当初咱们给小程序提供的 API 有 300 多个,组件有 30 多个,组件是有界面的。比方,视频、地图。

为什么小程序要受限,次要有两个起因:

  • 放弃体验的一致性。H5 太过灵便,JS 随时能够去扭转界面。
  • 平安思考。因为咱们提供了大量 API 和组件,且这些都是很底层的一些能力,比方电话号码、账号,必定不能轻易凋谢给大家。

怎么受限,次要有两点:

  • 编写语言,不再是间接写 HTML,而是用自定义语言 swan 来编写。
  • runtime 层有两个栈,一个是渲染栈,一个是 JS 执行栈,这两个栈从物理上隔离,以保障安全性。

2. 智能小程序框架

(1)开发运行全流程

先简略介绍一下整个百度智能小程序的开发流程。

  • 首先开发者用 swan 写布局;
  • 接着通过开发者工具打包,上传到咱们的小程序 B 端服务器;
  • 而后是小程序的审核流程,有机审、人审;
  • 最初是用户点击小程序时,客户端申请小程序 C 端服务器,C 端服务器再从 B 端服务器获取小程序包。整个过程都是加密传输,能够保障代码的平安。

(2)百度智能小程序框架 -SWAN

上图是一个百度智能小程序的框架,咱们外部命名为SWAN

分层构造如下:

  • 最上层是开发者根底库,命名为 swan-js,开发者间接和这层打交道。swan-js 负责两件事件:即 swan 代码转为 HTML,变成 WebView 可运行程序;客户端端能力的封装裸露。
  • 再下一层是 swan-native。这外面最外围的是 API 和组件的 NA 实现。其中双栈治理也在这一层,另外标红的 Extension 用于开发者宿主本身能力扩大应用,比方,贴吧宿主冀望减少个发帖能力,就能够通过此机制。
  • 再上面这层叫 Porting Layer。这层是百度小程序为了实现开源,减少的一层与宿主的接口层。最上面这一层是宿主根底能力层。如果宿主没有这些能力,能够参考百度开源的参考实现,可间接集成到宿主应用。

3. 外围构造

(1)前端角度

咱们从前端的视角来看看双栈构造。一个宿主客户端能够运行多个小程序,并且在一段时间内放弃存活状态,每个小程序都有一个 master 执行框架 JS 和小程序开发者的 JS,一个 master 对应多个 slave(slave 代表一个用户可见的界面)。

(2)客户端角度

从客户端角度来看双栈构造,如上图所示,master 负责执行 JS,能够有两种实现形式,WebView 或 JS 引擎(V8/jscore),JS 引擎的效率更高;slave 的展示有 WebView,为了放慢 WebView 的创立速度,设置 cache;master 和 slave 的通信通过音讯总线。

master 不反对 BOM、DOM 和 WEB-API,小程序只能调用对外开放的能力。

(3)小程序 NA 组件与界面关系

从体验上看,小程序的体验要好于 H5,其中有一点就是小程序会把一些 NA 的能力和 UI 交融到小程序外面去。小程序的主体渲染还是基于 H5 技术,接下来咱们讲一下 NA 元素如何融入 UI 界面。

NA 元素与 H5 的关系有两种,贴片关系、同层关系。

贴片关系:NA 元素在 H5 不在同一层,NA 浮在 H5 之上,H5 所有元素都不能够放到 NA 元素之上。因为不在一层,就须要解决滚动联动,当检测到 WebView 滚动 n 个像素,NA 元素也须要滚动 n 个像素。

同层关系:NA 元素在 H5 这一层,H5 的原生能够压在 NA 元素之上。

贴片、同层的界面层级树如上。

咱们举一个视频组件同层的例子。视频组件比较复杂,有 4 层。第 1 层是视频层,即原始视频的图像,第 2 层是弹幕层,第 3 层是用于视频管制的控件层(比方,开始、暂停按键),第 4 层 Slot 层,视频下面漂的 H5 元素将被放到这层。

同层解决机制,先在 H5(开发者写的 swan 会被转为 H5)上打一个非凡的标记先占位,属性 inline;浏览内核把这个区域的 surface 拿进去给到 NA 层;而后,小程序框架会把这个区域 surface 塞给播放器,让播放器间接在 surface 下面绘制,达到同层。下面的弹幕、控件、Slot,都是 swanjs 层 H5 实现,Slot 层能够认为是一个容器,例如写一个 video,其所有的子元素都会放在 Slot。

NA 的组件同层的技术计划还不太一样,安卓和 iOS 也是有些区别的。像在 iOS 上,如果有些组件设置 over-flow,它会人造反对这一套货色,然而安卓就须要浏览器内核来反对。

4. 小程序多宿主运行保障

百度智能小程序是开放系统,能够运行在多宿主之上,那如何在多宿主上保障小程序运行体验的一致性呢?

各个宿主集成了咱们的小程序框架后,首先要跑 CTS 测试,通过之后才能够拿到小程序列表进行散发。

对于可选能力局部,各个宿主不是所有的能力都须要实现。比方,一些 AI 能力、push 能力。

如果一个小程序用到了可选能力怎么办?

两个方法,一是小程序和宿主之间的双向选择机制,小程序能够抉择我要散发到哪些平台,宿主也有权力抉择要散发到哪些宿主。二是,小程序做兼容。

Estension 机制

上图所示,标红的是 Extension 机制,当宿主有一些定制化的要求时,能够应用此机制。作为宿主,须要做两件事件,一是在 JS 层须要写一套接口;二是在 Porting Layer 接口实现层实现一套能力。如果宿主感觉这个能力是通用的,能够反馈提案,审核通过后,百度小程序团队会将提案合并到开源框架里。

5. 章节小结

二、百度智能小程序框架性能优化实际

首先从用户视角看看一个小程序的加载过程。

1. 百度智能小程序加载分阶段过程

拿微博举例,如上图所示。

  • 首先小程序被启动后,先是一个 Loading 的过程,下面的 title 和上面的 tab(框架 NA 实现)显示进去
  • 。第二张图片咱们定义为 FP(First Paint)阶段。
  • 第三张图上面有搜寻框了,这其实是小程序包外面的内容。它是通过 initdate 接口初始化渲染进去的,此阶段咱们定义为 FCP(First Contentfull Paint)阶段。
  • 第四张图,是小程序从网上拉到了实时的内容,而后更新到界面,咱们将其定义为 FMP(First Meaningful Paint)阶段。
  • 最初一张图,所有的元素都曾经拉下来并展现了,用户能够操作任何一个地位,咱们将其定义为 TTI (Time to Interative) 阶段。

2. 百度智能小程序

(1)性能基线

百度小程序在 2019 年底建设了 FMP 指标,它在开发者平台展现的名字为“上屏工夫”。

咱们统计了线上的一个 80 分位点,耗时是 1.9s。什么是 80 分位点?比方,有 100 个申请过去了,而后咱们把申请的耗时排序,第 80 个申请的耗时,咱们就认为是 80 分位点。

(2)性能历史曲线

如上图所示,2019 年百度小程序性能优化的历史曲线。FP 框架层从靠近 3s 始终优化了当初的 1.1s 左右。百度小程序的指标是让小程序无线靠近 NA 体验。

3. 启动流程

接下来,咱们从开发者角度看,还能优化什么?

咱们先看一下启动流程,所有的启动逻辑简略串行列举(理论是有一些步奏是并行的)。

4. 性能优化

开发者可能做的性能优化次要有两局部。一是小程序包的体积,二是业务数据。

接下来,我用三点来阐明开发者能够做什么。

(1)包体积优化

倡议包体积放弃在 1M 以内,为什么呢?

因为咱们统计了一下,如果关上当次须要下载包,则这次的启动时长会占到咱们整个时长的 60%。1M 的包,80 分位速度须要 1s+ 能力下载实现。所以要管制本人的包的体积。而且咱们当初还只是看 80 分位,当咱们拉到 90 分位,99 分位,这个是一个十分陡的曲线,好转很重大。

包体优化机制

有两个技术:一是分包技术和独立分包技术,二是资源压缩。

  • 分包技术 & 独立分包技术分包技术

一个小程序有很多页面,但不是所有的页面都是高 PV 页面。很多页面是用户很少点到的,能够把这些页面放到咱们的分包去,主包放咱们高 PV 的页面。

分包不可能独立运行,比方,从搜寻 feed 散发过来,它运行时须要把咱们主包下载下来,然而因为它的概率低,不会影响绝大多数状况。简而言之,就是用分包技术把非关键的页面剥离进来。

用分包技术把非关键的页面剥离进来之后小程序包的体积还是大的话怎么办?

  • 独立分包技术

所谓独立,就是说下载完这个包之后就能够运行,无需下载主包。此时的主包和独立分包的区别就是,小程序总要有一个入口,这个入口的独立分包,咱们就命名为主包。

通过这两项技术来减小咱们的包体大小,将其放弃在在 1M 以内。

  • 资源压缩

咱们剖析过一些小程序,发现有的包体里蕴含 PC 图片,这无疑减少了包的体积。倡议如下:

  • 把图片放到服务器,不要放在包外面。
  • 压缩图片体积,比方,把 png 改为 jpeg 格局这样体积能够缩小 90%(不思考透明度状况)。
  • 剔除无用资源。

App-js 须要通过分包来解决,最终咱们要达到什么指标?

  • 单个包管制在 1M 以内。
  • 文件数管制在 200 个以内。

(2) 数据拉取

数据拉取的目标是疾速让界面有内容,缩小用户的白屏工夫。即便用户是断网的,也给他离线缓存一些数据。

如上图所示,这外面提到了业务骨架屏和框架骨架屏。当初很多小程序都会参考 H5 的实现,把 H5 的渐进式加载骨架屏用到咱们的小程序外面,用了这种技术之后,反而会让实在的内容展现的速度变慢,咱们统计大略有 300ms 提早。

为了解决骨架屏导致的内容展现提早,咱们做了一套框架层的骨架屏机制。依照咱们这个机制来实现骨架屏,对性能的影响就会大大减少。策略上就是在 master 做 appjs 执行时,就让 slave 加载框架骨架屏,并行执行。

本人写的业务骨架屏,它什么时候才展现?

如上图所示,当你把 App、page、waitNotify 告诉到渲染线程,到了 Ready firstRender 的时候才会渲染本人做的业务骨架屏,这个过程当然很慢。尽管你用了骨架屏,然而骨架屏和用户点击的这段时间还有大量的白屏工夫。用框架骨架屏,白屏工夫问题就会解决。用框架骨架屏,或多或少都会耗一点工夫,尽管是并行的,然而仍然在抢占手机的资源。

所以整体来看,站在客户端或者站在框架的角度,咱们是不倡议用,然而也不拥护用。如果要用就用框架骨架屏,影响最小。

request 的优化,我总结次要是两点,第一要早,第二要少。

  • “早”又能够分两局部来说,一是提前发,二是不阻塞。

第一是提前发,申请得太晚,展现当然比较慢了。倡议把网络申请放在 onlaunch 外面,这是咱们给小程序凋谢的第一个事件,很多小程序会放到 page unload 外面,这个就比较慢了。这两个工夫在线上 80 分位,大略差 200ms~300ms。第二个是不阻塞,常常看到一些小程序,一起来当前,它要等用户的受权、定位。通常定位波及 XY 坐标,然而定位一旦波及高度,就须要关上 GPS,这样性能又会慢 2s~3s。如果不须要高度就不要去设置,否则十分慢。还有的小程序在应用的时候会让用户受权,如果不受权上面什么也不展现,阻塞了。如果能够的话,倡议在须要受权的时候再提醒用户,这样用户也不恶感,也能放慢启动的速度。

  • “少”,次要分为两点,一是非要害申请延后,二是只拉取一屏数据。

一个小程序运行后,可能有几十甚至上百个网络申请,小程序除了本人的业务还要打点,这会很大水平上影响咱们的网络速度。因为个别的宿主在底层的网络库都会设置线程池,申请多了就要排队。小程序框架基本不晓得某个申请是外围申请还是非核心申请,只能排队。要是一上来全是一些打点的,业务就阻塞了。总之,整个页面须要显示的数据先申请,非关键申请延后。二是只拉一屏数据,分段加载。

(3)渲染

setData 操作是较为低廉的,尽量减少数据量和次数。

如上图所示,setData 是一个十分外围的 API,当网络数据回来,只有通过 setData 驱动渲染,内容能力显示到界面上。

上图是一个优化前和优化后的比照。咱们能够看到,即便是 1K 的数据,也须要 20ms 左右的工夫。如果 js 是用 WebView 来执行,首先一个 JS string,到了浏览器有 Renderer 线程、Browser 线程,变为 C 层的 string,而后再到咱们 NA,通过 Java interface,变成一个 Java string。而后到了 slave 当前还要再反过来,所以快不了。尽管咱们做了一些优化,通过内核让它变成一个内存指针优化切换,然而还是很低廉。

发现有些小程序在应用的过程中,setData 应用有很多不当之处,以下是应用 setdata 要留神的几点。

  • 缩小调用 setData 次数。goodcase:将屡次 setData 合并成一次 setData 调用。
  • 缩小 setData 数据量。badcase:新一页数据增加上之前页面数据后再调用 setData。
  • 变量变动只更新变量不更新对象。

5. 性能自查

性能自查次要有三个阶段,即开发阶段、测试阶段和上线后。

  • 在开发阶段这部分,咱们有三个伎俩去性能自查,别离是工具体验评分、性能面板(在客户端上性能面板能够提醒整个性能启动的耗时)以及打点零碎。
  • 在测试阶段咱们有两个伎俩,一是录屏,二是高速摄像头,这两个伎俩能够实在地反馈用户的体验。
  • 上线之后,有开发者平台。
    如何获取技术的官网反对路径?倡议去开发者文档和社群去获取技术支持。

6. 章节大节

  • 开发者可从包体积、数据申请、渲染三方面去优化性能。
  • 包体:1M 内。分包技术、压缩图片、无用资源剔除。
  • 骨架屏:如果要应用,倡议采纳框架骨架屏。
  • setData:缩小频度、缩小数据量。

整体回顾如下图。

———-  END  ———-

退出移动版