分享人:Mark Wu( 吴银波 )云智慧前端工程师,致力于云智慧大屏产品及ITSM、DOMM、DOEM等产品线定制化开发,拥有丰富的前端性能优化和开源项目经验。
不知道你有没有碰到过这些情况:
假如你也有这些情况,那么恭喜你,这只是开始...
假如没有,那么也恭喜你,你迟早会遇到的...
那么, 如果我们能够找到一些快速定位问题的方法,那大概率可以避免这样的问题,大幅提高效率。
结合具体的示例来分享一下我是如何利用Performance性能面板和console面板来定位问题的,末尾也和大家分享一个使用这个方法优化后造出的轮子。
现在看一下Performance性能分析报告:
可以看到时间轴下面包含FPS、CPU、网络等;这一块主要 关注FPS,观察有没有飘红的区域,可定位到下面的Main指标对应的js执行过程,观察程序哪部分影响了页面性能,这能帮助我们快速确定需要优化的代码位置;
还应关注总 阻塞时间,这是对当前页面运行是否流畅的一个总体评价,应尽可能减少阻塞时间;
最后关注 摘要部分,对比正在执行脚本与渲染时间,确定JS执行和页面渲染哪个为主要优化对象(优化往往是两者并行)。
下面两个示例分别侧重JS执行效率和页面渲染效率进行优化,JS执行效率主要降低代码空间复杂度,减少不必要的内存开销,避免深拷贝,及时清除定时器等;页面渲染效率主要减少页面重排次数,尽量同步页面动画与显示器帧数刷新。
DOMM定制化项目:现场某场景内G6拓扑组件节点数量一多,浏览器假死,开发环境无法重现。
分析:页面假死通常是js线程阻塞、栈内存溢出,或者是页面动画过于复杂导致css线程卡死、频繁布局抖动等造成的。
Performance分析:
从上图可以看到js执行时间比较长,渲染时间占用比较短。这种情况先排除css线程以及布局抖动的影响,确定问题是在JS执行上。并且在页面性能优化时针对这种情况想要再去较大地优化页面渲染效率是很难也是不划算的,这个时候的重点也是在JS执行效率上。
通过对于Performance的Main进行分析并结合代码分析,确定问题代码区域,在代码执行主要节点上打印时间消耗,针对耗时较大的区域代码进行细化,最终确定问题代码。
计算耗时打印
耗时打印情况:
分析:可以看到这部分JS代码总执行时长1027ms,其中计算节点、计算连线耗时最长,而且重复执行了两次,设置防抖函数。
分析:设置防抖后,此段JS总执行时长599ms,继续细化“计算连线”部分耗时打印。
细化耗时打印:
a、 “ 连线计算 ” 耗时过长
分析:“计算连线”段JS代码被多次引用,继续细化这部分耗时打印;
b、单次连线耗时
分析:“连线耗时”为计算单次节点间连线耗时,大量执行且单次耗时不短,对此部分代码继续细化,发现存在可疑的代码--深拷贝。
c、深拷贝耗时
分析:“克隆耗时”的打印规律和“连线耗时”相当,且存在耗时较长问题,使用累加计时打印深拷贝总体耗时。
分析:深拷贝累加有三次打印,总耗时679ms,占比很大。
耗时定位:每次深拷贝耗时较长,深拷贝算法需要优化或者连线计算逻辑避开深拷贝
分析:拷贝层级过深,造成耗时较长,使用浅拷贝代替。
优化深拷贝耗时后打印
分析:使用浅拷贝打印总耗时6ms,相对于原来的679ms耗时很短。
现在不能确定现场部署就没有问题,再来看看拓扑节点数量对于JS执行以及页面渲染效率的影响。
分析:可以看到200节点与单节点页面渲染耗时相差不大,主要是执行JS脚本多了25ms,因为现场最大会有800多个节点的情况,简单计算了下,发现耗时对比原先的1027ms仍有很大提升。
遇到问题:之前开发一张大屏,本地跑没有问题,但是联调测试发现右侧的滚动组件模块(有4个)中有一个模块没有东西,接口正常返回,字段也是正常的。最后发现是接口返回了190多条数据,前端全部渲染了这些组件,致使模块假死。
先看下现场效果图。左侧分别是地图、轮播图、饼图、轮播图,中间上面是两个拓扑链路图轮播,下面是4个echarts图表,右侧是4个滚动模块(图片不全)。现在除了要解决上述问题还得做好整张大屏的加载同步。
现场大屏的展示效果↓
分析:现在来看这个问题,既然全部加载会导致模块假死,那就不加载全部,而是采用过一条渲染一条(onebyone)方式,现在演示单个效果:
onebyone模式 单模块效果
注:绿框为可视区域,红框为滚动组件,渲染固定数量的滚动单位,利用css控制页面动画,定时刷新对应的滚动单位。
onebyone模式 单模块Performance分析面板
分析:单组件运行已产生JS线程阻塞,执行JS脚本、渲染耗时相当。
onebyone模式 4模块 Performance分析面板
分析:执行JS脚本、渲染耗时相当,产生较长JS线程阻塞,且页面会发生布局抖动、掉帧。
代码分析:由于每次一个滚动单位过场后会被替换,引发重排,然后每个模块如此,4个模块叠加,会一直连续引发页面重排,然后这里用的是js控制布局导致间距不一致。当时的改进方案是要减少重排次数以及替换布局方案,怎么减少重排次数?
“一次计算整个过场面板,每次过场面板过场后才去更新整个面板,替换为flex布局。”
现在来看一下这个方案的效果:
twomove模式单模块情况
twomove模式单模块Performance分析面板
分析:单组件运行未产生JS线程阻塞,单个模块同屏产生的dom数量比onebyone模式多,所以优势并不明显。
twomove模式4模块 Performance分析面板
分析:执行JS脚本、渲染耗时相当,JS线程阻塞时间减少,页面未出现布局抖动、掉帧,多模块下优势突出。
通过Performance性能分析确定主要优化方向,针对JS执行可以结合Main指标使用console对问题代码进行定位,针对页面渲染应减少页面重排降低页面渲染消耗,重点优化阻塞时间、页面掉帧问题。
继续对这个组件成果进行优化,增加了endWithNum属性,控制一轮循环完成之后隔开的单位数量,并且修复了一些bug,包括页面不可视后raf停止,css继续运行造成的不同调问题,进行反复测试,确保稳定性,并新增了一些配置属性,做成了轮子react-rollfree。
react-rollfree适用于各种滚动组件场景,包括文本、图片、动画等,支持大数据量动态更新,基本能够覆盖各种滚动动画场景,后面会增加弹幕模式,扩展更多应用场景。
下载方式:npm install react-rollfree
源码地址:https://github.com/Markuuuu/react-rollfree
具体配置:
`* @animationDirection boolean --滚动方向,默认从下到上,从左到右`
`* @animationTime number --过场时间 单位:S`
`* [@children](https://my.oschina.net/children117cl) [<jsx>] --滚动组件,支持隐式传入`
`* @childrenUpdateModel string --数据更新后更新列表,'now'立即更新,'later'跑完更新`
`* @contextHeight number --单条轮播组件height`
`* @contextWidth number --单条轮播组件width`
`* @endWithNum number --结尾空置滚动单位数量`
`* @height number --滚动外框height`
`* @horizontal boolean --横纵向轮播`,默认横向
`* @pauseWithHover boolean --默认开启,鼠标hover组件滚动停止`
`* @showBorder boolean --是否显示辅助设计边界`
`* @width number --滚动外框width`
使用:
`<RollFree`
`animationTime={20}`
`contextWidth={2036}`
`contextHeight={2036}`
`horizontal={false}`
`width={2048}`
`height={1583}`
`>`
`{滚动dom[]}`
`</RollFree>`
react-rollfree默认效果
1000个滚动模块效果图(实现黑客帝国特效)
更多智能运维方面资讯,请关注 云智慧AIOps社区
云智慧产品开源地址:
Github: https://github.com/CloudWise-OpenSource
Gitee: https://gitee.com/CloudWise
原网址: 访问
创建于: 2021-12-09 10:26:33
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论