React 开发者,如何克服 render 性能强迫症

2023-05-17 01:08:27 +08:00
 iPhone15

每天都会被 React 的渲染机制逼死:

这个世界上这么多 React 应用,
每时每刻,会有多少函数和对象,在一次次的 render 过程被创建又被立马丢弃。

虽然大多数场景下,这种渲染机制并不会在视觉上或性能上造成太多负担。

4533 次点击
所在节点    程序员
41 条回复
ivslyyy
2023-05-17 12:35:57 +08:00
减少重复渲染,用 useCallback
ref
在 react 里直接操作 DOM ,不用 state 那一套
Track13
2023-05-17 12:52:26 +08:00
没有感到卡顿就不管。😂
q307990588
2023-05-17 16:12:33 +08:00
@ivslyyy 还真是个啥都不懂的前端啊
ivslyyy
2023-05-17 16:20:43 +08:00
@q307990588 被发现了,我真的是一个网页代码初学者。
jswh
2023-05-17 16:36:12 +08:00
不用 react
转行后端
转行运维
转行炒饭
🤣
Leonard
2023-05-17 16:49:52 +08:00
别想太多,遇到性能瓶颈再考虑优化
Imindzzz
2023-05-17 16:49:55 +08:00
想想游戏都是一秒几十次重绘,会不会好受点?

而且没有被立马抛弃呀,不是都有缓存?

提 vue solid 的,可能懂点前端,但是不多。
声明式 UI 都得这样。
n18255447846
2023-05-17 18:10:58 +08:00
这种都要担忧的话,怎么不想想 class 语法开销呢,不如 Function.prototype ;又比如加减乘除,转化为二进制的开销,不如直接位操作符。

React 里只要合理地设置 SCU 和 areEqual ,就能杜绝大部分的重复渲染。
stroh
2023-05-17 18:35:56 +08:00
我以前一个同事去一个神奇的公司,他们公司要求用 react ,面试也是 react ,但他只会 jquery 和 js ,前端就他一个人,然后他就偷偷在 webpack 里加了个 copy 文件到 dist 的插件,项目还是用 jquery 写,然后每次打包的时候就自动到 dist 里,就这样项目做了 2 年,觉得没意思就跳槽了(不知道去哪个公司霍霍了),等新招的前端接手的时候,整个 react 项目里就是空壳,启动全部走 jquery 的 index ,他每次把项目考进去然后在 jenkins 打包构建,实际都是自己写的 jquery ,老板走之前还夸他项目性能多好多好,还加薪挽留...这件事后我就不对什么 react vue 感冒了,只要完成老板任务就可以
stroh
2023-05-17 18:38:06 +08:00
新招的前端还纳闷,你们公司不是用 react 吗?问了所有研发都说是 react ,还说 react 效率多好多块...说要继承之前前端的遗志把项目按照现有流程好好做下去,那个新来的前端一脸懵逼
beginor
2023-05-17 18:45:12 +08:00
@stroh 这个有点儿逗了,不会是段子吧。

至少 react 的开发效率比 jq 高太多, 特别是复杂交互的时候。

当然如果能用 jq 搞定复杂交互的话, 其它框架也是轻松掌握的。
fernandoxu
2023-05-17 21:41:04 +08:00
witcat
2023-05-17 21:42:33 +08:00
好多年前领导说过一句我觉得特别经典的话:没遇到瓶颈就不优化。
darkengine
2023-05-17 21:51:47 +08:00
记住六个字:又不是不能用
iPhone15
2023-05-17 23:56:55 +08:00
@Imindzzz 每次一定会有立马被抛弃的东西,各种 memo 的逻辑,就是判定是否有缓存,有则返回缓存+丢弃新传入的函数。

比如 useCallback(() => setCount(pre => pre + 1), []),虽然他返回的永远是首次缓存的函数,但新的函数还是会被创建然后丢弃。

第二次 render 的过程,也就是:
1 、创建函数:() => setCount(pre => pre + 1)
2 、传给 useMemo
3 、发现有缓存函数
4 、返回缓存函数
5 、丢弃刚刚创建的函数

另外 useMemo 是可以减少函数的“执行”,返回上次的”执行结果“,但是也无可避免的会创建新的函数,但被立马丢弃。

当然这都无伤大雅,只是日常总是觉得心里有疙瘩~😂
iPhone15
2023-05-18 00:03:02 +08:00
@iPhone15 修正笔误:

1 、创建函数:() => setCount(pre => pre + 1)
2 、传给 useMemo (更正为:传给 useCallback )
Imindzzz
2023-05-18 01:21:51 +08:00
@iPhone15 我明白你纠结得点了,就是匿名函数被丢掉了。
我虽然没看过 v8 源码,但是我觉得:匿名函数还没有被使用就不会被提前创建。
这个和立即执行函数还是不同的
fernandoxu
2023-05-18 06:42:34 +08:00
@iPhone15 即执行 useCallback 和 useMemo 也是成本,和简单的 re-render 都是执行函数,不一定有多少性能差别,re-render 又不一定会更新 dom 。所以无伤大雅的 re-render 没必要处理一下子,fix the slow render before you fix the re-render
stroh
2023-05-18 09:11:44 +08:00
@beginor 听前同事说的,不像假的,而且这种情况在业内不少见,不过很早前 jquery 我也用了 3 年,那时候没 react 也用的好好的
uaoin
2023-05-18 09:21:15 +08:00
我总是搞不清楚什么时候该使用 React.memo 包裹组件,总觉得每个组件都要包裹,然后又费劲做很多 memoized 的操作。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/940559

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX