0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

详解ROMA中复杂图表的渲染实现

京东云 来源:jf_75140285 作者:jf_75140285 2025-10-21 13:57 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一、背景

ROMA承接很多复杂图表的渲染需求,在京东金融APP内,特别是首页首屏的图表,对图表渲染的及时性要求很高。近期业务反馈频繁重启时,首页的黄金走势图偶现渲染不出的问题,通过梳理图表的渲染流程,对缓存策略、视图加载和渲染过程进行了重构,确保渲染成功率,提升了渲染速度以及补充了异常重试的功能。

二、使用场景分析

京东金融App内有很多使用复杂图表的业务场景,以下截取部分场景。下图分别是黄金历史金价的走势图、用户购买的基金的收益走势图、小金库的收益柱状图、用户投资诊断的雷达图、省钱账单和AI助手账单趋势柱状图。

wKgZPGj3IMGAQ5tLAAQZOteqvo0650.png

可见,金融App内图表的使用具备种类丰富、数据信息量大,定制程度高、交互频繁等特点,经调研发现,Apache ECharts 是一个基于 JavaScript 的功能强大的开源可视化图表库,被广泛应用于数据分析、监控系统、报表工具等领域。并且支持定制支持的图表类型,可降低图标库的体积和提升图标库的加载速度。由于原生端并没有类似的图表库,因次决定在 ROMA 中引入 ECharts 来承接复杂图表的显示需求 。

三、重构过程分析

1、原理分析

ROMA 对外提供 echarts 标签,内部依赖提前加载了 echarts.js 库的 WebView,将图表数据交给准备好环境的 webveiw,达到渲染图表的目的。这里有一个重要的前提就是成功加载了echarts.js 库的 WebView 才具备快速渲染各类图表的能力。并且需要提前打通 ROMA 与 Native,Native 与 WebView 之间的数据通讯,保证数据在三端之间的顺畅流转。

为此自定制了 JRTransEchartsWebView 专门用于渲染 echarts 数据,JRTransEchartsComponent 作为标签实现在承接 webview 和 jue 环境的数据传递和业务逻辑处理。以下类图展示了各主要类对象之间的相互关系。

wKgZO2j3IMGAJ7lAAAJipjadxGE594.jpg

首先打通 Native 和 WebView 的数据交互,原生端在创建 WebView 的时候就向其环境中注入 window 的 message 事件监听,拦截指定类型的事件,获取从 WebView 环境中发来的数据。

NSString *jsStrring = @"window.addEventListener('message', (e) => { 
                        var customDict = {'function':'jdttransWindowEventDispatch', 
                                          'careParamDict':{'data': e.data, 'origin': e.origin}}; 
                        window.webkit.messageHandlers.JDTTransEchartsHandler.postMessage(customDict);})";
NSString *jscode = [NSString stringWithFormat:jsStrring];
WKUserScript *script = [[WKUserScript alloc]initWithSource:jscode injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
[webView.configuration.userContentController addUserScript:script];

Native 向 WebView 发送数据通过 evaluateJavaScript 的方式,向JS环境中输入数据:

NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:@{@"type":@"message"}]; 
[dict jdd_setObjectCheck:message forKey:@"data"]; 
[dict jdd_setObjectCheck:@"*" forKey:@"origin"]; 
NSString *dictString = [dict jdd_JSONString]; 
NSString *jsString = [NSString stringWithFormat:@"javascript:(function (){ 
                                                  var event = new MessageEvent('message', %@); 
                                                  window.dispatchEvent(event);})()",dictString]; 
[webView evaluateJavaScript:jsString completionHandler:nil];

JUE 和 Native 之间的通讯通道在初始化 ROMA 的 SDK 时就已经建立,Native 和 webview 的数据交互也通过 postMessage 的方式建立,如下图所示:

wKgZPGj3IMKAUtK_AABqBd-ss88690.jpg

以上,JUE 通过调用 call native 将数据发送到 Native,Native 通过 window.dispatchEvent 的方式将数据传递给 WebView。而图表上的手势交互等事件 WebView 通过 postMessage 的方式发送,在 Native 监听指定类型的 message 获取数据,通过处理并通过 fire event 触发到 JUE。

2、缓存的设计

对于 echarts 渲染图表数据,大致经历以下过程,创建 webview,加载 echarts.js 渲染库,资源开始加载 ,资源成功加载,最后渲染图表数据,这几个过程中,除了最后一步渲染数据,前面的步骤都可以提前做,越早完成前面的工作,越能提升图表渲染的效率。

wKgZO2j3IMOAfj05AAA7HIKfmzY261.jpg

