成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

高中生打破React性能極限,將React性能提升70%!

開(kāi)發(fā) 架構(gòu)
對(duì)于很多應(yīng)用來(lái)說(shuō),傳統(tǒng)的虛擬 DOM 可能就足夠了,不需要切換到塊虛擬 DOM 或其他以性能為中心的框架。如果應(yīng)用在大多數(shù)設(shè)備上運(yùn)行流暢且沒(méi)有性能問(wèn)題,那么可能不值得花時(shí)間和精力過(guò)渡到不同的框架。在對(duì)技術(shù)堆棧進(jìn)行任何重大更改之前,必須仔細(xì)權(quán)衡取舍并評(píng)估應(yīng)用的要求。

React 是當(dāng)今最受歡迎的 JavaScript 框架之一,它的創(chuàng)新之一就是引入了虛擬 DOM,但很多現(xiàn)代框架已經(jīng)不再采用這種方案,其在某些情況下會(huì)影響應(yīng)用的性能。Svelte 的創(chuàng)建者 Rich Harris 曾將其稱(chēng)作純粹的開(kāi)銷(xiāo)。

圖片

一位名為 Aidenybai 的高中生開(kāi)發(fā)了一個(gè)名為 million.js 的輕量級(jí)(小于 4KB)虛擬 DOM 庫(kù),其可將 React 組件的性能提高多達(dá) 70%。

圖片

那 million.js 到底是什么?又是如何讓 React 的速度提高 70% 的呢?下面就來(lái)一探究竟!

本文目錄:

  • 基本概念
  • 使用步驟
  • 打包體積
  • 工作原理
  • 使用場(chǎng)景
  • 總結(jié)

基本概念

Million.js 提供了一個(gè)極致優(yōu)化的虛擬 DOM,可以與 React 兼容。使用 Million 創(chuàng)建 Web 應(yīng)用程序就像使用 React 組件一樣簡(jiǎn)單(它只是一個(gè)包裝 React 組件的高階組件),但加載和渲染速度更快。Million.js 使用經(jīng)過(guò)微調(diào)和優(yōu)化的虛擬 DOM 減少了 React 的開(kāi)銷(xiāo),就像 React 組件以純 JavaScript 的速度運(yùn)行一樣。

一個(gè)高中生就這么超越了Meta 的整個(gè)頂級(jí)工程師團(tuán)隊(duì)?帶著懷疑看了看 JavaScript 框架性能基準(zhǔn)測(cè)試對(duì)比結(jié)果:

圖片

數(shù)據(jù)不言自明,在第二張表中,內(nèi)存消耗的差異更加顯著,它清楚的顯示了 Million 如何在內(nèi)方面得到更好的優(yōu)化。

那為什么 million.js 會(huì)如此之快呢?

React 默認(rèn)的虛擬 DOM 是實(shí)際 DOM 的一種內(nèi)存抽象。組件被存儲(chǔ)在一個(gè)樹(shù)形結(jié)構(gòu)中,當(dāng)狀態(tài)發(fā)生變化時(shí),React 會(huì)創(chuàng)建一個(gè)新的虛擬 DOM。接下來(lái),將新的虛擬 DOM 樹(shù)與舊的虛擬 DOM 樹(shù)進(jìn)行比較,找出兩者之間的差異。最后,使用這些差異更新實(shí)際 DOM 樹(shù)。這就是所謂的協(xié)調(diào)過(guò)程。但是,創(chuàng)建全新的虛擬 DOM 代價(jià)很大。

Million 通過(guò)使用塊虛擬 DOM,采用了更加精簡(jiǎn)的方式。將應(yīng)用程序中的動(dòng)態(tài)部分提取出來(lái)并進(jìn)行跟蹤,當(dāng)狀態(tài)發(fā)生變化時(shí),只對(duì)變化的部分進(jìn)行 diff 操作。相比默認(rèn)的虛擬 DOM,不需要對(duì)整個(gè)樹(shù)進(jìn)行 diff。由于 Million 跟蹤了動(dòng)態(tài)部分的位置,因此可以精確地找到并更新它們,這種方法與 Svelte 很相似。

