网易云音乐 RN 低代码体系建设思考与实践

作者:BoBo (沈萧寒)

前情回顾

Tango 是一个用于快速构建低代码平台的低代码设计器框架,并以源代码为中心,执行和渲染前端视图,并为用户提供低代码可视化搭建能力,用户的搭建操作会转为对源代码的修改。借助于 Tango 构建的低代码工具或平台,可以实现 源码进,源码出的效果,无缝与企业内部现有的研发体系进行集成。

开源情况

目前 Tango 设计器引擎部分已经开源,正在积极推进中,可以通过如下的信息了解到我们的最新进展:

欢迎大家加入到我们的社区中来,一起参与到 Tango 低代码引擎的开源建设中。有任何问题都可以通过 Github Issues 反馈给我们,我们会及时跟进处理。

往期系列文章

本文主要探讨基于 Tango 低代码在 RN 场景如何打造一套标准低码研发体系。

为什么选择 RN 作为跨端方案

主流的跨端方案,建全的社区生态

RN(React Native)是 Facebook 开发的一种基于React框架的移动应用开发框架。它可以用于同时开发 iOS 和 Android 平台的跨平台移动应用程序。

在 npm trends 上可以看到,RN 每周的下载次数,稳固上升,相比5年前,下载量已经翻了接近10倍之多,Github Star 数量也来到了 110K 之多,拥有非常庞大的社区生态。

React 生态圈,支持动态更新

RN 上手成本较低,对于前端开发同学,React 技术栈可以无缝迁移,学习成本较低,对于客户端同学,RN 方案省去了大量编译的时间,相比于传统的原生开发,RN 可以大大减少代码重复,提高开发效率。此外提供了丰富的组件库和API,开发者可以使用这些组件和API快速构建用户界面和实现各种功能。同时,RN还具有良好的性能表现,可以轻松实现原生应用的用户体验。

在国内,无论大公司、小公司都钟情于应用的动态更新。因为动态更新能降低产品的试错成本。如果产品策略有调整,可以立马上线,线上有小问题也可以快速修复。但能够既满足动态更新,又能跨端,还能满足复杂业务需求的只有 JavaScript 语言。

新架构开启全新时代

2022 年,对于 React Native 来说是一个大年,因为重构已久的 React Native 新架构已经确定会在今年正式推出,相对于老架构,新架构在最关键的性能问题上有了非常大的提升,这将会为 React Native 开启一个全新的阶段。

React Native 新架构默认用的 JavaScript 引擎是 Hermes 引擎。Hermes 是一款专为移动端打造的 JavaScript 引擎,它支持 JavaScript 的 AOT 预编译。带来了更好的启动性能,此外在渲染机制,通信性能上均有成倍的提升,云音乐也第一时间进行了"尝鲜",详细迁移过程见:网易云音乐 RN 新架构升级实践

云音乐 RN 研发现状

RN 有着众多优势,云音乐也有相当多的 RN 需求,在需求不断地迭代,研发不断地投入过程中,还是暴露了一些问题。回顾一下 C 端场景的特点,往往是重视觉,重交互,我们来看一下目前 介入一个 RN 需求开发并最终交付上线的核心过程:

研发过程

准备开发环境

  • Mac 电脑 / 手机设备 (依赖物理设备)
  • App 测试包 (依赖客户端打包)
  • 模拟器 & XCode & ... (依赖运行环境)
  • RN Debugger (依赖调试工具)
  • RN 开发相关文档 & 平台 (依赖多个平台跳转)
  • 编辑器 IDE

静态页面开发 & 还原视觉(交互)稿

如图所示,开发第一阶段,还原设计稿,这个过程其实可以追溯到需求评审阶段:设计稿的页面构成,哪些已有现成组件,哪些需要定制开发,样式部分的代码如何编写等。

进入业务开发阶段

不同场景的 RN 需求对应的实际业务开发有所不同,以下三种是最为常见的业务开发类型。

  • 埋点开发: 页面曝光埋点,点击播放埋点等,需要开发者手动注入埋点,进行上报。
  • 数据获取: 例如获取歌曲列表接口,编写代码获取数据,组件消费数据。其实这个过程往往是会被开发者忽略的环节,假设某个业务场景消费的是相同的数据和逻辑,那么这时候我们可能有两个选项:复制之前的代码,或是将其封装为工具包或者耦合至组件进行复用。
  • 协议调用: 音视频播放等客户端协议调用联调,需查阅相关协议文档或工具组件文档。

项目验收/测试

  • 视觉反复修改验证,多主题验证,多机型验证 (开发)
  • 双端兼容性,多主题适配性 (开发 / 视觉)
  • 视觉验收页面还原度 (视觉 / 策划)
  • 业务方验收整体功能(QA / 策划)

较高的研发成本

  • 相对 H5 应用,RN 应用本地开发环境较重,依赖较多。
  • 页面灵活度高,需要熟悉现有组件体系,识别组件,还原视觉。
  • 研发链路周边生态零散,未整合,开发时平台跳转重,链路长。
  • 相同业务逻辑代码跨项目复用率低,未得到有效处理。
  • ...

我们期望构建一套为低码为中心的在线研发体系,通过整套体系标准化来解决目前的问题,降低研发成本和门槛,提高效能

标准化的低码研发体系

研发链路前后对比

RN 迭代从需求到交付涉及到多个核心环节,以下是目前开发现状和低码研发体系的对比。

Tango 将提供以源码为中心的 RN 在线搭建能力,支持 RN 应用快速交付,并提供标准化的线上研发流程

传统移动端搭建的问题和瓶颈

云音乐在移动端传统搭建上已经有了一些实践,但是在实际使用过程中遇到了一系列的问题。

DSL 方案局限性

首先传统搭建平台大多基于 DSL 驱动,再交由 DSL 解析器进行渲染,映射到对应的组件。DSL 本质上其实就是对代码的一种抽象,描述为一种 Schema 的形式进行可视化编排,最终还是要映射到真实的组件,组件消费 DSL 中携带的信息

如果面向业务模式稳定的固化场景,进行深度垂直定制,在这个前提下一套 DSL 确实可以解决大部分场景,剩下的场景可以直接放弃(交由开发介入)。

但是移动端场景的特点就是灵活性高 ,而此类产品的特点往往面向运营等非开发角色进行无码搭建,快速交付。 在实际使用过程中,会遇到 DSL无法满足业务需求,需要开发介入定制DSL,升级组件 的情况。

这个过程中其实带来了较大的成本:

  • 搭建平台基于 DSL 驱动,随着业务的迭代,DSL 需要不断升级以满足需求的变化
  • DSL 的版本迭代和规范需要严格遵守,对应组件库和解析器等中间件的维护仍需要投入开发资源
  • DSL 映射为客户端组件时,DSL 的变更依赖客户端迭代,存在隐形风险,且容易出现 RN 对应一套标准客户端组件库,DSL 对应另一套客户端组件库的情况,维护成本非常高,侵入性强。
  • 面向运营,最后很大概率是研发进行兜底开发,逐渐降低使用意愿

基于 AST 驱动

Tango 通过 AST 驱动,可视化的修改实际上就是对源码进行修改,对源码的直接修改其实就跳过了 DSL 映射到源码的过程,这样做的好处是,没有中间产物的形成,不需要额外的开发资源维护,也不会耦合至其他环境,可以跟现有的 云音乐 RN 研发生态较好的融合。所以 Tango 主要面向研发同学,解决灵活场景下的 RN 开发,侧重对研发环节进行提效在一些轻量场景,也可以作为 NoCode 平台,提供运营同学可视化搭建的能力。

从上图可以看出:无论 DSL 还是 AST,最终都是映射到实际的组件,组件能力的强大与否会直接影响整个低码体系,以及需求交付的效率。组件,是非常重要的!

构建在线真机预览调试环境

RN 和 Web 应用在线开发最大的区别在于 运行环境的不同,Web 场景可以基于 CodeSandbox 实时预览,RN 场景依赖 App 物理环境。

常见的 RN 应用调试环境:

方案 描述 优点 缺点
Expo Snack 在浏览器中运行和预览 React Native 代码 无需安装任何本地环境 依赖于 Expo SDK,功能受限,不适用于业务场景
模拟器 使用本地模拟器(如 iOS 模拟器、Android 模拟器) 提供与实际设备相似的运行环境 需要安装和设置本地模拟器,可能占用较多资源
物理手机 在真实手机设备上运行和预览应用 提供与实际设备完全一致的运行环境 需要连接和配置实际设备,可能受限于设备的可用性和数量
RN for Web 在浏览器中运行和预览 React Native Web 代码 可以在多个平台(包括桌面浏览器)上预览应用 组件需要适配 Web, 原生 API 可能不可用或存在差异

