[译] React 16 带来了什么以及对 Fiber 的解释

本文讲的是[译] React 16 带来了什么以及对 Fiber 的解释,

特性概览 —— 万众期待的 React 16

React 核心算法的更新已经进行了多年了 —— 这次更新提供了一个从底层重写了 React 的 reconciliation 算法(译注:reconciliation 算法,是 React 用来比较两棵 DOM 树差异、从而觉得哪一部分应当被更新的算法)。React将维护相同的公共API,并允许大多数项目立即升级(假设您已经修复了弃用警告)。新版本的发布主要有如下目的:

  • 能够将渲染流程中可中断的工作(interruptible work)换划分为一个个的 chunk。
  • 能够为渲染流程中的工作提供优先级划分,rebase 以及重用能力。
  • 在渲染流程中,能够自如地在父子组件中切换,这使得在 React 实现 layout 成为了可能。
  • 能够从 render() 函数返回多个 element。
  • 对 error boundary 提供了更好的支持。
  • **可以在 gitconnected 上关注我 >**

特性

核心算法重写

这次算法重写带来的主要特性是异步渲染。(注意:在 16.0 中尚不支持,但是在未来的 16.x 版本中将会做为可选特性)。另外,新的重写删除了一些不成熟的、妨碍了内部变化的抽象。

这些多来自于 Lin Clark 的演讲,所以你可以看看这个演讲,再在 twitter 上 关注并点赞 Clark 来支持她这个视角独特的概述。

异步渲染的意义在于能够将渲染任务划分为多块。浏览器的渲染引擎是单线程的,这意味着几乎所有的行为都是同步发生的。React 16 使用原生的浏览器 API 来间歇性地检查当前是否还有其他任务需要完成,从而实现了对主线程和渲染过程的管理。在 Firefox 中,一个浏览器主线程的例子很简单:

while (!mExiting) {
    NS_ProcessNextEvent(thread);
}

在之前的版本中,React 会在计算 DOM 树的时候锁住整个线程。这个 reconciliation 的过程现在被称作 “stack reconciliation”。尽管 React 已经是以快而闻名了,但是锁住整个线程也会让一些应用运行得不是很流畅。16 这个版本通过不要求渲染过程在初始化后一次性完成修复了该问题。React 计算了 DOM 树的一部分,之后将暂停渲染,来看看主线程是否有任何的绘图或者更新需要去完成。一旦绘图和更新完成了,React 就会继续渲染。这个过程通过引入了一个新的,叫做 “fiber” 的数据结构完成,fiber 映射到了一个 React 实例并为该实例管理其渲染任务,它也知道它和其他 fiber 之间的关系。一个 fiber 仅仅是一个 JavaScript 对象。下面的图片对比了新旧渲染方法。

React 16 也会在必要的时候管理各个更新的优先级。这就允许了高优先级更新能够排到队列开头从而被首先处理。关于此的一个例子就是按键输入。鉴于应用流畅性的考虑,用户需要立即获得按键响应,因而相对于那些可以等待 100-200 毫秒的低优先级更新任务,按键输入拥有较高优先级。

通过将 UI 的更新划分为若干小的工作单元,用户体验获得了提高。暂停 reconciliation 任务来允许主线程执行其他紧急的任务,这提供了更平滑的接口和可感知到的性能提升。

错误处理

在 React 中,错误总是难于处理,但在 React 16 中,一切发生了变化。之前版本中,组件内部发生的错误将污染 React 的状态,并且在后续的渲染中引起更多含义模糊的错误。

React 16 含有的 error boundary 不只能够提供清晰的错误信息,还能防止整个应用因错误而崩溃。将 error boundary 添加到你的应用之后,它能够 catch 住错误并且展示一个对应的 UI 而不会造成整个组件树崩溃。boundary 能够在组建的渲染期、生命周期方法及所有其子树的构造方法中 catch 错误。error boundary 通过一个新的生命周期方法 componentDidCatch(error, info) 就可以轻松实现。

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    // 展示一个回退 UI
    this.setState({ hasError: true });
    // 你也可以将错误日志输出到一个错误报告服务
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      // 你可以渲染任意的自定义回退 UI
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

在该例子中,任何发生在 <MyWidget/> 或者其子组件中的错误都能被 <ErrorBoundary> 组件所捕获。这个功能类似于 JavaScript 中的 catch {} 块。如果 error boundary 收到了一个错误状态,作为开发者的你能够确定此时应当展示的 UI。注意到 error boundary 只会 catch 其子树的错误,但不会识别自身的错误。

进一步,你能看到如下健全的、可控的错误信息:

兼容性

异步渲染

React 16.0 的初始版本将聚焦于对现有应用的兼容性。异步渲染不会再一开始作为一个可选项,但是在之后的 16.x 的版本中,异步渲染会作为一个可选特性。

浏览器兼容性

React 16 依赖于 Map 及 Set。为了确保对所有浏览器兼容,你需要要引入相关 polyfill。目前流行的 polyfill 可选 core-js 或 babel-polyfill

另外,React 16 也依赖于 requestAnimationFrame,这个依赖主要服务于测试。一个针对测试目的的 shim 可以是:

global.requestAnimationFrame = function(callback) {
  setTimeout(callback);
};

组件声明周期

由于 React 实现了渲染的优先级设置,你无法再确保不同组件的 componentWillUpdate 和shouldComponentUpdate 会按期望的顺序被调用。React 团队目前正致力于提供一个更新路径,来防止这些应用受到上面的行为的影响。

使用

截止到本文发布,目前的 React 16 还处于 beta 版本,但是很快它就会正式发布。你可以通过下面的方式尝试 React 16:

