百度智能小程序框架性能优化实践
在移动互联网中,App(NA)和H5一直处于博弈状态。在性能体验和灵活性之间很难找到平衡点。从技术上看,小程序是NA和H5的又一次碰撞。小程序的灵活性已经得到验证。在性能方面,百度智能小程序从框架启动、小程序包下载、小程序包加载和渲染四个方面对启动速度进行了优化。
在GMTC全球前端技术大会(深圳站)2019上,百度技术经理傅家兴讲解了可以用来提升自家小程序性能的手段,并介绍了如何使用小程序框架作为主持人。与自己的技术相结合。本文以傅家兴的演讲为基础。
以下是正文:
今天的主题是《百度开源小程序框架架构演进与性能优化实践》。本次分享由两部分组成。第一部分是百度智能小程序的整体框架和演进。主要讲了百度小程序开发全过程,百度智能小程序框架,百度小程序多主机运行保障。第二部分是关于百度小程序的开发。小程序框架的性能优化主要讲了整个小程序的启动过程以及从开发者的角度来看有哪些重要的优化点。
百度智能小程序整体架构及演进
整个移动互联网一直在寻找NA和H5之间的取舍。NA性能好,能力强;H5更灵活。我觉得渲染分两个流派,一个是NA渲染流派,一个叫H5渲染流派。
NA渲染组,比较有代表性的比如RN,;Web渲染组,比如百度的轻应用,以及后来做的小程序。
1. 整个开发过程概览
百度曾经做过的网页渲染学校的三个代表产品是轻应用、直接号码和小程序。
小程序受限的主要原因有两个:
主要有两点:
2.智能小程序框架(1)开发运营全流程
首先简单介绍一下整个百度智能小程序的开发过程。
(2)百度智能小程序框架-SWAN
上图是一个百度智能小程序的框架,我们内部命名为SWAN。
层次结构如下:
3. 核心结构(1)前端角
我们从前端的角度来看一下双栈结构。主机客户端可以运行多个小程序并在一段时间内保持活动状态。每个小程序都有一个执行框架JS和小程序开发者的JS,一个对应多个slave(slave代表一个用户可见的界面)。
(2)客户视角
从客户端来看,双栈结构,如上图,负责执行JS,可以两种方式实现,或者JS引擎(V8/),JS引擎效率更高;从显示是,为了加快创建速度,设置缓存;通过消息总线和从机通信。
不支持BOM、DOM、WEB-API,小程序只能调用对外开放的能力。
(3)小程序NA组件及接口关系
从体验上来看,小程序的体验要优于H5,其中之一就是小程序会在小程序中集成一些NA能力和UI。小程序的主要渲染还是基于H5技术。接下来我们来说说NA元素是如何融入UI界面的。
NA元素和H5之间有两种关系,补丁关系和同级关系。
补丁关系:H5中NA元素不在同一层,NA浮动在H5之上,H5的所有元素不能放在NA元素之上。因为不在第一层,所以需要处理滚动联动。当检测到滚动n个像素时,NA元素也需要滚动n个像素。
同层关系:NA元素在H5层,H5的可以压在NA元素上。
补丁和同一层的接口层次树如上。
让我们以与视频组件相同的层为例。视频组件更复杂,有 4 层。第一层是视频层,即原始视频的图像,第二层是弹幕层,第三层是视频控制的控制层(例如开始和暂停按钮),第四层layer 是 slot 层,它浮动在视频上。H5 元素将被放置到该层中。
对于同层处理机制,先在H5上打个特殊标记(开发者写的swan会转成H5),属性优先;浏览内核取出这个区域交给NA层; 然后,小程序框架会将这个区域插入播放器,让播放器直接在上面画图到达同层,上面的弹幕、控件、Slot都是在H5层实现的,可以考虑Slot层作为一个容器,比如写一个视频,它的所有子元素都会放在Slot中。
NA的同层组件的技术方案不尽相同,和iOS也存在一些差异。像在iOS上,如果某些组件设置为over-flow,自然会支持这一套东西,但是需要浏览器内核来支持。
4. 小程序多主机运行保障
百度智能小程序是一个开放系统,可以在多主机上运行,那么如何保证小程序在多主机上运行体验的一致性呢?
每台主机集成我们的小程序框架后,必须先运行CTS测试,测试通过后才能得到小程序列表进行分发。
对于可选能力,并不是每台主机的所有能力都需要实现。比如一些AI能力和推送能力。
如果小程序使用可选功能怎么办?
有两种方法。一是小程序和主机之间的双向选择机制。小程序可以选择我要分发到哪些平台,主机有权选择分发到哪些主机。其次,小程序兼容。
机制
如上图所示,当主机有一些定制需求时,可以使用红色标记的机制。作为宿主,需要做两件事,一是在JS层写一套接口;另一种是在Layer接口实现层实现一套能力。如果宿主觉得这个能力是通用的,可以反馈提案。审核通过后百度优化,百度小程序团队会将提案合并到开源框架中。
5. 章节摘要
百度智能小程序框架性能优化实践
首先从用户的角度来看一个小程序的加载过程。
1. 百度智能小程序加载分阶段处理
以微博为例,如上图所示。
2.百度智能小程序(1)性能基线
百度小程序于 2019 年底建立了 FMP 指标,其在开发者平台上显示的名称为“屏幕时间”。
我们计算了线上的第 80 个百分位,花费了 1.9 秒。第 80 个百分位数是多少?比如有100个请求来了,然后我们对请求的耗时进行排序,我们认为第80个请求的耗时是第80个百分位。
(2)业绩历史曲线
如上图所示,2019年百度小程序性能优化历史曲线。
FP框架层从近3s优化到现在的1.1s。
百度小程序的目标是让小程序无线接近北美体验。
3. 启动进程
接下来,从开发者的角度来看,我们还能优化什么?
我们先来看看启动过程。所有的启动逻辑都简单地串联列出(实际上有些步骤是并行的)。
4. 性能优化
开发人员可以做的性能优化有两个主要部分。一是小程序包的大小,二是业务数据。
接下来,我用三点来说明开发者能做什么。
(1)包大小优化
建议将包体积保持在1M以内,为什么呢?
因为我们统计过,如果你打开包需要下载的话,这次的启动时间会占到我们整个时间的60%。1M包,80%速度需要1s+下载。所以控制好自己包包的体积。我们仍然只关注第 80 个百分位。当我们拉到第90个百分位,第99个百分位,这是一个非常陡峭的曲线,恶化非常严重。
包体优化机制
技术有两种:一种是分包技术和独立分包技术,另一种是资源压缩。
分包技术
一个小程序有很多页面,但并非所有页面都是高 PV 页面。许多页面很少被用户访问。您可以将这些页面放在我们的子包中,将我们的高 PV 页面放在主包中。
子包不能独立运行。比如从搜索Feed分布来看,它运行的时候需要下载我们的主包,但是因为概率低,所以大部分情况不会影响。简而言之,就是利用分包技术剥离非关键页面。
使用分包技术剥离非关键页面后,小程序包大小仍然很大怎么办?
自主分包技术
所谓独立,是指不下载主包,下载包后即可运行。此时的主包和独立子包的区别在于,小程序总是有一个入口,而这个入口的独立子包被命名为主包。
这两种技术减少了我们的数据包大小,将其保持在 1M 以内。
我们对一些小程序进行了分析,发现一些包中包含PC图片,这无疑增加了包的体积。以下建议:
app-js需要通过分包来解决。我们最终想要达到什么目的?
(2) 数据拉取
数据拉取的目的是快速让界面有内容,减少用户的白屏时间。即使用户断网,也会为他离线缓存一些数据。
如上图,这里说的是业务骨架屏和框架骨架屏。现在很多小程序都会参考H5的实现,将H5的渐进式加载骨架屏用到我们的小程序中。使用该技术后,会减慢真实内容的显示速度。我们计算大约 300 毫秒。延迟。
为了解决骨架屏造成的内容显示延迟百度优化,我们做了一套框架层的骨架屏机制。按照我们实现骨架屏的机制,对性能的影响会大大降低。策略是让slave加载框架骨架屏,在appjs执行的时候并行执行。
自己写的业务骨架屏,什么时候展示?
如上图所示,当通知应用、页面、渲染线程到渲染线程时,自己制作的业务骨架屏只有在Ready时才会渲染。当然,这个过程非常缓慢。虽然你用的是骨架屏,但是从骨架屏到用户点击之间还是有很多白屏时间。有了框架骨架屏,白屏时间问题就迎刃而解了。使用框架骨架屏幕将花费或多或少的时间。虽然是水货,但依然在占用手机资源。
所以总的来说,无论是从客户端还是从框架的角度,我们都不推荐使用,但也不反对使用。如果要使用框架框架屏,影响是微乎其微的。
优化,我主要总结两点,第一是早,第二是少。
首先是发送早,请求来不及,显示当然慢。建议把网络请求放在里面。这是我们向小程序开放的第一个事件。很多会被放到页面中,比较慢。这两个时间在第 80 个百分位,相隔大约 200 毫秒到 300 毫秒。
二是非阻塞。我经常看到一些小程序。他们走到一起后,还要等待用户的授权和定位。通常定位涉及到XY坐标,但是一旦定位涉及到高度,就需要开启GPS,所以性能会慢2s到3s。不需要高度就不要设置,否则很慢。一些小程序在使用时会要求用户授权。如果他们没有被授权,下面不会显示任何内容,这是被阻止的。如果可能的话,建议在需要授权的时候提示用户,这样用户才不会反感,可以加快启动速度。
一个小程序运行后,可能会有几十个甚至上百个网络请求。小程序要自己管理业务,这会极大地影响我们的网络速度。因为一般主机在底层网络库中会设置一个线程池,如果请求过多,就会排队。小程序框架根本不知道一个请求是核心请求还是非核心请求,只能排队。如果它拿出一些管理,业务将被阻止。简而言之,就是先请求整个页面需要展示的数据,延迟非关键请求。
二是只拉取一屏数据,分段加载。
(3)渲染
操作比较昂贵,尽量减少数据量和次数。
如上图所示,是一个非常核心的API。当网络数据回来后,只有驱动渲染后才能在界面上显示内容。
上图是优化前后的对比。我们可以看到,即使是 1K 的数据,也需要大约 20ms。如果用js来执行,先是一个js,在浏览器里面有线程,线程,变成C层,然后我们NA,通过Java,变成Java。然后到了slave之后,又要倒过来,所以速度不快。虽然我们做了一些优化,使它成为通过内核的内存指针优化切换,但仍然很昂贵。
发现一些小程序在使用过程中,有很多不恰当的使用。以下是使用它们时需要注意的几点。
5. 性能自检
性能自检主要分为三个阶段,即开发阶段、测试阶段和发布后。
我如何获得对我的技术的官方支持?建议去开发者文档和社区寻求技术支持。
6. 章节小节
总体评价如下。
关注我转发本文,私信我“获取资讯”,即可免费获得价值4999元的InfoQ迷你书!