小红书自研小程序:电商体验与效果优化的运行时体系设计

小程序在其诞生后的几年内,凭借其简单、轻量、流畅、无需安装等特点,引来了爆发式的增长。伴随小红书电商业务的发展,我们洞察到越来越多的商家和品牌大客户有自己定制化需求场景,传统的电商和薯店存在下面三大问题:

为了解决上述问题,并快速打通基于小红书体系的支付与账号体系。过去的一年内,我们踏上了自研小程序之路。目前,在小红书店铺主页、 笔记详情、品牌专区、开屏均可唤起小程序。

品牌合作

案例展示

本文将主要介绍小红书进行小程序自研时的一些业务背景及工程化、容器能力的落地方案,以及运行时针对双线程架构 bridge,framework 能力的设计。

2.1 小程序 "运行时" 定义

运行时在不同语言中含义有所不同,但基本可以概括为 「运行在代码执行阶段的代码」,类似 vue-runtime, 提供了对于页面状态的劫持,生命周期的解析,api 的调用能;nodejs 提供了 JS 运行时执行能力等。小程序 “运行时” 则提供了在不同线程内,借助 Bridge 消息通道,进行逻辑调度的能力。

那么可以基本概括为:运行在小程序代码执行阶段、用于提供在独立线程中操作其他线程的页面(或视图),正确响应用户交互行为、并调度用户业务逻辑能力的代码。

2.2 小程序基础架构

小红书小程序也是对齐业界经典架构进行建设:

经典双线程架构

经典架构下,运行时主要分为 渲染层 - Render、逻辑层 - Service。Service 用于与系统能力进行交互,在安全的 JS 线程内调度用户业务逻辑。而 Render 则负责接受渲染指令、进行视图的绘制与用户交互的响应。逻辑层与渲染层则通过 js-bridge 进行消息的通讯,容器则负责接受 api 指令进行端能力的调用。

之所以需要一个独立的线程来执行 JS,其主要目的是为了限制 JS 灵活性。为了提供一个可用的 JS 环境,其实也有比较多的方案。比如,我们可以使用浏览器内核提供的 Service Worker ,来单独运行 service 层 JS 代码。或者我们可以使用多个 webview 实例来分别承载双端 js 的执行环境。

2.3 容器架构实现

按照经典架构的设计,我们需要在三端 (iOS、android、小程序开发者工具) 提供面向双线程的容器方案。在不同的容器环境下,渲染层和逻辑层选用的方案会存在一定差异,小红书三端选用容器的分布如下:

虽然运行环境存在一定差异,但容器对于基础库和业务脚本的加载顺序是基本一致的。我们可以将整个启动阶段拆解为下面几个阶段:

首先,当用户点击时,会经历一个基本的启动过程。

在这个启动流程的背后,会对应着上面提到渲染层 webview 容器被加载出来。于此同时,在用户看不到的地方,容器会进行逻辑层 v8/JsCore 的初始化, 同时会加载小程序的基础库代码。

脚本注入结束后,容器会立即通知「运行时逻辑层框架」进行依赖分析、并准备初渲染数据。

渲染层接受到 initialData 消息后,会进行后续渲染操作,用户即刻看到了页面的内容 至此,初渲染的流程基本结束。

当然,实际的容器的启动过程中的流程会更加复杂,整个启动流程可以用下面的这张图来表示:

 黑色、蓝色、橙色分别代表了 端侧、逻辑层、渲染层三个线程

实际场景中,容器还面临更多的挑战,比如如何确保双线程的是否 ready,再进行消息的推送等。核心在于,我们通过不同线程的容器,完成了页面渲染行为的控制。

可以看到,上述启动流程中容器侧分别在 Render 和 Service 分别注入了 page.render.js 和 service.js 的业务代码。那么如何进行业务代码构建,来分别在双线程下执行呢?这就需要依靠前端工程化的能力来实现了。

2.4 实现基础架构的工程化能力

通过前端工程化能力,我们可以对资源进行分类构建,小红书小程序使用 webpack 作为工程化构建工具。通常,小程序的构建分两块,一块是针对基础库的打包,一块是针对业务组件的构建。

