前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >不为别的,聊聊react源码的设计理念

不为别的,聊聊react源码的设计理念

作者头像
用户3986961
发布2022-03-15 15:04:19
6180
发布2022-03-15 15:04:19
举报
文章被收录于专栏:靠才华整容

前言

以前在看一些开源项目的源码时,比如cornerstone(一种为医学影像服务的web框架),折服于其优秀的设计模式,灵活的工具扩展,丰富的数据结构,在当时阅读和学习这些源码时,都是出于公司业务考虑,只是看懂了个大概,而如今随着编码技能的提高和经验的积累,我发现,源码的背后其实是在阐述一种设计理念,自顶而下,设计思想抽象逐渐落地,落实到每一行代码,同时我也有了进一步的体会,软件架构在某种程度上是为了服务它的设计理念,它的技术平衡点。

闲来无事,看了一些react的源码,聊聊react的设计理念。

React理念

官网告诉我们:“我们认为,React 是用 JavaScript 构建快速响应的大型 Web 应用程序的首选方式。它在 Facebook 和 Instagram 上表现优秀。”

它的特征是“快速响应”,“大型web应用”,那么它是如何处理快速响应的呢,首先得知道快速响应的性能瓶颈在哪?有这两类场景会影响这“快速响应”:

  • 当遇到数量众多的标签渲染比如800个li渲染,或者canvas上几十万色彩图形的渲染,会造成卡顿
  • 网络请求,需要等待数据返回才能进一步快速响应

那么react是如何解决的呢?

快速响应的第一个难题解决--将同步的更新渲染转换为可中断的异步更新

我们知道主流浏览器的刷新频率是60Hz,也就是每16.6ms浏览器刷新一次,而卡顿则是在这期间发生的,比如js脚本执行时间过长,页面卡帧,甚至掉帧,则在浏览器刷新的时候就会有卡顿的现象了。

怎么办呢?找浏览器要时间,在它每一帧渲染的时候,留一些时间给js线程,React利用这时间抓紧更新组件,从源码中看到,预留的时间是5ms。

而上面英文的意思就是Scheduler控制器每隔5ms,观察有没有其他work要占用渲染主线程,没有的话我就继续更新组件渲染,有的话我就先暂停,也就是说将复杂的长任务,分拆到每一帧的渲染中,js执行时间在5ms左右,之后执行html的布局和css渲染。

而这个机制在哪呢,就在Scheduler时间切片(后续会说)。

代码语言:javascript
复制
// 通过使用ReactDOM.unstable_createRoot开启Concurrent Mode
// ReactDOM.render(<App/>, rootEl);  
ReactDOM.unstable_createRoot(rootEl).render(<App/>);

快速响应的第二个难题解决--前端解决不了

网络延迟前端是无法解决的,所以只能是最大限度的减少用户对网络延迟的体验感知。

而react给出的答案是什么呢,它通过用户体验团队发现:

  • 悬停和文本输入之类的交互需要在很短的时间内处理
  • 点击和页面转换可以等待稍长时间而不会感到迟缓
  • 在屏幕之间切换时显示过多的中间加载状态会使切换的速度变慢

所以,react尝试了在Concurrent 模式在内部使用不同的“优先级”,对应于人类感知研究中的交互类别。设计了Suspense功能以及配套的hook --- useDeferredValue

总结

react为实现“构建快速响应的大型web应用”目的在渲染和网络请求上做了很多努力,并在架构设计方面也是言行合一,比如fiber架构的设计,diff算法的优化等等,下篇我们再一起探讨React的新老架构,以及为此所做的努力。

靠才华整容,我是认真的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 靠才华整容 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档