目前云音乐 RN 研发主要使用模拟器 + 真机扫码两种形式进行开发,起步我们考虑了相对轻量的方案:RN For Web 进行初步搭建及预览,再结合真机扫码进行实际联调 ,这样做的好处是在设计器运行沙箱上可以复用现有 CodeSandbox 能力,不需要做定制,但该方案马上暴露了一系列问题

  • 现有组件并非均兼容 RN Web,接入存在较大适配成本,收益低
  • Web 环境无法模拟真机环境,协议无法调用,无法满足实际开发场景
  • RN Web 与真机视觉还原度存在一定差异,视觉存在二次回归成本
  • ...

综上,选用 Mac IOS 模拟器作为真机运行环境,完美贴合本地开发体验 。也带来了更大的挑战,我们需要模拟一套在线开发环境(远程本地开发):

  1. 代码在哪里运行 ?
  2. 模拟器在哪里运行 ?
  3. 页面如何获取模拟器界面 ?
  4. 多人使用模拟器如何分配调度 ?
  5. 页面如何与模拟器通信交互 ?
  6. App 内置的联调工具如何使用 ?
  7. RN 运行日志如何透出 ?
  8. 与低代码平台怎么结合 ?

下面我们来具体看一下如何解决这些问题。

Metro 远端构建服务

首先我们来解决第一个问题,回顾一下本地开发过程:启动 RN 项目,通过模拟器或者真机 App 访问 RN bundleUrl 进行调试预览,本地启动的 dev server 其实就是打包服务(metro dev server),产物为:

arduino 复制代码
xx://10.10.10.10:8081/index.ios.bundle

那么远端构建其实就是将本地流程容器化:拉取项目代码,构建打包,输出产物。如图所示:

在低码平台初始化时将完整的代码推送至构建服务,构建服务分配一个实例进行上述构建过程,平台或者手机访问打包产物即可,代码变更时 patch 最新代码,触发 HMR 热更新即可。

基于直播流的模拟器投屏方案

模拟器运行环境

接下来第二个问题,模拟器运行环境可以使用 Mac 系列设备,包括不限于 Mbp,Mac mini,Mac Studio 等均可,在 Mac 物理机上对模拟器进行多开,实际可以并发启动的数量与设备性能正相关,相同规格的设备,推荐使用 ARM 架构的设备,性能会更加好。接下来对应第三个问题就是如何将模拟器的画面传输至页面。

图传方案/投屏方案对比

社区方案,Expo Snack dev,支持真机预览 & Web 两种形式。

Expo 真机界面通过实时图传的方式进行返回 (如下图所示),我们也进行了类似方案的实践,实践结果是在 20 ~ 30FPS 帧率下实时截屏图传返回至 Web 再显示,Socket 存在时序和堆积问题,造成画面时序不一致且闪烁严重

其实还有一种方式可以获取到屏幕的实时画面,通过直播推流的形式,将物理屏幕进行捕获推流,网页拉流播放即可,也就是传统意义上的"直播"

起初使用 ffmpeg 进行画面捕获并推流,但由于同一台物理机上会多开模拟器,并且存在遮挡问题,模拟器窗口的定位,宽高的识别成本较高。

arduino 复制代码
ffmpeg -f x11grab -video_size 1280x720 -i :0.0+100,200 -f alsa -i default -c:v libx264 -preset ultrafast -pix_fmt yuv420p -c:a aac -f flv rtmp://your-streaming-server-url/your-stream-key

最终采用 OBS 进行窗口捕获及推流,OBS 优势:自带窗口捕获,画布调整,完整的推流参数配置,以及内置 Web Socket 服务器可以进行直播控制

OBS 低延迟直播方案

常见的直播方案如下:

方案 性能 响应速度 优缺点
RTMP 优点:广泛支持、低延迟、稳定性较好;缺点:需要服务器支持、不适用于移动设备
HLS 优点:适用于移动设备、可实现自适应码率;缺点:较高的延迟
WebRTC 优点:低延迟、实时性好、支持点对点传输;缺点:浏览器兼容性较差
SRT 优点:低延迟、稳定性好、可靠性高;缺点:需要额外的配置和支持
DASH 较慢 优点:适用于移动设备、高度可定制;缺点:较高的延迟、需要额外的服务器支持
RTSP 较慢 优点:适用于视频监控、支持多种传输协议;缺点:延迟较高、不适用于移动设备

由于云手机交互时效性要求,需要一套 低延迟直播方案,经过综合对比:

选用 SRS 流媒体服务器进行转码,使用 OBS RTMP 进行推流,Web 使用 WebRTC 进行拉流得到云手机实时画面。

SRS 服务器

SRS是一个开源的(MIT协议)简单高效的实时视频服务器,支持RTMP、WebRTC、HLS、HTTP-FLV、SRT、MPEG-DASH和GB28181等协议。 SRS媒体服务器和FFmpeg、OBS、VLC、 WebRTC等客户端配合使用,提供流的接收和分发的能力,是一个典型的发布 (推流)和订阅(播放)服务器模型。 SRS支持互联网广泛应用的音视频协议转换,比如可以将RTMP或SRT, 转成HLS或HTTP-FLV或WebRTC等协议。

使用官方 Docker 镜像,一键启动。详见 SRS 官方文档

bash 复制代码
CANDIDATE="192.168.1.10"
docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 \
    --env CANDIDATE=$CANDIDATE -p 8000:8000/udp \
    registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5 ./objs/srs -c conf/rtmp2rtc.conf

OBS 推流与拉流

接下来对 OBS 进行一定的配置,Mac 设备优先选用 H264 硬件编码进行推流,码率和帧数控制在一定范围,推流地址设置为 rtmp://{your_ip}/live/{your_livestream_key} 即可。

网页端使用 WebRTC 播放器进行拉流,WebRTC(Web Real-Time Communications)是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。

对 WebRTC 还不太熟悉的同学可以详细阅读一下 Web RTC API

效果如图所示,平均响应速度在 0.5s 至 2s 内

至此,我们已经获取到实时画面,模拟器摇身一变成为云手机 ,接下来的核心问题:解决云手机的通信和交互,以及多台云手机如何调度分配的问题

基于 Socket 网关的云手机调度 & 通信交互方案

基于调度中心的通信机制

首先解决如何分配的问题,场景是:用户访问低码平台时,需要使用一台云手机,而一台物理机上可以启动多台云手机,并可以同时有多台物理机,需要正确的分配到一台设备。

有同学可能发现了,这个模式非常像"反向代理",那么顺着这个思路,我们需要实现一个虚拟网关,负责通信和调度,我们来看一下大致过程:

  • 将物理机中的设备主动上报到调度中心,并建立 Socket A,上报的设备存储在一个"虚拟设备池"中。
  • 调度中心对低码平台暴露一个 /lock 接口,从设备池中获取可用设备并占用,返回占用的设备信息,同步设备池状态,完成分配
  • 低码平台与云手机建立 WebRTC 连接,获取到屏幕实时画面。

这里还有一个问题,如何保证高并发下云手机与用户的一致性 (不会出现同一个设备被重复分配的问题), 服务端的同学应该非常熟悉这个场景,关键词如:"库存","超卖","秒杀","抢票","下单","抽奖"等场景均会涉及到这个问题,我们可以通过加锁来保证资源访问的单一,如 Redis 分布式锁,感兴趣的同学可以自行查阅一下相关资料。

此时用户已经分配到云手机,且可以看到实时画面。接下来就要解决如何通讯的问题,既然是通讯那么肯定首选长连接,我们需要与云手机建立 Socket B,该 Socket 可以将页面的消息发送至云手机 App 并将 App 中的数据返回至平台。上述流程如图所示:

此时云手机通讯机制已经建立,我们可以请求云手机加载某个 RN 页面,但此时云手机无法"使用",云手机需要支持基本的点击/滑动交互:

在线调试能力

基于已经建立的通讯连接,我们可以远程"操控"云手机并获取到 App 中运行的信息以及日志,在平台侧进行展示,为在线联调提供了通道,目前主要开放了以下几个能力:

快捷工具栏:为了还原本地开发体验,我们将调试工具中常用的能力进行了可视化,在云手机一侧提供了工具栏,进行快速使用。

运行状态栏: 在底部状态栏的左侧显示了目前云手机的设备信息以及当前 App 的信息。

日志信息栏 : 显示当前 warning,error的数量,点击后展开 Console 面板,查看当前 Metro 日志信息,对齐 Chrome Console 体验。

至此,前文提到在线开发的7个问题均已解决,我们来看最后一个问题,如何与低码进行结合

多维度的可视化搭建

模拟节点选中效果,结构树可视化编排

在 C 端场景 Tango 也保持了社区常见的交互形式,通过页面结构树面板可以对页面中的节点进行增删改查,调整位置等操作。

常见交互为大纲树和设计器都需要在点击后回显选中的节点,由于 RN 代码实际运行在客户端中,此处就带来了另一个问题: 静态的 RN 代码节点与客户端运行时的节点如何映射,确实是一个比较有趣的问题,我们可以延续之前模拟点击交互传的思路,大致如下:

通过标记节点,客户端计算返回选中的节点坐标宽高信息,模拟选中框覆盖在云手机上,达到选中的效果。

双模式切换,源码模式左看右写快速开发

对于专业 RN 开发同学,或复杂场景需切换至源码进行开发,我们也对源码模式下的开发体验进行了增强,提供"左看右写"的模式,结合完善的在线调试工具,典型场景下,可以完全脱离本地开发环境,使用线上进行开发

多形式的代码生成

Tango 本质上基于源码驱动 ,在 CMS B 端场景,CRUD 类型的页面可以通过数据模型驱动来快速初始化一个可用页面。由于 C 端场景的高灵活度,开发时大部分时间是在还原样式,实现静态页面。通过 D2C AIGC 模板市场等能力可以对设计稿,典型场景进行快速还原并得到初始代码,再结合低码平台进行二次搭建,来降低从 0 搭建成本。

低码生态建设

Tango 低码的理念不仅限于"在线","可视化搭建",旨在构建一个以源码为中心,完整的低码研发生态体系

运行时框架 & 组件

低码接入的组件能力完善与否也直接影响开发搭建效率,我们针对典型场景使用的高频组件进行细分,对此类组件进行"低码化"增强,减少原子组件重复低效使用的问题。

此外 Tango RN 也延续了 Tango Boot 的应用架构推崇 View-Model-Service 三层模型,演化为 Tango RN Boot 应用框架,其中模型层定义了 Observable States,视图层观察 Model 的变化而进行自动更新,服务层用来创建一组服务函数,供视图层和模型层消费。基于 Tango MVVM 理念,Tango RN Boot 在 Stores & Services 以外,对 RN 常见开发能力进行封装,让开发者可以快速构建 RN 应用。

数据资产沉淀与可视化编排

这里先挖个坑,后续会有专门的文章详细介绍。

...

云手机还能做什么

云手机顾名思义就是取代了物理手机,目前依赖物理手机的场景大部分都可以通过云手机进行平替,并且由于云手机拥有建全的通信机制,交互能力,可以畅享更多的可能性,以下罗列了一些比较常见的应用场景:

  • 扫码场景 所有扫码类的场景都可以接入云手机进行效果预览,通过云手机代替真实手机访问扫码结果

  • 协议调用/服务化 客户端协议可以通过云手机进行远程联调调用,测试协议调用情况,可以借助云手机作为运行容器将协议的调用服务化,包装为 API 接口供三方平台使用。

  • 视觉验收 可以使用云手机来查看应用程序在不同设备和屏幕尺寸上的显示效果,并确保界面元素的布局、颜色和交互行为的一致性。

  • 测试回归 可以用于测试回归,测试团队可以使用云手机来运行自动化测试脚本,执行一些特定的任务。

低码的天平问题

篇幅较长,如果您看到这里了,非常感谢,希望能给各位带来一些收获。最后还是想聊一点题外话,市面上大大小小的"低码"产品非常多,包括不限于各种可视化搭建平台,(X)aaS平台,代码插件工具等。

低码理念的出现本质上是为了解决某个(类)问题或某个(些)场景。在近几年社区低码概念的发展以及业务实践经验来看:

过于通用的方案: 不够贴合业务,无法开箱即用,接入成本高,门槛高,拓展性强。 过于垂直的方案: 贴合业务场景,可以开箱即用,接入成本低,门槛低,拓展性差。

这就是一个 "天平" 问题,如何寻找到平衡点是一个值得持续探讨的问题,低码的本质是提效,是解决问题,在这个大前提下,如何做到高内聚,低耦合的 T 型架构,是值得低码从业者持续思考和实践的 ~ 共勉 ~

总结

目前 RN 低代码研发体系建设正在持续进行,相关周边生态的能力正在不断完善,后续我们会将云手机能力下沉服务化,并逐步支持覆安卓云手机,以中台的形式开放给更多有需要的同学快速使用。之后我们会对核心模块的技术细节,以及可视化数据编排等进行更为详细的介绍,请持续关注我们的低码系列文章,感谢 ~

参考链接

最后

更多岗位,可进入网易招聘官网查看 hr.163.com/

相关推荐
桃园码工4 分钟前
15_HTML5 表单属性 --[HTML5 API 学习之旅]
前端·html5·表单属性
百万蹄蹄向前冲44 分钟前
2024不一样的VUE3期末考查
前端·javascript·程序员
轻口味1 小时前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami1 小时前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
吃杠碰小鸡2 小时前
lodash常用函数
前端·javascript
emoji1111112 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼2 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs
m0_748250032 小时前
Web 第一次作业 初探html 使用VSCode工具开发
前端·html
一个处女座的程序猿O(∩_∩)O2 小时前
vue3 如何使用 mounted
前端·javascript·vue.js
m0_748235952 小时前
web复习(三)
前端