基础库的打包需要构建基础库代码,产出分别用于提供运行时框架能力的 render.base.js 及 service.base.js

而业务组件的构建,则相对复杂。一个原生小程序组件或页面通常包含下面四个文件:

通过拆分多个文件,我们可以在构建时指定入口依赖,将对应的依赖打入所需要的模块内,在工程构建时,需要对文件进行分类打包:

我们使用 loader 作为 webpack 的 entry 入口进行构建,每个页面都会作为一个 entry 独立打包。这使得从行为上来说小程序更像一个 MPA(多页应用)。入口侧会进行 app.json 的校验,对配置以页面维度来进行解析,针对小程序业务代码,会分别构建出 page.render.js 和 service.js 分别交给不同的线程进行加载(如上图)。

构建会将代码打包成 UMD 格式文件,当在不同线程内执行基础库脚本时,部分脚本会自动执行,端侧只需要关注容器加载 Js脚本的时机及消息发送的顺序即可。

容器和工程化能力是小程序运行的基石,但小程序之所以可以做到高效开发、并拥有极强的跨平台能力和优秀的体验,这也得益于在框架底层提供了完善的组件及模块化能力,更有丰富的 api 来满足原生场景下各种系统能力调用的述求。

3.1  运行时总架构

这张图主要将运行时架构分为了渲染层、逻辑层和jsBridge:

  • 渲染层面向业务提供了组件、沙箱、性能收集等框架能力,这一层业务是无法接触到的

  • 逻辑层则在 JsContext 内提供了 invoke 层来与端侧进行数据交互

  • 逻辑层通过适配层,完成导航、Render和页面实例的管理

  • 逻辑层内核主要用于向业务代码的执行环境,提供 Page、Component、behavior 这类能力,并预置 JS Polyfill 来确保业务的 js 正常运行。

  • JSON schema 则用于定义 api 标准结构和定义,并通过 js-bridge 层完成端能力调用与通讯

3.2 基础能力分布

为了丰富小程序的基础能力,初期我们盘点了业界的功能矩阵,尽可能丰富小红书小程序的基础能力,目前运行时的基础能力分布如下:

 灰色部分为暂未支持的能力

其中包含了:

  • App, Compnent, Page 等基础能力

  • 网络、文件系统,设备等 API 能力

  • xhs-view, xhs-button 等面向业务的组件能力

目前,矩阵列出的功能,在小红书小程序基础库 ≥ v3.32.x 版本上已经得到支持。

3.3 双线程框架能力建设

熟悉小程序语法的同学都知道,小程序可以通过 Page、Component 来进行非常灵活的组件化开发。通过 selectComponent 、triggerEvent这类功能可以非常方便的进行 子 → 父 或 父 → 子 实例的追溯,这就要求框架侧需要维护组件之间的依赖关系。

实现这种架构有多种思路,不同厂商的做法也不同。譬如微信在 Page 体系和 Component 自定义组件的实现上就采用了不同的设计。微信在渲染侧通过 Exparser模块 完成小程序内的所有组件,包括内置组件和自定义组件组织管理。

小红书侧在渲染层则是 Fork Vue 框架,通过定制 Vue 的一些能力来完成页面渲染工作。借助 Vue优秀的组件化能力的来完成 Page, Component 的渲染工作。在逻辑层,则通过消息维护一棵类 vdom 树 , 来完成 视图 ←→ 逻辑 的映射与绑定关系,整个关系大概如下图所示:

3.4 事件系统

有了上述基础能力和双线程架构,运行时还需要实现一套事件系统,让 UI 界面与用户产生互动。事件通常分为两块,一块是服务于用户的手势交互,比如用户的点击 tap, 长按 longtap 等事件,另一块则是渲染层交互组件的回调时间,譬如 swiper 组件的 onChange 等回调。

在小程序的事件系统下,我们把这些用户的手势操作和组件回调,进行拦截与收集,全部转入消息队列转发到逻辑线程。每条消息携带自己的实例 ID,找到逻辑层实例进行对应函数的触发。

3.5 bridge 能力设计