为此,设计了可重复利用的并可自动扩容的 WebView 缓存容器 JRTransEchartsCache。在App启动阶段缓存 min 个 WebView 保存至缓存列表 cacheArray 中,并持续跟踪 WebView 加载 echarts.js 的阶段,确保在成功加载了 echarts.js 资源后再开始渲染图表数据。而对于过早的图表渲染指令,则先保存至指定标签的指令缓存列表 eventArray 中,待成功加载后,再渲染 eventArray 中的数据。

而对于 WebView 加载 echarts.js 资源失败的情况,也加入了失败重试的逻辑,当业务端发起数据渲染时会检查环境状态,而触发 echarts.js 的重新加载。

随着 WebView 使用,其状态被标记为 using,并根据使用的情况,自动触发 cacheArray 中的 WebView 扩容,最大扩容至 max 个。对于从详情页返回而释放的图表,其 WebView 将会被标记为 free ,可提供为其他的图表视图使用。 当使用图表的业务持续增多,当 cacheArray 中的 WebView 都被使用后,则新创建的 WebView 不再加入 cacheArray,遵循当次获取,当次创建,使用完成,就地销毁的原则。

3、渲染流程

下图记录了从 App 启动到业务创建 echarts 图表,到业务退出,到 App 退出期间,融合了缓存的初始化以及自动扩容,包括在 webview 加载 echarts.js 资源的不同阶段对渲染指令的处理,以及视图销毁后的内存处理等场景下的处理流程。

wKgZO2j3IMOAM9ZUAAMT5-fZGd0681.jpg

四、效果验证

为了更直观的展示图表在业务上的使用场景,使用重构后的图表标签渲染柱状图、条形图、折线图、饼图和组合图表,渲染的效果和操作都很流畅(由于文档的限制,对以下视频做了降频和清晰度的处理),效果如下:

wKgZPGj3IMqAcuXCAJXxyyZNU14523.gif

五、总结

通过此次图表的重构,在App冷启时,以 iPhoneXS Max 设备为例,首页首屏渲染图表数据的时间平均缩短了200ms;冷启首页首屏图表的渲染成功率,由之前的平均90%提升至接近100%;非首页首屏的图表渲染几乎零延迟;对于异常情况导致的环境初始化失败的问题,也在接受渲染指令时自检渲染环境并重启环境初始化,自动恢复数据的渲染。如果你也对图表渲染或者对跨端框架 ROMA 感兴趣,可留言交流。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 渲染
    +关注

    关注

    0

    文章

    79

    浏览量

    11350
  • 京东
    +关注

    关注

    2

    文章

    1066

    浏览量

    49889
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    知乎开源“智能预渲染框架” 几行代码实现鸿蒙应用页面“秒开”

    ,交互延迟等核心痛点,通过智能预测用户浏览目标进行提前渲染,只需几行代码即可显著提升复杂页面的加载性能,实现“页面秒开”的高效体验,为鸿蒙开发者带来开发效率和用户体验的双重飞跃。 随着鸿蒙生态快速发展,应用开发者难免会遇到一些性
    的头像 发表于 08-29 14:32 475次阅读
    知乎开源“智能预<b class='flag-5'>渲染</b>框架” 几行代码<b class='flag-5'>实现</b>鸿蒙应用页面“秒开”

    通道渲染:释放渲染的全部潜能!通道渲染的作用、类型、技巧

    在3D图形创作渲染通道(RenderPasses)是一项至关重要的技术,它通过将复杂渲染图像拆分为多个图层,如阴影、光照、法线等,使艺术家能够在后期制作
    的头像 发表于 07-15 14:22 450次阅读
    通道<b class='flag-5'>渲染</b>:释放<b class='flag-5'>渲染</b>的全部潜能!通道<b class='flag-5'>渲染</b>的作用、类型、技巧

    CPU渲染、GPU渲染、XPU渲染详细对比:哪个渲染最快,哪个效果最好?

    动画渲染动画3D渲染技术需要应对复杂的计算任务和精细的图像处理,作为渲染技术人员,选择合适的渲染模式,会直接影响制作效率和成品质量。在主流的
    的头像 发表于 04-15 09:28 1218次阅读
    CPU<b class='flag-5'>渲染</b>、GPU<b class='flag-5'>渲染</b>、XPU<b class='flag-5'>渲染</b>详细对比:哪个<b class='flag-5'>渲染</b>最快,哪个效果最好?

    2D图形渲染缓慢怎么加快?

    我有一个图形应用程序,它似乎渲染屏幕的速度很慢。按下屏幕后,通常需要相当长的时间来更新,大约 50 或 100 毫秒。 在应用程序启动时,我看到一条错误消息“GDK 无法创建 GL 上下文,回退
    发表于 04-02 06:46

    HarmonyOS应用高负载场景分帧渲染

    ,可以采用分帧渲染技术,将原本在一帧内加载的数据分散到多帧逐步加载,从而减轻单帧的渲染压力。不过,分帧渲染需要开发者精确计算每帧加载的数据量,操作较为
    的头像 发表于 03-25 10:28 867次阅读
    HarmonyOS应用高负载场景分帧<b class='flag-5'>渲染</b>

    基于鸿蒙原生ArkTS语法开发的图表组件--柱状图

    大家好,我是陈杨。在上一篇文章,我简要介绍了折线图的实现逻辑,并解释了整体图表的绘制规则。根据这些规则,我们还可以绘制更多种类的图表组件。在本期中,我将讲解如何
    的头像 发表于 03-16 16:01 830次阅读
    基于鸿蒙原生ArkTS语法开发的<b class='flag-5'>图表</b>组件--柱状图

    Labview坐标与图表上的点

    怎么把(x,y)这一坐标对应到Labview图表上的点?
    发表于 02-19 18:04

    GPU渲染才是大势所趋?CPU渲染与GPU渲染的现状与未来

    在3D建模和渲染领域,随着技术的发展,CPU渲染和GPU渲染这两种方法逐渐呈现出各自独特的优势,并且在不同的应用场景各有侧重。尽管当前我们处在一个CPU
    的头像 发表于 02-06 11:04 1249次阅读
    GPU<b class='flag-5'>渲染</b>才是大势所趋?CPU<b class='flag-5'>渲染</b>与GPU<b class='flag-5'>渲染</b>的现状与未来

    SciChart 3D for WPF图表

    DirectX 支持的 WPF 3D 图表和广泛的 API 完成工作。 WPF 3D 图表性能 我们传奇的 WPF 3D 图表性能由广泛的端到端性能优化、不安全代码、C++ 互操作、DirectX
    的头像 发表于 01-23 13:49 1262次阅读
    SciChart 3D for WPF<b class='flag-5'>图表</b>库

    SciChart—高性能的JavaScript图表和图形库

    使用 SciChart 的 JavaScript 图表库为您的 JS 应用程序发现终极解决方案。 使用 WebGL 创建动态、高速的图表和图形,非常适合实时处理复杂的数据可视化。使用我们强大而灵活
    的头像 发表于 01-22 10:15 2552次阅读
    SciChart—高性能的JavaScript<b class='flag-5'>图表</b>和图形库

    Chart FX——金融图表

    和收盘价之间的关系被视为重要信息,是这些图表的精髓所在。 使用 Chart FX,您可以创 高低收盘图、开高低收盘图和蜡烛图。向这些图表传递数据的过程与向 Chart FX 任何图表
    的头像 发表于 01-15 17:20 833次阅读

    Chart FX——图表导出

    Web格式的图片(如 PNG 或 JPEG)。 Chart FX 还有其他文件类型,称为 “图表模板”,允许您将图表的外观(颜色、图表类型和样式、可视工具等)保存在一个文件
    的头像 发表于 01-15 14:38 699次阅读
    Chart FX——<b class='flag-5'>图表</b>导出

    Chart FX——打印图表

    另一个重要的问题是图表打印的页数。当您需要打印包含大量点的图表(可滚动)时,Chart FX 将根据需要打印尽可能多的页面。若使用压缩属性, Chart FX 会通过重新计算适当的值使所有点都能
    的头像 发表于 01-13 09:12 642次阅读
    Chart FX——打印<b class='flag-5'>图表</b>

    Chart FX-图表渲染尺寸和格式

    渲染尺寸 网络开发人员的常见做法是创建一个大图表,以便于在浏览器上阅读。然而,这种做法可能是影响服务器在大负载情况下的表现和性能的一个重要因素。从本质上讲,图表越大,意味着必须处理、生成、存储和最终
    的头像 发表于 01-08 11:25 585次阅读
    Chart FX-<b class='flag-5'>图表</b><b class='flag-5'>渲染</b>尺寸和格式

    Chart FX-选择图表输出

    的格式即可。 您也可以指示 Chart FX 以多种格式渲染图表。配置图表的方法也有多种。 作为一个服务器控件,Chart FX 支持一种名为 RenderToStream 的方法,该方法允许开发人员选择
    的头像 发表于 01-05 11:06 798次阅读
    Chart FX-选择<b class='flag-5'>图表</b>输出