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

京东云开发者
• 阅读 4

一、背景

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

二、使用场景分析

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

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

可见,金融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 环境的数据传递和业务逻辑处理。以下类图展示了各主要类对象之间的相互关系。 详解ROMA中复杂图表的渲染实现

首先打通 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 的方式建立,如下图所示:

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

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

2、缓存的设计

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

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

为此,设计了可重复利用的并可自动扩容的 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 资源的不同阶段对渲染指令的处理,以及视图销毁后的内存处理等场景下的处理流程。

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

四、效果验证

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

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

五、总结

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

点赞
收藏
评论区
推荐文章
Stella981 Stella981
4年前
React 服务端渲染完美的解决方案
最近在开发一个服务端渲染工具,通过一篇小文大致介绍下服务端渲染,和服务端渲染的方式方法。在此文后面有两中服务端渲染方式的构思,根据你对服务端渲染的利弊权衡,你会选择哪一种服务端渲染方式呢?什么是服务器端渲染使用React构建客户端应用程序,默认情况下,可以在浏览器中输出React组件,进行生成DOM和操作DOM。Re
Stella981 Stella981
4年前
H5游戏性能优化整理(cocos
近期在一家公司负责H5游戏加载速度优化,这里把近期做的项目优化项做一个整理分享:(若文中有错误的地方,还请指出。)   分享流程:了解html渲染流程html相关优化http相关优化项目结构和游戏流程及优化游戏渲染相关优化代码编写优化html渲染流程HTML解析过程:构建DOM树、构
Stella981 Stella981
4年前
Jfreechart绘制漂亮的图表
要想绘制出漂亮的图表,就必须了解图表的构成部分,将图表进行分解成N个部分。然后再对每一个部分进行渲染,设置样式:包括背景色、轮廓线条样式和颜色、填充颜色、字体大小、样式、颜色。同时,需要确保在整个项目中,图表的样式风格整体统一,统一,和谐才能打造漂亮、干净、专业的外观.1.使用JfreeChart创建柱状图,折线图,饼图,堆积柱状图,时间序列图
Stella981 Stella981
4年前
JsRender 前端渲染模板基础学习
JsRender前端渲染模板使用模板,可以预先自定义一些固定格式的HTML标签,在需要显示数据时,再传入真实数据组装并展示在Web页中;避免了在JS中通过“”等手动分割、连接字符串的复杂过程;针对高性能和纯字符串渲染进行了优化;无需依赖DOM和jQuery;优先使用场景:元素重复出现;动态加载数据,并前端显示;JsR
绣鸾 绣鸾
1年前
KeyShot 2023.3 Pro for mac(3D渲染和动画制作软件)
是一款高级渲染和动画软件,它可以帮助用户快速创建高质量的渲染效果和动画效果。KeyShotPro具有以下特点:1.实时渲染:KeyShotPro支持实时渲染,用户可以在渲染过程中实时预览效果,节省了大量的时间和精力。2.高质量渲染:KeyShotPro支持
鸿蒙跨端实践-ArkTS和CAPI的混合开发实现
一、背景在文章中,讲述了动态化适配鸿蒙的方案实现,当在鸿蒙系统进行UI渲染的时候,我们使用了系统的组件进行递归渲染。在iOS和Android也是借助各自系统组件进行的渲染,但是在鸿蒙系统会存在以下4个严重问题:1.UI层级过多以金融APP理财频道页中的一个
京东云开发者 京东云开发者
3小时前
前端部署新方案-技术篇(总体架构设计)
一、背景ROMA承接很多复杂图表的渲染需求,在京东金融APP内,特别是首页首屏的图表,对图表渲染的及时性要求很高。近期业务反馈频繁重启时,首页的黄金走势图偶现渲染不出的问题,通过梳理图表的渲染流程,对缓存策略、视图加载和渲染过程进行了重构,确保渲染成功率,
铁扇公主 铁扇公主
2年前
macos动画制作渲染软件分享~
KeyShotPro是一款高级渲染和动画软件,它可以帮助用户快速创建高质量的渲染效果和动画效果。KeyShotPro具有以下特点:1.实时渲染:KeyShotPro支持实时渲染,用户可以在渲染过程中实时预览效果,节省了大量的时间和精力。2.高质量渲染:Ke
绣鸾 绣鸾
1年前
KeyShot 2023.3 Pro for mac(渲染和动画制作)
是一款高级渲染和动画软件,它可以帮助用户快速创建高质量的渲染效果和动画效果。KeyShotPro具有以下特点:1.实时渲染:KeyShotPro支持实时渲染,用户可以在渲染过程中实时预览效果,节省了大量的时间和精力。2.高质量渲染:KeyShotPro支持
公孙晃 公孙晃
1年前
KeyShot 2023.3 Pro Mac破解版 附 安装激活教程
是一款高级渲染和动画软件,它可以帮助用户快速创建高质量的渲染效果和动画效果。KeyShotPro具有以下特点:1.实时渲染:KeyShotPro支持实时渲染,用户可以在渲染过程中实时预览效果,节省了大量的时间和精力。2.高质量渲染:KeyShotPro支持