框架侧借助 bridge 通道可以非常方便进行消息的转发。但实际上,一条消息需要经过多次序列化和反序列化,才可以到达“目的地”。小红书小程序的 bridge 侧是如何实现的呢?

我们以渲染层事件消息举例,当渲染层收到一条点击 消息,会经过如下几个阶段:

不同容器下,对 webview 内核消息的拦截机制不同,ios 使用 messageHandler, android 则使用 console 通道拦截消息,但内核底层对消息的处理流程基本一致。

这个过程可以简单描述为以下几个环节:

  • Render 侧发送 postMessage 消息,此时消息需要经过一次序列化转成字符串

  • 浏览器拦截到消息,反序列化成 JSONObject 并发送到 Naive 容器侧

 容器开始进行跨线程事件分发,并转发消息到 service

  • Service 运行环境将消息反序列化成 string,并转成 JS 数据类型,传到 Service 所在的  JsContext 中

  • JsContext 中 invokeCallback 函数被调用

  • 至此,render 消息已成功转发至 service 层

可以看到,这个过程非常复杂,不仅要完成消息的转发,还要完成 jsonObject 和 js 数据类型的互转。为了在两个线程内方便的完成这种互调,并保证 bridge 的安全线,我们分别在双端分别实现了 handleMessage 和 postMessage 的封装,通过 schema 来定义 bridge 和 api  标准协议,来完成线程消息的转发和消息类型的校验工作。

一个标准的 api schema 定义大概是这样:

消息会在 JsContext 内完成校验,并在校验通过后以序列化的方式完成上述流程的传递。

3.6 数据编译能力与 JS 沙箱

为什么这里要提下数据编译能力和 js 沙箱呢。因为小程序双线程的框架下,逻辑层通过setData 发起页面更新请求,携带的数组字段在被渲染层对应的组件解析时,需要配合小程序的一些语法特性进行特殊转换。

在运行时侧,我们将字段的解析能力与数据字段的处理,都收拢到沙箱 环境中进行字段编译。通过沙箱,我们可以拦截业务代码对于变量的访问,从而实现变量的劫持,并配合完成 sjs 这类能力的实现。同时,沙箱可以有效防止业务动态注入一些变量或函数,带来的变量访问逃逸的安全问题。因此,沙箱在小程序语法和变量计算的过程中起到了至关重要的作用。

例如,下面这段代码片段:

在编译侧,我们会将 loader上面代码通过 ast 进行转换:

通过沙箱,我们可以拦截到业务对 sjs 模块访问,将访问属性替换为 sjs 的模块导出,从而实现类似 sjs 这样的脚本拓展能力。

双线程在线程隔离方案上,将原本在同一线程内执行的脚本、渲染等工作分散到多个线程内执行,带来了更好的性能。但如果单个 webview 线程的渲染负担过重或对设备内存占用过大一样会影响到整体的体验。

于此同时,线程隔离也带来了通讯的损耗,对于一次消息需要经过多次序列化和反序列化,消息序列化的损耗与转发也对性能有着直接的影响。

因此,小程序的性能优化不同于传统的 web,需要从框架、通道、容器三方面来考虑。

4.1 bridge 消息调度机制

bridge 消息通道的繁忙程度,会在很大程度上影响小程序的性能表现。通过上面对于 bridge 消息转发机制的介绍也可以看出,频繁的借助 bridge 进行消息转发,意味着消息要不断进行序列化和反序列化的操作。

实际场景中,数据量小于64KB时,时长基本在 10 - 40ms 内。传输时间与数据量上呈现正相关关系,传输过大的数据将使这一时间显著增加,因此减少传输数据量是降低数据传输时间的有效方式。

但是如果数据量较小,确在短时间内多次使用 bridge ,也会导致通道过于繁忙。小红书在 bridge 侧,通过一定消息调度能力,将特定场景下的消息进行聚合,确保一次序列化尽可能在不影响序列化性能的情况下,多携带一些消息到对应的线程内。

4.2 渲染层任务调度与优先级队列

前面我们曾经提到,双线程背景下,小程序的更新机制与事件系统全部都是通过消息进行处理的,但消息本身的收发都存在一定的延时性,这就注定了小程序是一个异步通讯的世界。那么在一个异步多线程的场景下,线程之间“生产“和“消费“的消息的速度会因性能、稳定性等因素而不一致,这时,我们便要借助消息队列的思想来管理我们的消息:

有了消息队列,我们可以更好的管理框架层抛出的消息体,但小程序框架内,除了更新消息和事件消息外,还有不同的消息体会与这些框架消息抢占消息通道。比如,框架收集不同的 render 线程 webview 内的性能指标,这些性能消息会与事件消息共享同一队列。但有些场景下,事件消息的优先级要远高于性能指标消息。

此外,不同的渲染层 render 实例的消息所拥有的优先级也不同,比如 A、B 页面在同一时间段内,因其“栈顶的地位”会因用户操作而不断变化,此时栈顶页面的框架消息优先级高于 B 页面的框架消息优先级,在底层。我们使用 二叉堆 结构来维护优先级队列。

4.3 容器预加载

小程序的启动分为冷启动和热启动,  从用户的角度看:

  • 冷启动:如果用户首次打开,或小程序销毁后被用户再次打开,此时小程序需要重新加载启动,即冷启动。

  • 热启动:如果用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时小程序并未被销毁,只是从后台状态进入前台状态,这个过程就是热启动。

通常在容器侧的优化,就是针对冷启动来进行。那么容器的预载,顾名思义,就是在合适的时间提前预载小程序容器,预载的同时,会提前进行基础库的下载和渲染容器(webview)的加载。

通过前置容器的初始化时机,来达到快速换起小程序,提高首屏的优化效果。这是小程序这类容器技术方案常用的优化策略。

4.4 性能监控与告警

性能优化的同时,框架侧需要对业务代码的性能和行为有一定感知能力。在底层,我们通过 aop 的方式,建设了一套监控和插件机制。在开发阶段,可以感知到业务各项指标的健康状况,业务可以接收到底层框架给出的性能告警信息,并通过告警信息中的修复建议,针对性的进行优化。

业务侧,则可以通过 performance api 拿到这些性能指标,来进行基础性能数据的收集与上报。

性能告警会结合性能标准阈值来给出提示和修复建议,未来在审核阶段也会结合这些指标进行小程序健康度的洞察。

4.5 ServiceTiming 与 RenderTiming

除了卡顿、渲染指标外,为了满足高级开发者洞察平台的性能信息的需要,我们对容器和框架在启动阶段的关键节点,都预留了性能点位。开发者可以通过 performance.serviceTiming和performance.renderTiming 来分别获取到各个关键阶段的时间戳信息。

各个线程内所预留的性能点位和其在启动阶段中的位置如下图所示:

以上就是小红书小程序运行时方案的原理解析。

小程序本身是一个依托宿主流量体系衍生出的技术体系,它的价值往往紧贴应用主体的流量,而应用主体本身,又依赖小程序的灵活性及低成本的特点快速完成流量的转换。社交、支付与搜索,这些都是互联网产品提供的服务形态,各大厂商都是结合用户的需求和行为差异进行更开放、安全的技术方案探索,小红书亦是如此。小红书依靠用户产生内容,而内容产生商品,那么结合各类消费场景,如店铺、笔记等都可以通过小程序容器快速进行交易链路闭环。

未来,我们也将在不同的品牌和赛道上,寻找更多的服务商与品牌大客户商家与我们一起,共同丰富小红书的商品服务供给,增加小红书商业收入。技术上,我们则会不断对齐业界,优化技术架构,在提高框架性能的同时,建立完善的服务市场、巡检机制等来帮助小红书服务商与自开发商家细致、高效的开发与管理自己的小程序。

小程序是一个比较庞大的技术体系,如果你觉得本文对你有帮助,欢迎点赞转发。我们后续会根据反馈继续展开介绍更多的技术建设细节。也欢迎访问我们的小程序官方网站与我们交流:

  • 小红书小程序介绍:https://miniapp.xiaohongshu.com/docs/guide/miniIntroduce 

  • 小红书社区专业号:https://pro.xiaohongshu.com/ 

  • 你也可以通过 https://github.com/redengineer/redmini 与我们进行交流

