chst365's blog chst365's blog
首页
  • Git
  • 网络
  • 操作系统
  • 浏览器
  • webpack
  • JavaScript
  • TypeScript
  • 性能
  • 工程化
  • React
  • 编程题
  • React技术揭秘
  • 算法
  • Node
  • 编码解码
  • NodeJS系列
  • Linux系列
  • JavaScript系列
  • HTTP系列
  • GIT系列
  • ES6系列
  • 设计模式系列
  • CSS系列
  • 小程序系列
  • 数据结构与算法系列
  • React系列
  • Vue3系列
  • Vue系列
  • TypeScript系列
  • Webpack系列
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

chst365

DIV工程师
首页
  • Git
  • 网络
  • 操作系统
  • 浏览器
  • webpack
  • JavaScript
  • TypeScript
  • 性能
  • 工程化
  • React
  • 编程题
  • React技术揭秘
  • 算法
  • Node
  • 编码解码
  • NodeJS系列
  • Linux系列
  • JavaScript系列
  • HTTP系列
  • GIT系列
  • ES6系列
  • 设计模式系列
  • CSS系列
  • 小程序系列
  • 数据结构与算法系列
  • React系列
  • Vue3系列
  • Vue系列
  • TypeScript系列
  • Webpack系列
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 浏览器

  • webpack

  • TypeScript

  • 性能

  • 工程化

  • React

  • JavaScript

  • 编程题

  • React技术揭秘

    • React理念
      • React 理念
        • CPU瓶颈
        • IO瓶颈
      • 总结
    • React新老架构
    • Fiber
    • 前置知识
    • render阶段
    • commit阶段
    • Diff算法
    • 状态更新
    • Hooks
  • 算法

  • 前端
  • React技术揭秘
chst365
2022-09-08
目录

React理念

# React 理念

从官网可看到React理念: React是用js构建快速响应的大型Web应用程序的首选方式。 那么,制约快速响应的因素是什么:

  • CPU瓶颈:当遇到大计算量的操作或设备性能不足使页面掉帧,导致卡顿
  • IO瓶颈:发送网络请求后,需等待数据返回才能进一步操作导致不能快速响应 React 是如何解决这两个瓶颈呢?

# CPU瓶颈

当项目变庞大、组件数量多,就容易遇到CPU瓶颈 如下Demo,向视图中渲染3000个li

function App() {
  const len = 3000;
  return (
    <ul>
      {Array(len).fill(0).map((_, i) => <li>{i}</li>)}
    </ul>
  );
}

const rootEl = document.querySelector("#root");
ReactDOM.render(<App/>, rootEl);  
1
2
3
4
5
6
7
8
9
10
11

主流浏览器刷新频率:60Hz(1000ms/60Hz),即16.6ms浏览器刷新一次。 我们知道,JS可操作DOM,GUI渲染线程JS线程是互斥的。所以JS脚本执行和浏览器布局、绘制不能同时执行。 在每16.6ms内,需完成如下工作:

JS脚本执行 --- 样式布局 --- 样式绘制
1

当JS执行时间 过长,超出16.6ms,这次刷新就无时间执行样式布局和绘制 在Demo中,由于组件数量多(3000个),JS脚本执行时间过长,页面掉帧,造成卡顿。 从打印的执行堆栈图看到,JS执行时间73.65ms,远多于一帧时间 如何解决这个问题? 答案是:在浏览器每一帧中,预留一些时间给JS线程,React用这些时间更新组件;若预留的时间不够,React将线程控制权交还给浏览器使其有时间渲染UI,react则等待下一帧时间来继续被中断的工作。 在源码 (opens new window)中,预留的时间是5ms。 这种将长任务分拆到每一帧中,称为时间切片(time slice) 如何开启时间? 开启Concurrent Mode可开启时间切片。

// 通过使用ReactDOM.unstable_createRoot开启Concurrent Mode
// ReactDOM.render(<App/>, rootEl);  
ReactDOM.unstable_createRoot(rootEl).render(<App/>);
1
2
3

此时可看到,长任务被分拆到每一帧不同的task中,JS脚本执行时间大体在5ms左右,这样浏览器就有时间执行样式布局和绘制,减少掉帧的可能性。

所以,解决CPU瓶颈的关键是时间切片,而时间切片的关键是将同步的更新变为可中断的异步更新

# IO瓶颈

网络延迟是前端开发者无法解决的。那么如何在网络延迟下,减少用户对网络延迟的感知呢? React的答案是将人机交互研究的结果整合到真实的UI中。 这里以IOS系统为例子 从设置页面,进入通用页面(不涉及网络请求) 作为对比,从设置进入Siri与搜索页面 两者的区别? 前者的交互是同步的,直接显示后续页面 后者的交互是异步的,需等待请求返回再显示后续页面。 但从用户感知看,两者区别微乎其微。 这里的做法是:在点击“Siri与搜索”后,先在当前页停留一小段时间,用来请求数据;若这段时间足够短,用户则无感知,若请求时间超过范围,再显示loading效果。 为此,React实现了Suspense (opens new window)功能及配套hook——useDeferredValue (opens new window) 在源码内部,为支持这些特性,需将同步的更新变为可中断的异步更新

# 总结

React为践行构建快速响应的大型Web应用程序,主要解决了CPU的瓶颈和IO瓶颈两大关键问题。主要是将同步更新变为可中断的异步更新

#前端#React技术揭秘
上次更新: 2022/09/16, 17:10:42
获取n以内所有的素数
React新老架构

← 获取n以内所有的素数 React新老架构→

最近更新
01
面试官
03-27
02
this&指针&作用域&闭包
03-27
03
前端
03-27
更多文章>
Theme by Vdoing | Copyright © 2019-2025 chst365 | 豫ICP备17031889号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式