后面會(huì)詳細(xì)介紹 Million.js 的工作原理。

使用步驟

在使用 million 之前,首先需要?jiǎng)?chuàng)建一個(gè) React 項(xiàng)目在,這里略過(guò)創(chuàng)建項(xiàng)目的過(guò)程。

或者也可以直接克隆官方提供的 React + Vite 項(xiàng)目模板(https://github.com/aidenybai/million-react),打開(kāi)項(xiàng)目根目錄,依次執(zhí)行 npm install 和 npm run dev 命令來(lái)啟動(dòng)項(xiàng)目,啟動(dòng)完成之后在瀏覽器輸入 localhost:3000 就可以看到以下界面:

圖片

可以通過(guò)以下命令來(lái)安裝 million 庫(kù):

npm install million

使用方式很簡(jiǎn)單,引入 million,并在組件中使用:

import React, { useState } from 'react';
import { block } from 'million/react';
import './App.css';

function App() {
  const [count, setCount] = useState(0);
  return (
    <div className="App">
      <h1>Million + React</h1>
      <button onClick={() => setCount((count) => count + 1)}>
        count: {count}
      </button>
    </div>
  );
}

const AppBlock = block(App)

export default AppBlock

可以看到,組件從 million 中引入了 block(),并使用 block() 包裹 App 組件。Million.js 可以讓我們創(chuàng)建塊(block),塊是一種特殊的高階組件,可以像 React 組件一樣使用,但具有更快的渲染速度。

塊的一個(gè)用例是高效地渲染數(shù)據(jù)列表。下面在 React 中構(gòu)建一個(gè)數(shù)據(jù)網(wǎng)格。可以在組件中分別定義 <Table />(用于展示數(shù)據(jù)列表) 和 <Input />(用于輸入展示列表的行數(shù)) 組件,使用 useState() hook 存儲(chǔ)要顯示的行數(shù)。

import React, { useState } from 'react';
import './App.css';

function App() {
  const [rows, setRows] = useState(1);
 
  return (
    <div>
      <Input value={rows} setValue={setRows} />
      <Table>
        // ...
      </Table>
    </div>
  );
}

export default App;

假設(shè)我們通過(guò)一個(gè)名為 buildData(rows) 的函數(shù)獲取任意數(shù)據(jù)數(shù)組:

const data = buildData(100);
// [{ adjective: '...', color: '...', noun: '...' }, ... x100]

現(xiàn)在可以使用 Array.map() 在表格中渲染數(shù)據(jù):

import React, { useState } from 'react';
import './App.css';

function App() {
  const [rows, setRows] = useState(1);
  const data = buildData(rows);
 
  return (
    <div>
      <Input value={rows} setValue={setRows} />
      <Table>
        {data.map(({ adjective, color, noun }) => (
          <tr>
            <td>{adjective}</td>
            <td>{color}</td>
            <td>{noun}</td>
          </tr>
        ))}
      </Table>
    </div>
  );
}

export default App;

頁(yè)面效果如下:

它的性能表現(xiàn)非常好。從 0 到 100,幾乎沒(méi)有延遲,但一旦超過(guò) 500 左右,渲染時(shí)就會(huì)有明顯的延遲。

這時(shí)引入 million 來(lái)看看:

import React, { useState } from 'react';
import { block } from 'million/react';
import './App.css';

function App() {
  const [rows, setRows] = useState(1);
  const data = buildData(rows);
 
  return (
    <div>
      <Input value={rows} setValue={setRows} />
      <Table>
        {data.map(({ adjective, color, noun }) => (
          <tr>
            <td>{adjective}</td>
            <td>{color}</td>
            <td>{noun}</td>
          </tr>
        ))}
      </Table>
    </div>
  );
}

const AppBlock = block(App)

export default AppBlock

此時(shí),再添加超過(guò) 500 條數(shù)據(jù)時(shí),頁(yè)面渲染就會(huì)快很多。

除此之外,Million 還提供了其他實(shí)用工具,特別是用于高效地渲染列表。Million 并不推薦將傳統(tǒng)的列表包裝在block HOC 中進(jìn)行渲染,而是推薦使用內(nèi)置的 For 組件:

<For each={data}>
  ({ adjective, color, noun }) => (
    <tr>
      <td>{adjective}</td>
      <td>{color}</td>
      <td>{noun}</td>
    </tr>
  )
</For>

打包體積

頁(yè)面的執(zhí)行性能非常重要,其初始加載也非常重要,其中一個(gè)重要因素就是項(xiàng)目的打包體積。這里我們使用 Million 和不使用它構(gòu)建了相同的應(yīng)用。

使用純 React 的打包體積:

使用 Million 的打包體積:

可以看到,gzip 捆綁包大小的差異小于 5 kB,這意味著對(duì)于多數(shù) React 應(yīng)用來(lái)說(shuō),Million 對(duì)項(xiàng)目的體積影響可以忽略不計(jì)。

工作原理

最后,我們來(lái)看看 million 的工作原理。

React 的虛擬 DOM

虛擬 DOM 的產(chǎn)生是為了解決頻繁操作真實(shí) DOM 帶來(lái)的性能問(wèn)題。它是真實(shí) DOM 的輕量級(jí)、內(nèi)存中的表示形式。當(dāng)一個(gè)組件被渲染時(shí),虛擬 DOM 會(huì)計(jì)算新?tīng)顟B(tài)和舊狀態(tài)之間的差異(稱(chēng)為 diff 過(guò)程),并對(duì)真實(shí) DOM 進(jìn)行最小化的變化,使它與更新后的虛擬 DOM 同步(這個(gè)過(guò)程稱(chēng)為協(xié)調(diào))。下面來(lái)看一個(gè)例子,假設(shè)有一個(gè) React 組件 <Numbers />:

function Numbers() {
  return (
    <foo>
      <bar>
        <baz />
      </bar>
      <boo />
    </foo>
  );
}

當(dāng) React 渲染此組件時(shí),它將經(jīng)過(guò)檢查更改的 diff 和更新 DOM 的協(xié)調(diào)過(guò)程。這個(gè)過(guò)程看起來(lái)像這樣:

  1. 我們得到了兩個(gè)虛擬 DOM:current(當(dāng)前的),代表當(dāng)前 UI 的樣子,和 new(新的),代表想要看到的樣子。
  2. 比較第一個(gè)節(jié)點(diǎn),發(fā)現(xiàn)沒(méi)有差異,繼續(xù)比較下一個(gè)。
  3. 比較第二個(gè)節(jié)點(diǎn),發(fā)現(xiàn)有一個(gè)差異,在 DOM 中進(jìn)行更新。
  4. 比較第三個(gè)節(jié)點(diǎn),發(fā)現(xiàn)它在新的虛擬 DOM 中已經(jīng)不存在了,在 DOM 中將其刪除。
  5. 比較第四個(gè)節(jié)點(diǎn),發(fā)現(xiàn)它在新的虛擬 DOM 中已經(jīng)不存在了,在 DOM 中將其刪除。
  6. 比較第五個(gè)節(jié)點(diǎn),發(fā)現(xiàn)有差異,在 DOM 中進(jìn)行更新并完成了整個(gè)過(guò)程。

diff 過(guò)程取決于樹(shù)的大小,最終導(dǎo)致虛擬 DOM 的性能瓶頸。組件的節(jié)點(diǎn)越多,diff 所需要的時(shí)間就越長(zhǎng)。

隨著像 Svelte 這樣的新框架的出現(xiàn),由于性能開(kāi)銷(xiāo)的問(wèn)題,甚至不再使用虛擬 DOM。相反,Svelte 使用一種稱(chēng)為 "臟檢查" 的技術(shù)來(lái)確定哪些內(nèi)容已經(jīng)發(fā)生了改變。類(lèi)似 SolidJS 這樣的精細(xì)響應(yīng)式框架更進(jìn)一步,精確定位于 DOM 中哪些部分發(fā)生了變化,并僅更新這部分內(nèi)容。