哈笛

商业技术组 - 小程序团队成员(tailiang@xiaohongshu.com),目前负责小红书运行时相关技术开发工作。

小红书商业技术组专注于小红书 App 内交易链路开发,目前我们正在招聘 iOS 、Android、Web 研发工程师 

欢迎感兴趣的同学发送简历至:REDtech@xiaohongshu.com;

并抄送至:blv@xiaohongshu.com;lanfeihong@xiaohongshu.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/60213.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

facebook怎么运营?

很多做跨境的小伙伴都是通过facebook进行聊天交友,通过facebook平台去做营销引流获客。大家在做facebook营销的时候难免会遇到一些问题,尤其是账号封禁申诉、facebook运营等等一系列内容,下面跨境王营销助手就为大家详细讲解下,希…

以前管Facebook叫“脸书” 现在管Meta叫什么呢

一 硅谷今天的大新闻是Facebook宣布改名了,改叫Meta。 段子挺多,比如国内有媒体宣布,Facebook不要脸了。 还有这张很有趣的图: 不过这张包浆严重的图有个小毛病,按照前后逻辑要一致,google不是google&am…

【WhatsApp营销】如何在Facebook和Instagram上创建Click-to-WhatsApp广告

关键词:WhatsApp营销,Click-to-WhatsApp广告 通过 WhatsApp 中简单快速的客户沟通,公司和客户可以建立直接且有价值的关系。但是,由于WhatsApp不允许企业与用户直接发起会话,要想鼓励客户在WhatsApp上与商家联系&…

双色球系统开发

