高中生打破React性能极限,将React性能提升70%!(下)

简介: 高中生打破React性能极限,将React性能提升70%!(下)

高中生打破React性能极限,将React性能提升70%!(上)https://developer.aliyun.com/article/1411538


Million 的虚拟 DOM


2022 年,Blockdom 发布了 。基于不同的思路,Blockdom 引入了“块虚拟DOM”的概念。块虚拟 DOM 采用不同的 diff 方法,可以分为两部分:

  • 静态分析:对虚拟 DOM 进行分析,将树的动态部分提取到“Edit Map”中,即虚拟DOM的动态部分到状态的“Edit”(Map)列表中。
  • 脏检查:对比状态(而不是虚拟 DOM 树)以确定发生了什么变化。如果状态发生了变化,通过 Edit Map 直接更新DOM。

简而言之,就是对比数据而不是 DOM,因为数据的大小通常比 DOM 的大小小得多。而且对比数据值可能比对比完整的 DOM 节点更简单。

由于 Million.js 采用了与 Blockdom 类似的方法,因此下面将使用 Million.js 的语法。

下面来看一个简单的计数器应用以及它如何使用 Million.js 处理:

import { useState } from 'react';
import { block } from 'million/react';
function Count() {
  const [count, setCount] = useState(0);
  const node1 = count + 1;
  const node2 = count + 2;
  return (
    <div>
      <ul>
        <li>{node1}</li>
        <li>{node2}</li>
      </ul>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Increment Count
      </button>
    </div>
  );
}
const CountBlock = block(Count);

constCountBlock = block(Count);

这个程序很简单,显示效果如下:

21.webp.jpg


(1)静态分析

静态分析可以在编译时或运行时的第一步完成,具体取决于是否使用了 Million.js 的实验性编译器。

此步骤负责将虚拟 DOM 的动态部分提取到“编辑映射”中。

  1. 这里没有使用 React 来渲染 JSX,而是使用 Million.js 来渲染它,它将占位符节点(用“?”表示)传递到虚拟DOM。这些节点将充当动态内容的占位符,并在静态分析过程中使用。

31.webp.jpg

  1. 现在开始静态分析,检查第一个节点是否有占位符,没有找到,继续下一步。

32.webp.jpg

  1. 在第二个节点中检查占位符,没有找到,继续下一步。

33.webp.jpg

  1. 检查第三个节点的占位符并找到“?”。 将占位符添加到“Edit Map”,它将prop1关联到占位符节点。然后从块中删除占位符。

34.webp.jpg

  1. 检查第四个节点的占位符并找到“?”。 将占位符添加到“Edit Map”,它将 prop2 关联到占位符节点。 然后从块中删除占位符。

35.webp.jpg

  1. 检查第五个节点是否有占位符,没有找到,完成检测。

36.webp.jpg

(2)脏检查

创建 Edit Map 后,就可以开始脏检查了。 这一步负责确定状态发生了什么变化,并相应地更新 DOM。

  1. 可以只区分 prop1prop2,而不是按元素进行区分。 由于两者都与在静态分析期间创建的“Edit Map”相关联,因此一旦确定差异,就可以直接更新 DOM。
  2. 41.webp.jpg
  3. 比较当前的 prop1 和新的 prop1 值,由于它们不同,因此更新了 DOM。

42.webp.jpg

  1. 比较当前的 prop2 和新的 prop2 值,由于它们不同,因此更新了 DOM。

43.webp.jpg可以看到,脏检查比 diff 步骤需要更少的计算。这是因为脏检查只关心状态,而不关心虚拟 DOM,因为每个虚拟节点可能需要许多级别的递归来确定它是否已经改变,状态只需要一个浅层相等检查。

Million.js使用场景

Million.js 具有相当高的性能,并且能够在 JavaScript 框架基准测试中胜过 React。 JavaScript 框架基准测试通过渲染一个包含行和列的大型表格来测试框架的性能。该基准测试旨在测试高度不切实际的性能测试(如添加/替换 1000 行),并不一定代表真实的应用。

那 Million.js 或块虚拟 DOM可以用在什么地方呢?

静态内容多,动态内容少

当有很多静态内容而动态内容很少时,最好使用块虚拟 DOM。 块虚拟 DOM最大的优势就是不需要考虑虚拟 DOM 的静态部分,所以如果能跳过很多静态内容,速度会非常快。

例如,在这种情况下,块虚拟 DOM 将比常规虚拟 DOM 快得多:

// ✅
<div>
  <div>{dynamic}</div>
  很多静态内容...
</div>

如果有很多动态内容,可能看不出块虚拟 DOM 和常规虚拟 DOM 的区别:

// ❌
<div>
  <div>{dynamic}</div>
  <div>{dynamic}</div>
  <div>{dynamic}</div>
  <div>{dynamic}</div>
  <div>{dynamic}</div>
</div>

如果构建一个管理系统,或者一个包含大量静态内容的网站,块虚拟 DOM 可能非常适合。 但是,如果构建一个网站,其中比较数据所需的计算量明显大于比较虚拟 DOM 所需的计算量,那么可能看不出太大差异。

例如,这个组件不适合块虚拟 DOM,因为要比较的数据值多于虚拟 DOM 节点:

javascript

复制代码

// 5个要比较的数据值functionComponent({ a, b, c, d, e }) {
  // 1个要比较的虚拟DOM节点  return<div>{a + b + c + d + e}div>;
}

“稳定”的 UI 树

块状虚拟 DOM 也适用于“稳定”的 UI 树,或者变化不大的 UI 树。 这是因为 Edit Map 只创建一次,不需要在每次渲染时都重新创建。

例如,以下组件是块虚拟 DOM 的一个很好的使用场景:

javascript

复制代码

functionComponent() {
  return<div>{dynamic}div>;
}

但是这个组件可能比常规的虚拟 DOM 慢:

javascript

复制代码

functionComponent() {
  returnMath.random() > 0.5 ? <div>{dynamic}div> : <p>sadp>;
}

注意,“稳定”返回意味着不允许具有非列表类动态的组件(如同一组件中的条件返回)。

细粒度地使用

初学者犯的最大错误之一是到处使用块虚拟 DOM。 这是个坏主意,因为块虚拟 DOM 并不总是比常规虚拟 DOM 快。

相反,应该识别块虚拟 DOM 更快的某些模式,并仅在这些情况下使用它。 例如,可能对大表使用块虚拟 DOM,但对具有少量静态内容的小表单使用常规虚拟 DOM。

总结

块虚拟 DOM 为虚拟 DOM 概念提供了一个全新的视角,提供了一种管理更新和最小化开销的替代方法。 尽管它具有潜力,但它并不是一种放之四海而皆准的解决方案,开发人员在决定是否采用这种方法之前应该评估应用的具体需求和性能要求。

对于很多应用来说,传统的虚拟 DOM 可能就足够了,可能不需要切换到块虚拟 DOM 或其他以性能为中心的框架。 如果应用在大多数设备上运行流畅且没有性能问题,那么可能不值得花时间和精力过渡到不同的框架。在对技术堆栈进行任何重大更改之前,必须仔细权衡取舍并评估应用的要求。

相关文章
|
5月前
|
存储 缓存 监控
如何避免React性能问题
【4月更文挑战第9天】 提升React应用性能的关键策略包括:最小化渲染,如使用`React.memo`和`PureComponent`;优化列表渲染,如使用虚拟化和`key`属性;代码分割以按需加载;避免内联函数和对象;优化state和props;使用Profiler分析性能;减少网络请求;谨慎使用第三方库;考虑服务端渲染或静态网站生成;并保持应用更新。持续监控和调整是性能优化的重要部分。
50 8
|
5月前
|
JavaScript 前端开发 API
详解React与Vue的性能对比
详解React与Vue的性能对比
299 0
|
5月前
|
前端开发 JavaScript UED
使用React Hooks优化前端应用性能
本文将深入探讨如何使用React Hooks来优化前端应用的性能,重点介绍Hooks在状态管理、副作用处理和组件逻辑复用方面的应用。通过本文的指导,读者将了解到如何利用React Hooks提升前端应用的响应速度和用户体验。
|
5月前
|
监控 前端开发 API
如何优化React性能?
【4月更文挑战第9天】提升React应用性能的关键策略包括:使用React.memo和PureComponent防止不必要的重渲染;实施代码分割减少初始加载时间;借助React Profiler定位性能问题;优化state和props以减小大小和复杂性;设置列表项的key属性;避免内联函数和对象;自定义shouldComponentUpdate或React.memo比较函数;使用虚拟化技术渲染大量列表;通过Context API共享数据;以及利用服务端渲染加速首屏加载。不断监控和调整是优化的核心。
55 9
|
2月前
|
前端开发 UED 开发者
React组件优化全攻略:深度解析让你的前端应用飞速运行的秘诀——从PureComponent到React.memo的彻底性能比较
【8月更文挑战第31天】在构建现代Web应用时,性能是提升用户体验的关键因素。React作为主流前端库,其组件优化尤为重要。本文深入探讨了React组件优化策略,包括使用`PureComponent`、`React.memo`及避免不必要的渲染等方法,帮助开发者显著提升应用性能。通过实践案例对比优化前后效果,不仅提高了页面渲染速度,还增强了用户体验。优化React组件是每个开发者必须关注的重点。
49 0
|
5月前
|
前端开发 开发者
React useMemo钩子指南:优化计算性能
React useMemo钩子指南:优化计算性能
|
5月前
|
前端开发
掌握React中的useCallback:优化性能的秘诀
掌握React中的useCallback:优化性能的秘诀
|
5月前
|
前端开发 JavaScript API
blog-engine-07-gatsby 建极速网站和应用程序 基于React的最佳框架,具备性能、可扩展性和安全性。
探索多种博客引擎:Jekyll, Hugo, Hexo, Pelican, Gatsby, VuePress, Nuxt.js 和 Middleman。了解Gatsby,基于React的静态站点生成器,以其特性如React基础、静态生成、广泛插件支持、简便部署和现代开发流程脱颖而出。安装Gatsby需先安装Node.js,然后通过`gatsby-cli`创建新站点。开发涉及编写页面、本地开发、生成静态文件及部署。尽管Gatsby具有现代化和高性能优势,但也存在学习曲线和配置复杂性的挑战。
|
5月前
|
前端开发 UED
React 窗口防抖:提升网页性能的利器
React 窗口防抖:提升网页性能的利器
68 0
|
5月前
|
JavaScript 前端开发
React与Vue性能对比
React与Vue性能对比
74 2