Million 的虛擬 DOM

2022 年,Blockdom 發(fā)布了 。基于不同的思路,Blockdom 引入了“塊虛擬DOM”的概念。塊虛擬 DOM 采用不同的 diff 方法,可以分為兩部分:

  • 靜態(tài)分析:對(duì)虛擬 DOM 進(jìn)行分析,將樹(shù)的動(dòng)態(tài)部分提取到“Edit Map”中,即虛擬DOM的動(dòng)態(tài)部分到狀態(tài)的“Edit”(Map)列表中。
  • 臟檢查:對(duì)比狀態(tài)(而不是虛擬 DOM 樹(shù))以確定發(fā)生了什么變化。如果狀態(tài)發(fā)生了變化,通過(guò) Edit Map 直接更新DOM。

簡(jiǎn)而言之,就是對(duì)比數(shù)據(jù)而不是 DOM,因?yàn)閿?shù)據(jù)的大小通常比 DOM 的大小小得多。而且對(duì)比數(shù)據(jù)值可能比對(duì)比完整的 DOM 節(jié)點(diǎn)更簡(jiǎn)單。

由于 Million.js 采用了與 Blockdom 類(lèi)似的方法,因此下面將使用 Million.js 的語(yǔ)法。

下面來(lái)看一個(gè)簡(jiǎn)單的計(jì)數(shù)器應(yīng)用以及它如何使用 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);

這個(gè)程序很簡(jiǎn)單,顯示效果如下:

(1)靜態(tài)分析

靜態(tài)分析可以在編譯時(shí)或運(yùn)行時(shí)的第一步完成,具體取決于是否使用了 Million.js 的實(shí)驗(yàn)性編譯器。

此步驟負(fù)責(zé)將虛擬 DOM 的動(dòng)態(tài)部分提取到“編輯映射”中。

  1. 這里沒(méi)有使用 React 來(lái)渲染 JSX,而是使用 Million.js 來(lái)渲染它,它將占位符節(jié)點(diǎn)(用“?”表示)傳遞到虛擬DOM。這些節(jié)點(diǎn)將充當(dāng)動(dòng)態(tài)內(nèi)容的占位符,并在靜態(tài)分析過(guò)程中使用。
  2. 現(xiàn)在開(kāi)始靜態(tài)分析,檢查第一個(gè)節(jié)點(diǎn)是否有占位符,沒(méi)有找到,繼續(xù)下一步。
  3. 在第二個(gè)節(jié)點(diǎn)中檢查占位符,沒(méi)有找到,繼續(xù)下一步。
  4. 檢查第三個(gè)節(jié)點(diǎn)的占位符并找到“?”。將占位符添加到“Edit Map”,它將prop1關(guān)聯(lián)到占位符節(jié)點(diǎn)。然后從塊中刪除占位符。
  5. 檢查第四個(gè)節(jié)點(diǎn)的占位符并找到“?”。將占位符添加到“Edit Map”,它將 prop2 關(guān)聯(lián)到占位符節(jié)點(diǎn)。然后從塊中刪除占位符。
  6. 檢查第五個(gè)節(jié)點(diǎn)是否有占位符,沒(méi)有找到,完成檢測(cè)。

(2)臟檢查

創(chuàng)建 Edit Map 后,就可以開(kāi)始臟檢查了。這一步負(fù)責(zé)確定狀態(tài)發(fā)生了什么變化,并相應(yīng)地更新 DOM。

  1. 可以只區(qū)分 prop1 和 prop2,而不是按元素進(jìn)行區(qū)分。由于兩者都與在靜態(tài)分析期間創(chuàng)建的“Edit Map”相關(guān)聯(lián),因此一旦確定差異,就可以直接更新 DOM。
  2. 比較當(dāng)前的 prop1 和新的 prop1 值,由于它們不同,因此更新了 DOM。
  3. 比較當(dāng)前的 prop2 和新的 prop2 值,由于它們不同,因此更新了 DOM。

可以看到,臟檢查比 diff 步驟需要更少的計(jì)算。這是因?yàn)榕K檢查只關(guān)心狀態(tài),而不關(guān)心虛擬 DOM,因?yàn)槊總€(gè)虛擬節(jié)點(diǎn)可能需要許多級(jí)別的遞歸來(lái)確定它是否已經(jīng)改變,狀態(tài)只需要一個(gè)淺層相等檢查。

使用場(chǎng)景

Million.js 具有相當(dāng)高的性能,并且能夠在 JavaScript 框架基準(zhǔn)測(cè)試中勝過(guò) React。

JavaScript 框架基準(zhǔn)測(cè)試通過(guò)渲染一個(gè)包含行和列的大型表格來(lái)測(cè)試框架的性能。該基準(zhǔn)測(cè)試旨在測(cè)試高度不切實(shí)際的性能測(cè)試(如添加/替換 1000 行),并不一定代表真實(shí)的應(yīng)用。

那 Million.js 或塊虛擬 DOM 可以用在什么地方呢?

靜態(tài)內(nèi)容多,動(dòng)態(tài)內(nèi)容少

當(dāng)有很多靜態(tài)內(nèi)容而動(dòng)態(tài)內(nèi)容很少時(shí),最好使用塊虛擬 DOM。塊虛擬 DOM最大的優(yōu)勢(shì)就是不需要考慮虛擬 DOM 的靜態(tài)部分,所以如果能跳過(guò)很多靜態(tài)內(nèi)容,速度會(huì)非常快。

例如,在這種情況下,塊虛擬 DOM 將比常規(guī)虛擬 DOM 快得多:

// ?
<div>
  <div>{dynamic}</div>
  很多靜態(tài)內(nèi)容...
</div>

如果有很多動(dòng)態(tài)內(nèi)容,可能看不出塊虛擬 DOM 和常規(guī)虛擬 DOM 的區(qū)別:

// ?
<div>
  <div>{dynamic}</div>
  <div>{dynamic}</div>
  <div>{dynamic}</div>
  <div>{dynamic}</div>
  <div>{dynamic}</div>
</div>

如果構(gòu)建一個(gè)管理系統(tǒng),或者一個(gè)包含大量靜態(tài)內(nèi)容的網(wǎng)站,塊虛擬 DOM 可能非常適合。但是,如果構(gòu)建一個(gè)網(wǎng)站,其中比較數(shù)據(jù)所需的計(jì)算量明顯大于比較虛擬 DOM 所需的計(jì)算量,那么可能看不出太大差異。

例如,這個(gè)組件不適合塊虛擬 DOM,因?yàn)橐容^的數(shù)據(jù)值多于虛擬 DOM 節(jié)點(diǎn):

// 5個(gè)要比較的數(shù)據(jù)值
function Component({ a, b, c, d, e }) {
  // 1個(gè)要比較的虛擬DOM節(jié)點(diǎn)
  return <div>{a + b + c + d + e}</div>;
}

“穩(wěn)定”的 UI 樹(shù)

塊狀虛擬 DOM 也適用于“穩(wěn)定”的 UI 樹(shù),或者變化不大的 UI 樹(shù)。這是因?yàn)?Edit Map 只創(chuàng)建一次,不需要在每次渲染時(shí)都重新創(chuàng)建。

例如,以下組件是塊虛擬 DOM 的一個(gè)很好的使用場(chǎng)景:

function Component() {
  return <div>{dynamic}</div>;
}

但是這個(gè)組件可能比常規(guī)的虛擬 DOM 慢:

function Component() {
  return Math.random() > 0.5 ? <div>{dynamic}</div> : <p>sad</p>;
}

注意,“穩(wěn)定”返回意味著不允許具有非列表類(lèi)動(dòng)態(tài)的組件(如同一組件中的條件返回)。

細(xì)粒度使用

初學(xué)者犯的最大錯(cuò)誤之一是到處使用塊虛擬 DOM。這是個(gè)壞主意,因?yàn)閴K虛擬 DOM 并不總是比常規(guī)虛擬 DOM 快。