# yarn
yarn add react@next react-dom@next

# npm
npm install --save react@next react-dom@next

如果你觉得本文对你很有用,请给我一个 。 在 Medium 上关注我,你能阅读更多关于 React、Nonde.js、JavaScript 和开源软件的文章。你也可以在 Twitter 或者 gitconnected找到我。
gitconnected —— 一个软件开发者和工程师的社区。创建一个账户并登陆 gitconnected,这是一个当前最大的沟通开发者的社区。这是它的最新地址 gitconnected.com






原文发布时间为:2017年10月11日


本文来自合作伙伴掘金,了解相关信息可以关注掘金网站。

时间: 2024-09-20 04:03:18

[译] React 16 带来了什么以及对 Fiber 的解释的相关文章

[译] React 未来之函数式 setState

本文讲的是[译] React 未来之函数式 setState, 原文地址:Functional setState is the future of React 原文作者:Justice Mba 译文出自:掘金翻译计划 译者:reid3290 校对者:sunui,imink React 使得函数式编程在 JavaScript 领域流行了起来,这驱使大量框架采用 React 所推崇的基于组件的编程模式,函数式编程热正在大范围涌向 web 开发领域. 但是 React 团队却还不"消停",他

[译] React 在服务端渲染的实现

本文讲的是[译] React 在服务端渲染的实现, 原文地址:Server-Side React Rendering 原文作者:Roger Jin 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- 译者:牧云云 校对者:CACppuccino.xx1124961758 React 在服务端渲染的实现 React是最受欢迎的客户端 JavaScript 框架,但你知道吗(或许更应该试试),你可以使用 React 在服务器端进行渲染? 假设你为客户构建了一个很棒的

译:Facebook将重新授权许可React、Jest、Flow 与 Immutable.js(重磅)

下周,我们将用MIT协议重新授权我们的开源项目React.Jest.Flow和Immutable.js.之所以我们要重新授权这些项目,是因为React是很多网络开源软件生态系统的基础,我们不希望因为非技术的原因导致开源生态的倒退. Next week, we are going to relicense our open source projects React, Jest, Flow, and Immutable.js under the MIT license. We're relicen

Facebook 重写 React 和 Relay 框架,旨在提升性能

Facebook 已完全重写用于构建用户界面的 React 框架.新的项目名称为 React Fiber,其在公布之前就已在 Facebook.com 运行使用.现在,Facebook 将此项目公示,并计划在今年推出 React 16.0 之后将它向开发者开放. 同时,Facebook 也表示已重写 React 的数据驱动框架 Relay. React Fiber React Fiber 包含 React 最初的开发理念,也兼容现有的基于 React 的应用程序.Facebook 将其作为 Re

深入了解React新引擎:React Fiber

Facebook正在以流行的JavaScript框架React为基础开发一个全新的架构.这个名为React Fiber的全新设计改变了检测变更的方法和时机,借此可改进浏览器端和其他渲染设备的响应速度. 这一全新架构最初已于2016年7月公开发布,其中蕴含着过去多年来Facebook不断改进的工作成果.该架构可向后兼容,彻底重写了React的协调(Reconciliation)算法.该过程可用于确定出现变更的具体时间,并将变更传递给渲染器. 实际上该团队在单线程JavaScript引擎的基础上构建

[译] setState() 门事件

本文讲的是[译] setState() 门事件, 原文地址:setState() Gate 原文作者:Eric Elliott 译文出自:掘金翻译计划 译者:reid3290 校对者:1992chenlu,qinfanpeng React setState() 解惑 译注:本文起因于作者的一条推特,他认为应该避免使用 setState(),随后引发论战,遂写此文详细阐明其观点.译者个人认为,本文主要在于"撕逼",并未深入介绍 setState() 的技术细节,希望从技术层面深入了解 s

Facebook 是如何构建首个跨平台 React Native 应用的?

今年早些时候,我们发布了 React Native for iOS.React Native 将开发者在 web 上所使用的 React - 拥有声明式的自包含组件以及快速的开发周期 - 带到了移动平台, 同时保留了原生应用程序的运行速度.保真度及外观.今天,我们很高兴地发布了 React Native for Android. 现在我们已经在 Facebook 的生产环境中使用 React Native 超过一年了.几乎就是一年之前,我们的团队着手开发广告管理应用.当时我们的目标是创建一个新的

React全栈 Redux Flux webpack Babel整合开发---学习笔记

这些东东不难,只是工程结构和开发流程有些专业. 我不是专业写前端,但自己的代码中,VUE.JS,JQUERY之类的也用得不少,了解一下总是有好处的. 这本书,写得不错,概念,实操都一步一步的. ~~~~~~~~~~~~~~~ 当然,webpack的版本是基于1x的,到2x要自己作一些语法转换. ~~~~~~~~~~~~~~~ 看到一小半,将一个系统工程的文件呈现一下,便于总结记忆. package.json { "name": "react", "vers

2017年React、Angular和Vue的动态

2016年对于JavaScript来说是非常重要的一年,因为其语言和框架均向前迈进了一大步.2017年可能依然会如此,因为还有很多令人兴奋的特性将会发布. 框架方面增长势头最强劲的是Vue.js.2016年,Vue的创建者Evan You已经开始将全部精力放到该框架上,并且在9月份发布了2.0版本.社区也经常会将Vue看成现有JavaScript框架的一个现实可行的替代者. 2017年,这种增长势头依然会继续,同时Vue还制定了新一年的计划,包括更好的测试和提升开发者的体验.Vue现在正致力于本