Ant Design Ellipsis 中的判断逻辑 isEleEllipsis 方法非常消耗性能

问题暴露

周三上午 10:12 在国内反馈群里收到性能问题的反馈:
反馈截图

本来以为是机器问题,后来发现机器配置是一致的(即使是新的笔记本设备也存在相同问题):
合肥/武汉 2个职场都存在这个问题

同时通过跟业务沟通我们更具体的定位到是这几个页面的问题:

  • 个人/小组工作量

  • 工单列表

  • Inbound 进线列表

与此同时,使用了 Clarity 的 Copilot 工具查了一下这几个页面最近的性能,我们可以看到 LCP 上确实存在严重问题,这个体验确实很糟糕:

于是,我们开始着手分析:

首先,尝试用 AI 工具 CodeX 分析和解决了下这 2 个页面的问题,并且在晚上上了一个版本。但事实证明,AI 目前还无法解决前端性能问题 。尽管 AI 版本没能成功解决问题,但是 AI 给出了一些言之有物的方向:
**结论** 卡顿主因不是接口慢,而是点击 `查询` 后前端主线程被宽表渲染/重排卡住了。 **证据** `个人工作量(new) /telecol/report/workload/person` - 主列表接口:`378ms` - 刷新时间接口:`164ms` - 表格真正出现数据:约 `5.4s` - 长任务:`3325ms`、`1644ms` - 额外还夹了站内信轮询、根路径 `fetch`、日志上报 `小组工作量(new) /telecol/report/workload/team` - 主列表接口:`264ms` - 刷新时间接口:`125ms` - 表格真正出现数据:约 `4.6s` - 长任务:`3036ms`、`1259ms` - 还夹了根路径 `fetch` 和 Clarity 上报 这组数据说明: - 网络请求本身很快,核心接口都在 `400ms` 内 - 但用户要等 `4.6s-5.4s` 才看到有效数据 - 中间被两段超长主线程任务卡住,量级是 `3s + 1s`,这就是体感卡顿来源 **怎么理解** 你前面那份线上指标里 `LCP/INP` 高,是合理的。因为真实链路是: 1. 刷新页面 2. 点 `查询` 3. 接口很快返回 4. 前端开始渲染超宽动态表 5. 主线程被长任务占住,页面长时间不响应 所以这不是"菜单切换壳层慢",也不是"单纯接口慢",而是"查询触发后的页面渲染太重"。 **顺带确认的一点** 线上当前版本在点 `查询` 时,仍然会额外请求一次 `refresh-time`。这说明我本地刚做的"把 `latestRefreshTime` 从首屏/查询链路后移"的优化,线上还没生效。 **下一步建议** 优先级直接这样排: 1. 先上本地已做的减法 - `refresh-time` 延后 - 组织树选择器按需请求 - 宽表不再用 `x: 'max-content'` 2. 继续压表格渲染成本 - 默认少渲染列 - 给动态列稳定宽度 - 把低频列折叠 - 评估表体虚拟滚动 3. 下一轮要抓 flame chart - 现在已经证明"慢在主线程" - 下一步不是再猜,而是定位这 `3s` 长任务到底耗在 `ProTable`、列计算、还是 DOM layout

于是第二天我们不得不手动 DEBUG 解决问题,并开启"人工"智能分析。

根因定位 Why?

具体步骤

  • 无论是 MacOS 还是 Windows OS 这个卡顿感都是明显可见的,说明跟操作系统 OS 无关

  • 然后让坐席用 Chrome 浏览器登录和我们测试用 Chrome 浏览器登录,发现卡顿感也是明显可见的,说明跟浏览器及其版本无关

  • 然后接口的返回速度也很正常都是 100~300ms 内返回了数据,说明这跟后端的接口速度无关

  • 最后这些页面的共性是都是宽表,横向有许多列,大概有 40 列,虽然数据分页后只有 20 条,说明这跟页面表格渲染有关,最后结果也验证了这一点

Chrome Devtools Performance Panel

在 的反馈中有一个关键线索是 "一旦页面开始渲染,点击 tab 切换无响应,造成卡顿感强烈":
实测:卡顿感极其强烈

于是,我们开始通过 Chrome Devtools 的 Perfromance Panel 面板手动抓取上述操作路径依赖中 JS 的执行帧火焰图 (Flame Chart),分析引发卡顿感的根源:
火焰图

从图中左下角可以发现其中主要卡顿点在 JS 执行线程跟浏览器的渲染线程上,我们再细化一下,只选中红色的 LongTask 看看究竟是啥导致了"卡顿"问题的发生:
3x LongTask

Rendering: 3760ms

Scripting: 1410ms
1x LongTask

Rendering: 1211 ms

Scripting: 113ms
Why? 原来是 "Recalculate Style" performance issues

Why?

是什么导致了这个问题?Recalculate Style

在它之上还有概念叫 Reflow:Reflow 属于"重新渲染"过程中的一个关键步骤,即重排布局 。当页面布局发生变化时,浏览器会先进行 Reflow (重新算位置),然后紧接着进行 Repaint (重新画到屏幕上)。

所以根据上述分析我们可以得出如下结论:浏览器的渲染耗时极高,而且它一边计算(执行 JS)一遍重排(Reflow > Recalculate > Repaint)

Which?

那究竟是什么导致了它一直 Reflow 呢?点进去这个火焰区块发现:

找到了是 isEleEllipsis 这个方法。那这个方法是干嘛的?为什么?继续点进去:
罪魁祸首

这个方法的执行居然花了近 100ms !而且这个代码看起来是 ant-design 的代码!要去提 ISSUE 了,见 https://github.com/ant-design/ant-design/issues/57563

如果界面上有 20 rows * 40 columns = 800 cells,那么久导致了 800 * 100ms = 8s 左右的卡顿和延迟,这体验确实极差。

设计解决方案 How?

临时解决方案

禁用 ellipsis: true 配置,全部删除或注释掉。

长期解决方案

尝试升级 ant-design 的版本,看新版本是否有解决这个问题。若有,则无事发生。若无,则维持临时解决方案,且非必要不再使用 ellipsis 属性

测试解决方案

使用上述解决方案后,经测试,性能变好,切换很快,符合预期。

回顾上述提到的 AI 给出的提示中的第三步:
3. 下一轮要抓 flame chart - 现在已经证明"慢在主线程" - 下一步不是再猜,而是定位这 `3s` 长任务到底耗在 `ProTable`、列计算、还是 DOM layout

问题出现在 列计算 + DOM layout

AI 时代,前端已经离失业不远了,都要转全栈偏前了 🤣。朋友们,为什么前端最先被替代?因为这是互联网时代最 open 的职业,没有之一。

用户反馈

将解决方案上线后,用户反馈也不卡了。

致谢

这个问题的妥善解决,离不开业务同学的反馈,领导的支持,还有同事的建议,测试的帮助。

相关推荐
酉鬼女又兒3 小时前
零基础快速入门前端ES6 核心特性详解:Set 数据结构与对象增强写法(可用于备赛蓝桥杯Web应用开发)
开发语言·前端·javascript·职场和发展·蓝桥杯·es6
阿珊和她的猫4 小时前
以用户为中心的前端性能指标解析
前端·javascript·css
叫我一声阿雷吧4 小时前
JS 入门通关手册(36):变量提升、暂时性死区与块级作用域
javascript·变量提升·暂时性死区·tdz·块级作用域· 前端面试
成都渲染101云渲染66664 小时前
跳出“硬件堆砌”陷阱|渲染101如何用技术重构云渲染的专业价值?
java·前端·javascript
SuperEugene4 小时前
Vue3 性能优化规范:日常必做优化(不玄学、可落地)|可维护性与兜底规范篇
开发语言·前端·javascript·vue.js·性能优化·前端框架
cypking5 小时前
二次封装ElementUI日期范围组件:打造带限制规则的Vue2 v-model响应式通用组件
前端·javascript·elementui
酉鬼女又兒5 小时前
零基础快速入门前端蓝桥杯Web考点深度解析:var、let、const与事件绑定实战(可用于备赛蓝桥杯Web应用开发)
开发语言·前端·javascript·职场和发展·蓝桥杯·es6·html5
happymaker06265 小时前
vue指令扩展以及监视器的使用
前端·javascript·vue.js
还是大剑师兰特5 小时前
EventBus核心方法用法
javascript·vue.js·大剑师