相反,應(yīng)該識(shí)別塊虛擬 DOM 更快的某些模式,并僅在這些情況下使用它。例如,可能對(duì)大表使用塊虛擬 DOM,但對(duì)具有少量靜態(tài)內(nèi)容的小表單使用常規(guī)虛擬 DOM。

總結(jié)

塊虛擬 DOM 為虛擬 DOM 概念提供了一個(gè)全新的視角,提供了一種管理更新和最小化開(kāi)銷(xiāo)的替代方法。盡管它具有潛力,但它并不是一種放之四海而皆準(zhǔn)的解決方案,開(kāi)發(fā)人員在決定是否采用這種方法之前應(yīng)該評(píng)估應(yīng)用的具體需求和性能要求。

對(duì)于很多應(yīng)用來(lái)說(shuō),傳統(tǒng)的虛擬 DOM 可能就足夠了,不需要切換到塊虛擬 DOM 或其他以性能為中心的框架。如果應(yīng)用在大多數(shù)設(shè)備上運(yùn)行流暢且沒(méi)有性能問(wèn)題,那么可能不值得花時(shí)間和精力過(guò)渡到不同的框架。在對(duì)技術(shù)堆棧進(jìn)行任何重大更改之前,必須仔細(xì)權(quán)衡取舍并評(píng)估應(yīng)用的要求。

責(zé)任編輯:武曉燕 來(lái)源: 前端充電寶
相關(guān)推薦

2025-01-13 00:00:00

2021-08-27 14:26:06

開(kāi)發(fā)技能React

2019-07-04 15:57:16

數(shù)據(jù)安全互聯(lián)網(wǎng)

2009-05-20 09:02:53

IT職業(yè)培訓(xùn)就業(yè)高中生

2019-02-25 07:07:38

技巧React 優(yōu)化

2024-06-04 00:00:01

微軟EdgeReact

2022-08-03 09:11:31

React性能優(yōu)化

2019-03-13 10:10:26

React組件前端

2016-12-19 10:00:00

React性能優(yōu)化

2023-11-01 17:57:56

React應(yīng)用程序性能

2017-01-04 10:18:00

React NativScrollViewAndroid

2011-04-19 09:40:31

2024-12-20 16:31:34

2019-03-14 15:38:19

ReactJavascript前端

2023-07-19 15:45:47

ReactDOM輕量級(jí)

2020-06-22 07:30:00

React開(kāi)發(fā)工具

2009-04-14 15:30:25

2009-08-10 17:08:52

計(jì)算機(jī)專(zhuān)業(yè)就業(yè)IT培訓(xùn)

2017-04-17 06:07:01

React Nativ開(kāi)發(fā)性能

2023-09-20 08:57:09

架構(gòu)內(nèi)存
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产精品69毛片高清亚洲 | 玖玖免费 | 91正在播放 | 亚洲精品日韩一区二区电影 | 91精品国产色综合久久 | 国产高清免费视频 | 日本精品视频在线观看 | 日韩有码一区 | 精精国产xxxx视频在线播放 | 国产高清视频在线观看 | 久国产精品 | 日韩精品一区二区三区在线播放 | 一区二区三区四区不卡 | 国产精品成人69xxx免费视频 | av中文字幕在线 | 自拍偷拍第一页 | 国产午夜精品久久久久 | 国产在线麻豆精品入口 | 国产黄色电影 | 亚洲精品高清视频 | 亚洲一区二区三区 | 亚洲综合色视频在线观看 | 国产精品久久欧美久久一区 | 精品亚洲一区二区三区四区五区高 | 欧美视频在线免费 | 日日干日日色 | 日韩影音 | 国产精品视频久久 | 一区二区在线看 | 亚洲精品日韩在线 | 粉嫩av久久一区二区三区 | 国产一区二区在线免费观看 | 中文字幕1区2区3区 日韩在线视频免费观看 | av在线一区二区三区 | 久久综合九色综合欧美狠狠 | 日韩高清成人 | 情侣酒店偷拍一区二区在线播放 | 日韩亚洲欧美一区 | 亚洲一区二区精品视频 | 99在线免费观看视频 | 日本精品999 |