因为几个项目下来,我们发现前端的应用过于卡顿,甚至还不如上一版本 JQuery Easy UI 做出来。在项目经理的会议主持下,我和前端同学在会议上就React 是否符合我们需求的问题充分交换了意见,最终会议决定放弃 React,转向 Vue。
具体原因如下: 我们应用需要每个 tab 内容显示 1000 个列表条目,每个条目显示一个文本状态和背景颜色,1000 个条目里随机每秒有一个改变文本状态。
之前有一版是用 JQ 的。JQuery 做出来的就初次只卡顿 2s,而 React 作出来每点击一次 button 却要卡的四五秒。经过前端深入对 React 研究之后,他认为这是 React 的缺陷-->无法很好地解决高频率渲染大量组件内容。
为什么无法解决呢?我不是前端,我这里拷贝一下前端的原话:
因为 React 在进行状态更新的时候,会进行判断每一个 listitem 的状态是否有改变。当然一两个组件这样就没啥问题,但是要是有 1000-1500 个小方块同时显示,而且每秒还要更新客户订单量,这样统计就会很卡了。你可以自己试一下,for 循环 1 到 1000,只输出一个文本,都会卡成狗屎,更别说 React 判断过程中不只判断一个 prop 属性呢,他要判断 N 个属性,你要在 1000*N 的判断之后,才进行渲染呢!我一开始就说用 Vue 会比较好,React 在 ERP 有嗯用完全搞不定那么多高频率的渲染需求的。“
而且我也觉得用 React 的大部分都是为了 CRUD 吧?如果像一些实时的高频率的刷新,抱歉,我和前端没看到哪一个大厂用 React 来做,感觉真的卡成狗屎。既然前端觉得 Vue 很 ok,那就让他去试试。
所以,各位认同 React 不适合大数据高频率的论点吗?
![]() | 1 geshansuiyue 2018-12-22 14:42:42 +08:00 ![]() 准备看戏 |
![]() | 2 momocraft 2018-12-22 14:44:18 +08:00 ![]() 能不能把你们实验时的代码发出来看看 |
![]() | 3 niubee1 2018-12-22 14:46:11 +08:00 编译成 webassembly 试试 |
![]() | 4 reus 2018-12-22 14:48:25 +08:00 ![]() 你这前端肯定不懂二分法 水平不行怪框架? |
![]() | 5 hlwjia PRO 能不能把你们实验时的代码发出来看看 + 1 |
![]() | 6 reus 2018-12-22 14:50:42 +08:00 ![]() 当然,就这个需求,vue 确实对菜鸡友好,但请不要说是 react 的缺陷,是你们前端不懂状态管理而已。 |
![]() | 7 duan602728596 2018-12-22 14:53:05 +08:00 via iPhone ![]() 果然是水平不行怪框架 |
8 VDimos 2018-12-22 14:57:49 +08:00 via Android vue 不也是 vdom 遍历查找更新? react 的快速算法是目前最优的算法,这个框架真不背锅 |
![]() | 9 shangjiyu 2018-12-22 14:58:00 +08:00 flutter ? |
10 VDimos 2018-12-22 14:59:27 +08:00 via Android 而且大量列表这个还和 css 与 html 有关,有些设置来会很卡 |
![]() | 11 zuoyuTU 2018-12-22 15:00:29 +08:00 同意 demo 开源下,大家免费帮你找找坑 |
![]() | 12 codermagefox 2018-12-22 15:01:06 +08:00 "因为 React 在进行状态更新的时候,会进行判断每一个 listitem 的状态是否有改变。" 蛤????我学的是假 React? Vue 不会这样难道不是因为为了性能手动切断了 Object.defineProperty 的状态更新吗? React 的 SetState 做不到??您能把代码发一下吗??? 看我的一头问号 |
![]() | 13 codermagefox 2018-12-22 15:01:33 +08:00 @codermagefox #12 看我的->看的我 |
![]() | 14 reus 2018-12-22 15:03:11 +08:00 @VDimos 不是,vue 不需要遍历,vue 组件读写属性时会标记为需要更新。react 这个需要自己实现 shouldUpdateComponent 或者用 PureComponent,比 vue 灵活但对菜鸡不友好。 |
![]() | 15 hlwjia PRO ![]() In conclusion, 前端的门槛太低了 |
16 Cbdy 2018-12-22 15:03:47 +08:00 via Android ![]() 技术不行,框架背锅,稳 |
![]() | 17 leega0 2018-12-22 15:04:59 +08:00 ![]() 只想说你们的选择是正确的,react 不是不行,而是不适合你们。 |
18 nohup OP 这里我的前端回复一下: 应用用的是 React+Redux+React-Router,demo 就不放了,公司保密 @codermagefox Vue 有 getter/setter 加持,压根就不需要判断哪些属性变了哪些属性没变。setState 一样要判断属性是否更改,这是很低效反人类的,你需要判断了 1000*N 个属性之后才进行渲染 @reus 讨论不是更新某个条目去找到这个条目,而是 React 在高频度渲染情况远不如 Vue。React 需要一个个去判断,低效的很呢,作为开发者能参与的性能优化最多加个 PureComponentn,其实没什么软用的,就算你自己写 ShouldComponentUpdate 还是卡成狗屎 |
![]() | 19 codermagefox 2018-12-22 15:09:00 +08:00 @reus #14 我甚至怀疑都不到这个优化层级,卡 4-5 秒啊! 我甚至怀疑原因是他们没有加 Key,不然怎么可能卡 4-5 秒.哪怕有 1/3 走 Update,也就 1000 个条目,会用得着这么久? 我当初用某开源库就碰到过这种情况,用数据去检索中文 Key 无法检索导致点一下就卡 5 秒.后来还是绕弯路解决的. 看到这个帖子真是有点生气 |
20 nohup OP |
![]() | 21 codermagefox 2018-12-22 15:14:36 +08:00 @nohup #20 那么请问一下,不能放源码能不能放源码运行时的 perfermance?这个总不是机密吧?我想看看,如果真是个框架缺陷,我也好好学习一下 |
22 nohup OP @codermagefox 什么是运行时 performance ? js 没有这个东西的吧 |
![]() | 23 codermagefox 2018-12-22 15:17:46 +08:00 @nohup #22 ChromeDevTool-> Performance |
24 nohup OP @codermagefox 中国人要用中文。好的,我稍后 append 一下 |
![]() | 25 hlwjia PRO ![]() “中国人要用中文。好的,我稍后 append 一下” 莫名的喜感 |
![]() | 26 codermagefox 2018-12-22 15:25:01 +08:00 ![]() @nohup #22 而且你们前端总结出来的那个结论,我也觉得是欠妥的.1000*3 的 insert 数量是不可能卡 5 秒的. 卡 5 秒只有可能是 O(n)的复杂度,也就是所有 DOM 节点全部走 insert 完全没有走 domdiff 效果和你们前端做循环的效果是一样的 循环输出 DOM 的实际复杂度不是 3000,而是对比 10 亿次 |
![]() | 28 yadgen 2018-12-22 15:30:22 +08:00 ![]() 前端能卡 4-5 秒,你们前端可以换人了。 项目经理没有主见,估计也是听听你们的意见,感觉似乎是那么一回事儿,就定夺,也可以更换了。 |
29 Kyle18Tang 2018-12-22 15:30:37 +08:00 via Android @hlwjia 哈哈哈,我也笑了。而且 chrome 里本来也是英文。。。 |
![]() | 30 yadgen 2018-12-22 15:32:13 +08:00 追加一点,可以写个 Demo,从没见过有人贴项目代码。 |
31 ugu 2018-12-22 15:32:48 +08:00 人不行哦,不赖框架 |
![]() | 33 chinvo 2018-12-22 15:33:13 +08:00 via iPhone 典型技术不行怪框架 坐等下一篇《经过两个月试用我们放弃了 vue 》 不过说实在的,vue 根本没有生态可言,做项目基本没法用 |
![]() | 34 zjsxwc 2018-12-22 15:33:52 +08:00 |
35 bb22 2018-12-22 15:34:16 +08:00 请到 codesandbox 跑个 demo 让我们看看,不然只能怪你们的前端不行了 |
![]() | 36 moeone 2018-12-22 15:34:24 +08:00 吃瓜 |
![]() | 37 momocraft 2018-12-22 15:37:57 +08:00 其实我觉得这个数据量 jquery "只" 卡 2s 就有点喜感. 同为著名框架, 性能差几十倍是不小的新闻了, 发个 demo 也许能上 hn 头条, 你们可以试一下 |
40 shyangs 2018-12-22 15:42:17 +08:00 这大新闻为什么不是老外先发现的 老外不是用 React 更多吗 ::doge:: |
![]() | 41 passerbytiny 2018-12-22 15:43:47 +08:00 ![]() 大概率:一段时间后,经过技术选型研究,我们放弃了 Vue,转向原生 HTML+Javascript ;再一段时间后,经过技术选型研究,我们放弃了网页端,转向客户端。 显示 1000 行还要能随机刷新,这基本上属于特殊需求了,通用轮子一般都不能完美解决,要自造轮子。 你不是前端,直接下了结论,后面又只当前端的传话筒,所以我很想问你一句经典的话:关你屁事? |
![]() | 44 lsido 2018-12-22 15:48:02 +08:00 via iPhone 前端怎么还没回复,大伙儿等着看戏呢 |
![]() | 45 reus 2018-12-22 15:51:06 +08:00 @nohup 问你的前端,去图书馆找书,是不是从头一本本找。1000 个元素,递归拆分成树,有元素更新时,shouldComponentUpdate 只需要执行数次,哪来的一个个判断。所以我一开始就说他不懂二分查找。 |
![]() | 47 creanme 2018-12-22 15:54:01 +08:00 via Android 别盲目换框架啊,问题解决不了发群里,或者社区,先咨询一下能否解决再说啊。 |
![]() | 48 janxin 2018-12-22 15:56:52 +08:00 我觉得是 JS 不能多线程导致的渲染效率过低 |
49 nohup OP @passerbytiny 的确不关我事,但我要把抛弃 React 的理由拿出来 6 一 6,看看大家的意见 |
50 frozen2013 2018-12-22 15:57:55 +08:00 via Android ![]() 我看过一篇介绍 react-fiber 的,里面提到过 fiber 架构出来之前的性能问题,跟你们公司遇到的类似,但是人家做实验 demo 的 dom 个数是 100000 个,10 万个啊!!! 你们 1000 个就遇到明显卡顿,是不是先花点时间看看如何优化?!突然换框架重写的成本我觉得也是很大的。 https://www.infoq.cn/article/what-the-new-engine-of-react |
51 xiaojie668329 2018-12-22 15:59:00 +08:00 这肯定不是 react 的锅。。代码写不好用 vue 同样也会卡。 |
52 nohup OP 回复 by 前端: @reus 现在元素需要更新,但是你就是不知道更新的元素有哪些,所以才一个个用 shouldComponentUpdate 去判断的嘛,这跟元素查找有什么关联吗,难道是我理解错了? |
![]() | 53 j717273419 2018-12-22 15:59:30 +08:00 ![]() 你们别这样。。。回头前端要找工作了。。。 |
![]() | 54 codermagefox 2018-12-22 16:04:42 +08:00 @nohup #52 不好意思,是我偏激了.你们前端其实这么想是正常的,毕竟我是闲着无聊才经常看源码. 如果你们真是这种特殊需求,你可以让他去看看 Fiber 架构.这玩意我不懂,但是面试的时候已经被问到了,似乎就是用来解决你们这种特殊需求的. |
![]() | 55 reus 218-12-22 16:08:30 +08:00 ![]() @nohup 用二叉树式组件去表示列表,更新一个元素,那就只有那个元素路径上的 shouldComponentUpdate 会执行。说到这个份上都还不理解,那我就没办法了。 |
![]() | 56 passerbytiny 2018-12-22 16:08:37 +08:00 @nohup #44 先下结论再看意见,拿出来的理由是自己不懂的,你这是“看看大家意见”的态度? 说下你的职位类型吧,你要是项目经理或者管开发进度的,我理解你,只忽略该主题,要不是,就上 block 了。 |
![]() | 57 scofieldpeng 2018-12-22 16:12:49 +08:00 一般来说都是技术不行,然后又不愿意承认,只好怪框架。坐等楼主上相关不涉及机密的 demo 代码来得出一个严谨的结论 |
![]() | 58 hlwjia PRO ![]() 找了个古老的项目,改了一下录了个视频 这个是每秒从后端获取 1200 个颜色变化 |
![]() | 59 beyoung 2018-12-22 16:15:12 +08:00 ![]() 你们真的经过了技术研究? 而不是主观感受 |
60 lihongjie0209 2018-12-22 16:15:33 +08:00 @janxin js 和渲染有什么关系, 渲染是浏览器的工作 |
61 nohup OP |
![]() | 62 a href="/member/reus" class="dark">reus 2018-12-22 16:22:28 +08:00 ![]() @nohup 例如更新第 700 个,在各个结点组件的 shouldComponentUpdate 里判断,前 500 个不需要重渲染,后 500 个需要。后 500 个里面,前 250 个需要重渲染,后 250 个不需要。250 个需要重渲染的里面,前 125 个不需要,后 125 个需要。递归下去,到第 700 个,需要调用的 shouldComponentUpdate 次数是 log(2, 1000) * 2,不需要一个个比较。 |
![]() | 64 so898 2018-12-22 16:24:49 +08:00 明天会不会因为 SEO 转回去…… |
![]() | 65 reus 2018-12-22 16:25:16 +08:00 @nohup 所以说菜鸡就是菜鸡,懂的人,说到“二分”,就应该领悟了,知道要用二叉树去表示组件,从而高效地判断需要更新哪里。菜鸡呢,说再多也理解不了,反而怪说的人没说清楚。 |
66 251243021 2018-12-22 16:31:28 +08:00 纯属写法问题.不怪框架,顶多 vue 更友好而已 |
67 kimown 2018-12-22 16:33:42 +08:00 via Android 项目性能考虑,需要换语言,换框架,地球上肯定有案例的,但人能力不行,水平垃圾还做开发,怪语言,怪框架,也是有的,lz 你是上一类人,还是下一类人呢? |
![]() | 68 learnshare 2018-12-22 16:37:12 +08:00 这个性能瓶颈并不能怪哪个框架 是需要自己优化数据量、数据结构或者呈现方式,甚至需要选择一个脑子更好使的产品经理 只渲染可见部分,就是个不错的优化方式。随手搜到的文章: https://zhuanlan.zhihu.com/p/41237949 https://zhuanlan.zhihu.com/p/26022258 |
69 nohup   OP 回复 by 前端 @reus “那就只有那个元素路径上的 shouldComponentUpdate 会执行”这段话产生了很多歧义,是 SCU 返回 true 值,还是 SCU 压根就不调用,还是你在外面类似 redux 套了一个高阶函数? 动不动说别人菜鸡,建议你看看自己说过的话逻辑通不通,说那么模模糊糊的话谁可以理解的了?你这种说话调调就像 : React 可以加个二分查找来优化,用树来表示列表(是组件层次的树形还是 model 的属性?),只有需要更新的元素才会执行 shouldComponentUpdate(那到底执不执行?你干脆说会进行渲染不行?) 说的好像只有你会数据结构一样,你当然没有义务完全一步步说的清楚,但是说话歧义这么多,是不是该抽空检查了一下自己? |
![]() | 70 hualongbei 2018-12-22 16:38:39 +08:00 Talk is cheap. Show me the code. |
![]() | 71 duzhihao 2018-12-22 16:39:32 +08:00 ![]() 难道我们开发产品是为了证明 vue 和 react 谁牛逼。别开玩笑了。 |
72 dremy 2018-12-22 16:49:20 +08:00 via iPhone 可回收(复用)列表了解一下,1000 多个元素一般不会是一屏全部展示出来的吧,那只 diff 和渲染可以看到的列表元素就好了,几十一百个元素的话肯定不会有问题 |
![]() | 74 sunnyadamm 2018-12-22 16:55:13 +08:00 via Android 围观一下,不做评论 |
![]() | 75 creanme 2018-12-22 16:55:16 +08:00 想看 demo。。。简单演示下就行。 |
![]() | 76 wu67 2018-12-22 16:57:57 +08:00 ![]() @dremy 还真有那种一页列出一千多两千条的垃圾需求, 产品就是这么要求的...明明告诉过他这要把整个表都列出来了... 另外上面某人说话戾气真大, 有技术经验确实是可以骄傲的资本, 但不意味这你可以随意鄙视贬低别人, 没几个人是生而知之的, 说的好像别人不能见微知著就是垃圾一样 |
77 Lax 2018-12-22 17:03:29 +08:00 ![]() 一个项目用 vue,有一个列表,10000 条数据的列表,首次打开和更新会都感觉卡顿(排序+渲染接近 1s ),减少到 5000 条数据时感觉卡顿不明显。 用浏览器 profiling 工具看到大部分时间在遍历 dom 的操作。 这类问题解决方法是只把需要展示出来的添加到页面。我用了这个库: https://github.com/Akryum/vue-virtual-scroller 换成 vue 之后你们 1000 条数据时的问题,可能会延缓到 5000 条以后才遇到,也算解决了问题。但是我并不认为 react 会“不行”,可能不适合你们使用。 |
![]() | 78 murmur 2018-12-22 17:06:15 +08:00 @Lax vdom 的框架 batch insert 都要趴窝 还得 jquery+template 一次生成字符串一次插入搞定 |
![]() | 80 will0404 2018-12-22 17:13:00 +08:00 ![]() 你的 listitem 组件可能很复杂,也可能很简单,1000 个可以说多,也可以说非常少。 无论如何,一秒钟改变其中一个的状态,基本上不会造成性能问题,别说 4s,1s 都不可接受。 我刚刚试了一下每一秒改变 10000 个组件的状态,React 每次重新渲染都少于 400ms。当然我实验的组件很简单,它没有子组件。 我给你提供个思路,ReactDevTool 可以看到每次操作哪些组件被重新渲染了,显然,你有太多组件重新渲染了,实际上每次只需要重新渲染一个。一般情况下,用 shouldComponentUpdate 就可以解决。但我不知道你的情况有多复杂,就不多做评论了。 不过我看了下上面的回复,不觉得这是 React 的问题。 |
81 lufangfan 2018-12-22 17:18:44 +08:00 我是来学习的,希望会有大神能在这个话题下讲解。 |
![]() | 82 bookit 2018-12-22 17:19:48 +08:00 不判断了,直接 1000 个全部更新要多长时间? 我觉得也不需要 5 秒。。。 |
![]() | 83 ByZHkc3 2018-12-22 17:20:53 +08:00 via Android 大厂不用 react ???????????????? |
![]() | 84 xuhaoyangx 2018-12-22 17:23:46 +08:00 ![]() ![]() |
![]() | 85 wjl4107336 2018-12-22 17:35:00 +08:00 via Android 引战 |
![]() | 86 Weny 2018-12-22 17:35:48 +08:00 水平太差,简单点一个 shouldComponentUpdate 解决 ,稍微稳妥一些上 immutable.js immer.js 。这个水平,怕是拉个高中生都写得比你们强吧。15 年的时候 react states 就有 immutable.js 做为解决方案了。几个国内大厂都有实践过,特别是在移动端。 |
![]() | 88 React 2018-12-22 17:56:30 +08:00 ![]() https://github.com/jonmiles/react-performance-tests 这个是 15 年的测试,渲染 10000 个小方块,哪有你说的那么不堪 |
![]() | 89 Arrowing 2018-12-22 18:01:31 +08:00 via Android ![]() 看到描述就知道楼主要挨喷了,果不其然,保重啊楼主。 |
90 Justin13 2018-12-22 18:11:41 +08:00 via Android 我大胆的猜测下,你们的每次更新都会改变所有节点的数据的引用。或者改变了某些下传的衍生数据的引用。 这都会导致每次都要更新整个组件树。 真正耗时间的一定是你们的 code 而不是 react 的 code。 |
![]() | 91 shuhao 2018-12-22 18:17:31 +08:00 via Android 围观 |
92 Justin13 2018-12-22 18:19:59 +08:00 via Android React 走的是函数式的路子,如果说写 React 的过程中需要通过深比较来控制刷新,只能说明你是在逆着 React 的范式在写,根本没有完全理解其思想。 基于同样的理由,我也反对 reselect 这个库。它虽然解决的痛点,但是光治标不治本。用了反而鼓励你继续乱搞。 |
![]() | 93 jason94 2018-12-22 18:22:52 +08:00 吃瓜群众,前来围观 |
![]() | 94 br00k 2018-12-22 19:42:55 +08:00 via iPhone 这样很难帮到你。整个 demo 出来找问题就简单了。 |
![]() | 95 rrfeng 2018-12-22 20:31:10 +08:00 via Android 知乎上有个争论性问题上,有个回答说专门做高度复杂的 ERP 系统的,react 用的很好。 1 确实是水平不行怪框架 2 水平不行也不是什么错,选择合适的才对 3 angular 一样也可以选择啊 |
![]() | 96 Biwood 2018-12-22 20:38:52 +08:00 楼主如果把问题的核心代码写个 demo 发到这儿来一起讨论一下就好了,标题和正文确实非常容易不必要的引起口水之争,看不到具体的代码实现,怎么吵都没有意义 |
97 leo8 2018-12-22 20:41:54 +08:00 via iPhone 想看下到底是什么原因造成的 |
98 chen26 2018-12-22 20:53:35 +08:00 围观 |
![]() | 99 creanme 2018-12-22 21:20:57 +08:00 |
![]() | 100 abcbuzhiming 2018-12-22 21:31:46 +08:00 前端三大 MVVM 框架论原理都是半斤八两的,我不认为他们的性能会有数量级的差别,所以我认为你们的前端压根就没抓住问题根本,所以你们用 Vue 多半还是会撞上这个南墙 |