百度智能小程序框架性能优化实践(上)

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"导读:今天分享的文章是来自百度智能小程序研发部的实战总结:《百度开源小程序框架架构演进和性能优化实践》。分享包含两部分,第一部分是百度智能小程序整体的框架及演进,主要讲百度小程序开发全流程概况、百度智能小程序框架,以及百度小程序多宿主运行保障;第二部分是百度小程序框架的性能优化,主要讲整个小程序的启动过程,以及从开发者角度,有哪些重要的优化点。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"一、百度智能程序整体框架及演进","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"整个移动互联网一直是在 NA 和 H5 之间寻找权衡,NA 的性能好、能力强;H5 灵活性更高。我认为渲染分为两派,一派就是 NA 渲染派,一派叫做 H5 渲染派。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"NA 渲染派,比较有代表性的如 RN 、 Flutter ;Web 渲染派,比如百度的轻应用,以及之后做的小程序。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"1. 开发全流程概览","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/16/16f3844aa1906482b800272a1a664059.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"百度曾经做过的 Web 渲染派的三个代表产品,分别是轻应用、直达号和小程序。","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"轻应用,是 H5 + 端能力。它是一个标准的 H5,增加了一些 NA 的 API,比如定位等。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"直达号,在技术层面跟轻应用是一样的。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"小程序,本质上是一个受限的 H5 + 大量丰富的 API + UI 组件。现在我们给小程序提供的 API 有 300 多个,组件有 30 多个,组件是有界面的。比如,视频、地图 。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"为什么小程序要受限,主要有两个原因:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"保持体验的一致性。H5 太过灵活,JS 随时可以去改变界面。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"安全考虑。因为我们提供了大量 API 和组件,且这些都是很底层的一些能力,比如电话号码、账号,肯定不能轻易开放给大家。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"怎么受限,主要有两点:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"编写语言,不再是直接写 HTML ,而是用自定义语言 swan 来编写 。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"runtime 层有两个栈,一个是渲染栈,一个是 JS 执行栈,这两个栈从物理上隔离,以保障安全性。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2. 智能小程序框架","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(1)开发运行全流程","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a1/a165dd6c9abc20391756aba1c3e3b7a7.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"先简单介绍一下整个百度智能小程序的开发流程。","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先开发者用 swan 写布局;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接着通过开发者工具打包,上传到我们的小程序 B 端服务器;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然后是小程序的审核流程,有机审、人审;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最后是用户点击小程序时,客户端请求小程序 C 端服务器,C 端服务器再从 B 端服务器获取小程序包。整个过程都是加密传输,可以保证代码的安全。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(2)百度智能小程序框架 -SWAN","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/39/39476a164e62e253051a4444b98b4f88.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上图是一个百度智能小程序的框架,我们内部命名为","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"SWAN","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"分层结构如下:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最上层是开发者基础库,命名为 swan-js ,开发者直接和这层打交道。swan-js 负责两件事情:即 swan 代码转为 HTML,变成 WebView 可运行程序;客户端端能力的封装暴露。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再下一层是 swan-native。这里面最核心的是API 和组件的 NA 实现。其中双栈管理也在这一层,另外标红的 Extension 用于开发者宿主自身能力扩展使用,比如,贴吧宿主期望增加个发帖能力,就可以通过此机制。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再下面这层叫 Porting Layer。这层是百度小程序为了实现开源,增加的一层与宿主的接口层。最下面这一层是宿主基础能力层。如果宿主没有这些能力,可以参考百度开源的参考实现,可直接集成到宿主使用。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"3. 核心结构","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(1)前端角度","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/79/79849cecd7d12f7955f14b31c55f2eea.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们从前端的视角来看看双栈结构。一个宿主客户端可以运行多个小程序,并且在一段时间内保持存活状态,每个小程序都有一个 master 执行框架 JS 和小程序开发者的 JS,一个 master 对应多个 slave(slave 代表一个用户可见的界面)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(2)客户端角度","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/0b/0bfca404104d05050f2d361a3d885f80.webp","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"从客户端角度来看双栈结构,如上图所示,master 负责执行 JS,可以有两种实现方式,WebView 或 JS 引擎(V8/jscore),JS 引擎的效率更高;slave 的展现有 WebView,为了加快 WebView 的创建速度,设置 cache;master 和 slave 的通信通过消息总线。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"master 不支持 BOM、DOM 和 WEB-API,小程序只能调用对外开放的能力。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(3)小程序 NA 组件与界面关系","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/94/94433bbcf6afe9bcc8f9ccaf8d4444d4.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"从体验上看,小程序的体验要好于 H5,其中有一点就是小程序会把一些 NA 的能力和 UI 融合到小程序里面去。小程序的主体渲染还是基于 H5 技术,接下来我们讲一下 NA 元素如何融入 UI 界面。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"NA 元素与 H5 的关系有两种,贴片关系、同层关系。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"贴片关系:NA 元素在 H5 不在同一层,NA 浮在 H5 之上,H5 所有元素都不可以放到 NA 元素之上。因为不在一层,就需要处理滚动联动,当检测到 WebView 滚动 n 个像素, NA 元素也需要滚动 n 个像素。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"同层关系:NA 元素在 H5 这一层,H5 的原生可以压在 NA 元素之上。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ba/ba7979f7dcfa39796764a173b606d119.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"贴片、同层的界面层级树如上。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":"br"}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ad/adb971b7713b82cc9e1b5cc50f846d35.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们举一个视频组件同层的例子。视频组件比较复杂,有 4 层。第 1 层是视频层,即原始视频的图像,第 2 层是弹幕层,第 3 层是用于视频控制的控件层(比如,开始、暂停按键),第 4 层 Slot 层,视频上面漂的 H5 元素将被放到这层。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"同层处理机制,先在 H5(开发者写的 swan 会被转为 H5) 上打一个特殊的标记先占位,属性 inline;浏览内核把这个区域的 surface 拿出来给到 NA 层;然后,小程序框架会把这个区域 surface 塞给播放器,让播放器直接在 surface 上面绘制,达到同层。上面的弹幕、控件、 Slot ,都是 swanjs 层 H5 实现 ,Slot 层可以认为是一个容器,例如写一个 video,其所有的子元素都会放在 Slot。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"NA 的组件同层的技术方案还不太一样,安卓和 iOS 也是有些区别的。像在 iOS 上,如果有些组件设置 over-flow ,它会天然支持这一套东西,但是安卓就需要浏览器内核来支持。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"4. 小程序多宿主运行保障","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/25/254d321159f136e5f68f1cd923132cc3.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"百度智能小程序是开放系统,可以运行在多宿主之上,那如何在多宿主上保证小程序运行体验的一致性呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"各个宿主集成了我们的小程序框架后,首先要跑 CTS 测试,通过之后才可以拿到小程序列表进行分发。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对于可选能力部分,各个宿主不是所有的能力都需要实现。比如,一些 AI 能力、push 能力。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果一个小程序用到了可选能力怎么办?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"两个办法,一是小程序和宿主之间的双向选择机制,小程序可以选择我要分发到哪些平台,宿主也有权利选择要分发到哪些宿主。二是,小程序做兼容。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Estension 机制","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/4b/4ba4e4b9efabc1639b01e8e7af22b6f1.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上图所示,标红的是Extension 机制,当宿主有一些定制化的要求时,可以使用此机制。作为宿主,需要做两件事情,一是在 JS 层需要写一套接口;二是在 Porting Layer 接口实现层实现一套能力。如果宿主觉得这个能力是通用的,可以反馈提案,审核通过后,百度小程序团队会将提案合并到开源框架里。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":"br"}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"5. 章节小结","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8a/8a8dc772938f8bbbbaae633ccfee3a08.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"更多精彩内容欢迎关注百度开发者中心公众号。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/db/db4e117abea670fd43ad7ee5bc9683e8.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章