import java.util.Random; import java.util.Scanner;public class Test8 {public static void main(String[] args) {//双色球系统开发//投注号码由6个红色球号码和1个蓝色球号码组成//红色球号码从1-33中选择,要求选择红球不能重复//蓝色球号码从1-16中选择//共7个…

每日新闻 | 科大讯飞董事长刘庆峰:我国中学生六成作业是重复的

点击蓝字 关注我们 更多精彩,请点击上方蓝字关注我们! 每日新闻播报 第08-02期 1 趋势洞察 科大讯飞董事长刘庆峰:我国中学生六成作业是重复的 在由北京师范大学与科大讯飞联合主办的人工智能与教育大数据峰会上科大讯飞董事长刘庆峰表示&…

科大讯飞董事长刘庆峰:人工智能窗口期有多远?【软件网每日新闻播报│第10-19期】

每一个企业级的人 都置顶了 中国软件网 中国软件网 为你带来最新鲜的行业干货 小编点评 小编: 今儿个 Garner划了4000亿刀的云计算赛道 别跑偏!别掉队! 大家撒丫子跑吧 趋势洞察 科大讯飞董事长刘庆峰:人工智能产业进入窗口期 …

补贴下的科大讯飞:盈利水平堪忧、股东接连减持,刘庆峰没信心?

成立超20年,科大讯飞仍严重依赖补贴,且股东也在接连减持。 10月26日,科大讯飞发布2020年第三季度财报。财报显示,2020年1-9月,科大讯飞营收实现72.84亿元,同比增长10.82%;归属于上市公司股东的…

产业、生态、渠道,三个关键词解码2020年科大讯飞开发者节刘庆峰发言

10月23日,以“AI焕新更美好”为主题的2020年科大讯飞全球1024开发者节在安徽广播电视台亚洲一号演播厅举行。发布会上,科大讯飞董事 长刘庆峰向与会者分享了自己对产业的洞察,并对科大讯飞接下来的发展做了阐述。 01 刘庆峰谈2020人工智能产…

chatgpt赋能python:Python关键词搜索优化

Python关键词搜索优化 Python是一种高级编程语言,通常被用于开发Web应用程序、数据科学、人工智能、机器学习等领域。Python拥有大量的库和框架,能够在很大程度上提升开发效率。 但是,想要在Python领域获得成功,需要了解Python关…

欣奥诚分享:企业最应避讳这八类广告宣传词汇

广告宣传中,企业最应避讳这八类词汇 众所周知,拥有一个朗朗上口、脍炙人口的广告标语、广告口号,对于企业战略部署、发展壮大具有最要作用。一个好的广告标语,不仅可以传达产品买点、展现品牌魅力,激发购买欲望&#…

人工智能本来是个很简单的事,咋被人们整的这么神秘?

(1) 很多人以为大模型的参数量大是因为数据多。 其实大模型的参数量和超参数的配置相关。主要的超参数有下面几个: 词表大小:Vocab_Size最大位置编码大小:Max_Position_embeddings隐层节点数大小:Hidden_Si…

探究ChatGPT与GPT-4的缺陷不足,揭示大预言LLM模型的局限性——没有完美的工具

目录 ChatGPT与GPT-4的缺陷不足——任何工具都不是万能的1. 引言2. 事实性错误2.1 问题示例2.2 原因分析2.3 解决方法 3. 实时更新3.1 问题示例3.2 原因分析3.3 解决方法 4. 总结 参考资料其它资料下载 ChatGPT与GPT-4的缺陷不足——任何工具都不是万能的 1. 引言 2022 年末 C…

网页版直播和聊天室

序言 话说上一回,我说到了直播和聊天室,使用的是原生实现的。然而对我来说这太简单了,不足以体现我技术的优越性。下面开启我的装逼之旅。 效果 1.截图 2.视频 关键看游客模式,登录提醒,跳转登录,发送…

chatgpt赋能python:Python打开总闪退怎么办

Python打开总闪退怎么办 如果你从事或者熟悉Python编程,那么你肯定有遇到过打开Python总是闪退的情况,这让你倍感烦恼,不知道该怎么办。在这篇文章中,我们将会讨论Python打开总闪退的原因和一些修复方法。 问题原因 Python打开…

chatgpt赋能python:如何升级你的Python到最新版本

如何升级你的Python到最新版本 Python作为一种强大的编程语言,拥有广泛的用途,从网站开发到数据科学,都可以使用它来实现。然而,Python不断更新,每个新版本都带来了新的功能和改进,因此升级Python到最新版…

人工智能发展到GPT4经历了什么,从专家系统到机器学习再到深度学习,从大模型到现在的GPT4

大家好,我是微学AI,今天给大家讲一下人工智能的发展,从专家系统到机器学习再到深度学习,从大模型到现在的GPT4,讲这个的目的是让每个人都懂得人工智能,每个人都懂得人工智能的发展,未来人工智能…

调用百度文心AI作画API实现中文-图像跨模态生成

作者介绍 乔冠华,女,西安工程大学电子信息学院,2020级硕士研究生,张宏伟人工智能课题组。 研究方向:机器视觉与人工智能。 电子邮件:1078914066qq.com 一.文心AI作画API介绍 1. 文心AI作画 文…

AI绘画调用OpenAI-api接口【人工智能里的未来之城】:4 座未来派塔楼,天桥上覆盖着茂密的树叶,数字艺术

OpenAI绘画数字艺术是一种利用人工智能算法生成数字艺术的技术。该技术使用了一种称为GAN(Generative Adversarial Networks,生成对抗网络)的深度学习模型,这种模型由两个神经网络组成:生成器和判别器。 生成器的作用是生成新的数字艺术作品,它从随机噪声中生成图像,并…

集多个AI绘画开源模型于一体的工作台#invokeAI使用测评

原文:集多个AI绘画开源模型于一体的工作台#invokeAI使用测评-技术圈 当AI绘画模型和平台越来越多,你是否想使用统一美观的界面来使用你所有的AI绘画模型?invokeAI——这个精致的WebUI工具可以帮助你创建一个统一美观的工作环境: …

AI绘画升温、AI写作降温,AIGC玩“变脸”

配图来自Canva可画 自柯洁在“围棋人机大战”中惜败AlphaGo后,AI再次上演打败艺术家的戏码,AIGC(人工智能自主生成内容)时代真的要来了吗? 据了解,在今年科罗拉多州博览会艺术竞赛中,一名叫艾…