自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

自研框架躋身全球 JS 框架榜單,排名緊隨 React、Angular 之后!

開發(fā) 前端
這次我們發(fā)布的大版本號為 6.0.2,我們將這個具有里程碑意義的大版本命名為 Strve6,而 “Strve6,從芯出發(fā)!” 這個口號正是 Strve6 的核心理念。這一版本象征著我們從底層技術(shù)出發(fā),致力于為用戶提供更優(yōu)質(zhì)、更高效的開發(fā)體驗(yàn)。

前言

終于實(shí)現(xiàn)了一個重要目標(biāo)!我獨(dú)立研發(fā)的 JavaScript 框架 Strve,最近發(fā)布了重大版本 6.0.2。距離上次大版本發(fā)布已經(jīng)接近兩個月,期間進(jìn)行了大量的優(yōu)化,使得框架性能和穩(wěn)定性都得到了大幅度的提升。在上次的大版本更新中,成功實(shí)現(xiàn)了對 JSX 語法的全面支持,使得 Strve 在代碼智能提示和代碼格式化方面更加友好,進(jìn)一步提高了開發(fā)效率。

介紹

相信有些小伙伴沒有聽說過 Strve 到底是什么,那我這里就大體介紹一下。

Strve 是一個可以將字符串轉(zhuǎn)換為視圖(用戶界面)的 JavaScript 庫。Strve 不僅易于使用,而且可以靈活地拆解不同的代碼塊。使用模板字符串開發(fā)用戶界面,主要是利用 JavaScript 的能力,只關(guān)注 JavaScript 文件。Strve 又是一個易用性的 JavaScript 框架,它提供了很多實(shí)用的功能與生態(tài)工具。

我們可以通過一些簡單的示例來了解 Strve 的使用方法。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Strve.js</title>
  </head>

  <body>
    <script src="https://cdn.jsdelivr.net/npm/strve-js@6.0.2/dist/strve.full.prod.js"></script>
    <script>
      const { html, setData, createApp } = Strve;
      const state = {
        count: 0,
      };

      function add() {
        setData(() => {
          state.count++;
        });
      }

      function App() {
        return html`<h1 onClick=${add}>${state.count}</h1>`;
      }

      const app = createApp(App);
      app.mount('#app');
    </script>
  </body>
</html>

在上述代碼中,我們通過引入 Strve 庫,并使用 createApp 方法創(chuàng)建了一個 App 組件,然后通過 mount 方法掛載到頁面上,這里的 App 組件就是通過模板字符串來定義的。這樣就可以在 JS 代碼中編寫用戶界面,是不是很方便呢?我們發(fā)現(xiàn),在模板字符串中,我們使用 ${} 來引用數(shù)據(jù),并且使用 onClick 方法來綁定事件。這樣就可以實(shí)現(xiàn)一個計數(shù)器的功能。

除了這種簡單的示例,Strve 還支持很多復(fù)雜的功能,我們可以使用 JSX 語法來編寫組件,也可以使用函數(shù)式組件來編寫組件,還可以使用組件來編寫組件,甚至可以編寫一些自定義的組件。

如果想了解更多關(guān)于 Strve 的信息,稍后可以到文章末尾處查閱官方文檔。

性能評估

我們既然發(fā)布了 Strve,那么肯定需要對其性能進(jìn)行評估,我們評估的工具就用js-framework-benchmark 。js-framework-benchmark 是什么?我們這里就簡單介紹下 js-framework-benchmark,它是一個用于比較 JavaScript 框架性能的項(xiàng)目。它旨在通過執(zhí)行一系列基準(zhǔn)測試來評估不同框架在各種場景下的性能表現(xiàn)。這些基準(zhǔn)測試包括渲染大量數(shù)據(jù)、更新數(shù)據(jù)、處理復(fù)雜的 UI 組件等。通過運(yùn)行這些基準(zhǔn)測試,可以比較不同框架在各種方面的性能優(yōu)劣,并幫助開發(fā)人員選擇最適合其需求的框架。js-framework-benchmark 項(xiàng)目提供了一個包含多個流行 JavaScript 框架的基準(zhǔn)測試套件。這些框架包括 Angular、React、Vue 等。每個框架都會在相同的測試場景下運(yùn)行,然后記錄下執(zhí)行時間和內(nèi)存使用情況等性能指標(biāo)。通過比較這些指標(biāo),可以得出不同框架的性能差異。這個項(xiàng)目的目標(biāo)是幫助開發(fā)人員了解不同 JavaScript 框架的性能特點(diǎn),以便在選擇框架時能夠做出更加明智的決策。同時,它也可以促進(jìn)框架開發(fā)者之間的競爭,推動框架的不斷改進(jìn)和優(yōu)化。

在評估之前,我們必須要了解 js-framework-benchmark 中有兩種模式。一種是 keyed,另一種是 non-keyed。在 js-framework-benchmark 中,"keyed" 模式是指通過給數(shù)據(jù)項(xiàng)分配一個唯一標(biāo)識符作為 "key" 屬性,從而實(shí)現(xiàn)數(shù)據(jù)項(xiàng)與 DOM 節(jié)點(diǎn)之間的一對一關(guān)系。當(dāng)數(shù)據(jù)發(fā)生變化時,與之相關(guān)聯(lián)的 DOM 節(jié)點(diǎn)也會相應(yīng)更新。而 non-keyed 模式是指當(dāng)數(shù)據(jù)項(xiàng)發(fā)生變化時,可能會修改之前與其他數(shù)據(jù)項(xiàng)關(guān)聯(lián)的 DOM 節(jié)點(diǎn)。

因?yàn)?Strve 支持keyed模式,所以我們將使用此模式來評估 Strve 的性能。

對以下操作進(jìn)行了基準(zhǔn)測試:

  • 創(chuàng)建行:頁面加載后創(chuàng)建 1,000 行的持續(xù)時間(無預(yù)熱)。
  • 替換所有行:替換表中所有 1,000 行的持續(xù)時間(5 次預(yù)熱迭代)。
  • 部分更新:對于具有 10,000 行的表,每 10 行更新一次文本(進(jìn)行 5 次預(yù)熱迭代)。
  • 選擇行:響應(yīng)單擊該行而突出顯示該行的持續(xù)時間。(5 次預(yù)熱迭代)。
  • 交換行:在包含 1,000 行的表中交換 2 行的時間。(5 次預(yù)熱迭代)。
  • 刪除行:刪除具有 1,000 行的表的行的持續(xù)時間。(5 次預(yù)熱迭代)。
  • 創(chuàng)建多行:創(chuàng)建 10,000 行的持續(xù)時間(無預(yù)熱)
  • 將行追加到大型表:在包含 10,000 行的表中添加 1,000 行的持續(xù)時間(無預(yù)熱)。
  • 清除行:清除填充有 10,000 行的表的持續(xù)時間。(無熱身)
  • 就緒內(nèi)存:頁面加載后的內(nèi)存使用情況。
  • 運(yùn)行內(nèi)存:添加 1,000 行后的內(nèi)存使用情況。
  • 更新內(nèi)存:1000 行的表點(diǎn)擊 5 次更新后的內(nèi)存使用情況。
  • 替換內(nèi)存:點(diǎn)擊 5 次創(chuàng)建 1000 行后的內(nèi)存使用情況。
  • 重復(fù)清除內(nèi)存:創(chuàng)建并清除 1,000 行 5 次后的內(nèi)存使用情況。
  • 更新內(nèi)存:1000 行的表點(diǎn)擊 5 次更新后的內(nèi)存使用情況。
  • 啟動時間:加載和解析 javascript 代碼以及渲染頁面的持續(xù)時間。
  • 持續(xù)交互:燈塔指標(biāo) TimeToConstantlyInteractive:悲觀 TTI - 當(dāng) CPU 和網(wǎng)絡(luò)都非??臻e時。(不再有超過 50 毫秒的 CPU 任務(wù))
  • 腳本啟動時間:燈塔指標(biāo) ScriptBootUpTtime:解析/編譯/評估所有頁面腳本所需的總毫秒數(shù)
  • 主線程工作成本:燈塔指標(biāo) MainThreadWorkCost:在主線程上工作所花費(fèi)的總時間包括樣式/布局等。
  • 總字節(jié)權(quán)重:燈塔指標(biāo) TotalByteWeight:加載到頁面中的所有資源的網(wǎng)絡(luò)傳輸成本(壓縮后)。

對于所有基準(zhǔn)測試,都會測量持續(xù)時間,包括渲染時間。

因?yàn)閖s-framework-benchmark是一個自動化測試的工具,只需要符合標(biāo)準(zhǔn)的代碼就可以進(jìn)行測試。Strve 支持 JSX 語法,所以我們將使用 JSX 語法來編寫測試代碼。

import { setData, createApp } from 'strve-js';
import { buildData } from './data.js';

let selected;
let rows = [];

function setRows(update = rows.slice()) {
  setData(
    () => {
      rows = update;
    },
    {
      name: TbodyComponent,
    }
  );
}

function add() {
  const data = rows.concat(buildData(1000));
  setData(
    () => {
      rows = data;
    },
    {
      name: TbodyComponent,
    }
  );
}

function remove(id) {
  rows.splice(
    rows.findIndex((d) => d.id === id),
    1
  );
  setRows();
}

function select(id) {
  setData(
    () => {
      selected = id;
    },
    {
      name: TbodyComponent,
    }
  );
}

function run() {
  setRows(buildData());
  selected = undefined;
}

function update() {
  for (let i = 0; i < rows.length; i += 10) {
    rows[i].label += ' !!!';
  }
  setRows();
}

function runLots() {
  setRows(buildData(10000));
  selected = undefined;
}

function clear() {
  setRows([]);
  selected = undefined;
}

function swapRows() {
  if (rows.length > 998) {
    const d1 = rows[1];
    const d998 = rows[998];
    rows[1] = d998;
    rows[998] = d1;
    setRows();
  }
}

function TbodyComponent() {
  return (
    <tbody>
      {rows.map((item) => (
        <tr class={item.id === selected ? 'danger' : ''} data-label={item.label} key={item.id}>
          <td class='col-md-1'>{item.id}</td>
          <td class='col-md-4'>
            <a onClick={() => select(item.id)}>{item.label}</a>
          </td>
          <td class='col-md-1'>
            <a onClick={() => remove(item.id)}>
              <span class='glyphicon glyphicon-remove' aria-hidden='true'></span>
            </a>
          </td>
          <td class='col-md-6'></td>
        </tr>
      ))}
    </tbody>
  );
}

function MainBody() {
  return (
    <fragment>
      <div class='jumbotron'>
        <div class='row'>
          <div class='col-md-6'>
            <h1>Strve-keyed</h1>
          </div>
          <div class='col-md-6'>
            <div class='row'>
              <div class='col-sm-6 smallpad'>
                <button type='button' class='btn btn-primary btn-block' id='run' onClick={run}>
                  Create 1,000 rows
                </button>
              </div>
              <div class='col-sm-6 smallpad'>
                <button
                  type='button'
                  class='btn btn-primary btn-block'
                  id='runlots'
                  onClick={runLots}
                >
                  Create 10,000 rows
                </button>
              </div>
              <div class='col-sm-6 smallpad'>
                <button type='button' class='btn btn-primary btn-block' id='add' onClick={add}>
                  Append 1,000 rows
                </button>
              </div>
              <div class='col-sm-6 smallpad'>
                <button
                  type='button'
                  class='btn btn-primary btn-block'
                  id='update'
                  onClick={update}
                >
                  Update every 10th row
                </button>
              </div>
              <div class='col-sm-6 smallpad'>
                <button type='button' class='btn btn-primary btn-block' id='clear' onClick={clear}>
                  Clear
                </button>
              </div>
              <div class='col-sm-6 smallpad'>
                <button
                  type='button'
                  class='btn btn-primary btn-block'
                  id='swaprows'
                  onClick={swapRows}
                >
                  Swap Rows
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
      <table class='table table-hover table-striped test-data'>
        <component $name={TbodyComponent.name}>{TbodyComponent()}</component>
      </table>
      <span class='preloadicon glyphicon glyphicon-remove' aria-hidden='true'></span>
    </fragment>
  );
}

createApp(() => MainBody()).mount('#main');

以下頁面就是將進(jìn)行基準(zhǔn)測試的頁面:

圖片圖片

我們大體看下測試過程,我們將使用動圖來展示頁面效果,這樣會覺得更加直觀。

動圖動圖

最終,Strve 通過了壓力測試!

圖片圖片

基準(zhǔn)測試結(jié)果

既然我們通過測試,我們就需要提交到j(luò)s-framework-benchmark官方項(xiàng)目中,進(jìn)行綜合評估,與全球其他框架進(jìn)行比較。

我們提交的 PR 在 2023 年 9 月 18 號被作者合并了。

圖片圖片

在接下來的時間里,作者進(jìn)行了一系列的測試。最終,Chrome 118 版本于上周發(fā)布,并在 GitHub 上公布了官方的測試結(jié)果。

圖片圖片

我們打開下面的網(wǎng)址,看下 Strve 的官方測試結(jié)果:

https://krausest.github.io/js-framework-benchmark/2023/table_chrome_118.0.5993.70.html

經(jīng)過查詢,全球 JavaScript 框架榜單中共有 142 個框架。

性能測試基準(zhǔn)分為三類:

  • 持續(xù)時間
  • 啟動指標(biāo)
  • 內(nèi)存分配

【持續(xù)時間】

在此測試基準(zhǔn)中,Strve 平均值 1.42,排名第 90 位。

React、Angular 和 Vue,平均值分別為1.40、1.38 和 1.20,分別排名第 85 位、第 83 位和第 51 位。

平均值越小,排名則越靠前。顏色越綠代表越優(yōu)。

持續(xù)時間持續(xù)時間

【啟動指標(biāo)】

在此測試基準(zhǔn)中,Strve 平均值 1.07。

React、Angular 和 Vue,平均值分別為 1.68、1.80 和 1.30。

平均值越小,排名則越靠前。顏色越綠代表越優(yōu)。

啟動指標(biāo)啟動指標(biāo)

【內(nèi)存分配】

在此測試基準(zhǔn)中,Strve 平均值 1.33。

React、Angular 和 Vue,平均值分別為 2.46、2.82 和 1.86。

平均值越小,排名則越靠前。顏色越綠代表越優(yōu)。

內(nèi)存分配內(nèi)存分配

新特性

我們在上面的測試中,可以看到 Strve 性能表現(xiàn)非常不錯。

這次我們發(fā)布的大版本號為 6.0.2,我們將這個具有里程碑意義的大版本命名為 Strve6,而 “Strve6,從芯出發(fā)!” 這個口號正是 Strve6 的核心理念。這一版本象征著我們從底層技術(shù)出發(fā),致力于為用戶提供更優(yōu)質(zhì)、更高效的開發(fā)體驗(yàn)。

此次版本我們在性能與體驗(yàn)之間做了權(quán)衡。在源碼層面,我們將普通 Diff 算法升級為 雙端 Diff 算法,大大提升了性能。另外,我們在用戶體驗(yàn)層面也做了很大的改進(jìn)。

這里,我們提到了雙端 Diff 算法,我們在面試中經(jīng)常提到這個概念,但是很少用到實(shí)際項(xiàng)目中去。那么,為了更好地理解雙端 Diff 算法如何提高性能,我們來看一個關(guān)于 Strve 簡單的示例。

我們來遍歷一個數(shù)組,并且每次點(diǎn)擊按鈕,往數(shù)組頭部中添加一個元素。

【普通 Diff 算法】

<script type="module">
  import {
    html,
    setData,
    createApp,
  } from 'https://cdn.jsdelivr.net/npm/strve-js@6.0.2/dist/strve.full-esm.js';

  const state = {
    arr: [1, 2],
    count: 3,
  };

  function useUnshift() {
    setData(() => {
      state.count++;
      state.arr.unshift(state.count);
    });
  }

  function App() {
    return html`
      <fragment>
        <button onClick=${useUnshift}>Unshift</button>
        <ul>
          ${state.arr.map((todo) => html`<li>${todo}</li>`)}
        </ul>
      </fragment>
    `;
  }

  const app = createApp(App);
  app.mount('#app');
</script>

我們可以看到右側(cè) DOM 樹,每次點(diǎn)擊按鈕,都會重新渲染整個列表。這樣是肯定耗損瀏覽器性能的。

動圖動圖

【雙端 Diff 算法】

<script type="module">
  import {
    html,
    setData,
    createApp,
  } from 'https://cdn.jsdelivr.net/npm/strve-js@6.0.2/dist/strve.full-esm.js';

  const state = {
    arr: [1, 2],
    count: 3,
  };

  function useUnshift() {
    setData(() => {
      state.count++;
      state.arr.unshift(state.count);
    });
  }

  function App() {
    return html`
      <fragment>
        <button onClick=${useUnshift}>Unshift</button>
        <ul>
          ${state.arr.map((todo) => html`<li key=${todo}>${todo}</li>`)}
        </ul>
      </fragment>
    `;
  }

  const app = createApp(App);
  app.mount('#app');
</script>

我們可以看到右側(cè) DOM 樹,每次點(diǎn)擊按鈕,僅添加必要的元素,而不是重新渲染整個列表。這是因?yàn)槲覀冊诿總€列表項(xiàng)中添加了 key 屬性,并且這個 key 是唯一的。key 這個特殊的 attribute 主要作為 Strve 的虛擬 DOM 算法提示,在比較新舊節(jié)點(diǎn)列表時用于識別 vnode。只要標(biāo)簽類型與 key 值都相等,就說明當(dāng)前元素可以被復(fù)用。

動圖動圖

熱門話題

文章接近尾聲,讓我們來回顧一下最近社區(qū)的幾個熱門話題。

  1. 為什么要開發(fā)這個框架?初衷是什么?

答:其實(shí),我的動機(jī)特別簡單,完全受 JSX 語法的影響。剛接觸 JSX 語法的時候,就被它那種魔法深深地吸引住了,可以在 JS 中寫 HTML。所以,我就想我自己可不可以也搞一個類似 JSX 語法的庫或者框架呢!一方面可以鍛煉自己的代碼能力,另一方面體驗(yàn)開發(fā)框架的整個流程,也方便我以后更全面的學(xué)習(xí)其他框架(Vue.js、React.js 等)。

做自己喜歡的事情是特別有意義的!

  1. 為什么選擇 Strve 作為框架的名字?

答:Strve 最初定位是可以將字符串轉(zhuǎn)換為視圖(用戶界面)的 JavaScript 庫,所以是由 String 和 View 兩個單詞縮減組成的新單詞。

  1. 跟前端熱門框架比較,是想超過它們嗎?

答:不是,我主要是想學(xué)習(xí)一下前端熱門框架的實(shí)現(xiàn)原理,然后自己實(shí)現(xiàn)一個框架。有一句話說得好:“只有站在巨人的肩膀上才能望得更遠(yuǎn)!”。

  1. 記得之前也寫過登上框架榜單的文章,這次為什么還要寫?

答:之前,Strve 測評的模式是使用"non-keyed"。現(xiàn)在,Strve 新的版本支持"keyed"模式,所以,我重新寫了一篇文章,來介紹 Strve 的新特性。

  1. Strve 6.0.2 版本發(fā)布,普通 Diff 算法升級為雙端 Diff 算法,可以簡單講下雙端 Diff 算法的概念嗎?

答:雙端 diff 算法就是頭尾指針向中間移動,分別判斷頭尾節(jié)點(diǎn)是否可以復(fù)用,如果沒有找到可復(fù)用的節(jié)點(diǎn)再去遍歷查找對應(yīng)節(jié)點(diǎn)的下標(biāo),然后移動。全部處理完之后要對剩下的節(jié)點(diǎn)進(jìn)行批量的新增和刪除。

  1. Strve 是個 JavaScript 庫還是 JavaScript 框架?

答:首先,我們來看下框架與庫有什么區(qū)別?庫更多是一個封裝好的特定的集合,提供給開發(fā)者使用,而且是特定于某一方面的集合(方法和函數(shù)),庫沒有控制權(quán),控制權(quán)在使用者手中,在庫中查詢需要的功能在自己的應(yīng)用中使用,我們可以從封裝的角度理解庫;框架顧名思義就是一套架構(gòu),會基于自身的特點(diǎn)向用戶提供一套相當(dāng)于叫完整的解決方案,而且控制權(quán)的在框架本身,使用者要找框架所規(guī)定的某種規(guī)范進(jìn)行開發(fā)。Strve 可以是框架,因?yàn)?Strve 提供了路由、插件等生態(tài)工具;Strve 也可以是庫, 因?yàn)?Strve 可以單獨(dú)作為一個渲染庫。

  1. Strve 你還要繼續(xù)維護(hù)下去嗎?

答:是的,我還會繼續(xù)維護(hù)下去,因?yàn)槲乙蚕雽W(xué)習(xí)下去,也希望能幫助到更多前端開發(fā)者。

關(guān)于

Strve 我是從 2021 年下半年開始開發(fā),到現(xiàn)在也快兩年了。在這兩年中,從一個之前只會 調(diào)用 API 的碼農(nóng),到現(xiàn)在可以獨(dú)立開發(fā)一個框架,讓我收獲了很多。學(xué)習(xí)了如何去分析一個框架的實(shí)現(xiàn)原理,也學(xué)習(xí)了如何去設(shè)計一個框架。

Strve 源碼倉庫:https://github.com/maomincoding/strve

Strve 中文文檔:https://maomincoding.gitee.io/strve-doc-zh/

如果大家覺得 Strve 還不錯,麻煩幫我點(diǎn)下 Star 吧,謝謝!

責(zé)任編輯:武曉燕 來源: 前端歷劫之路
相關(guān)推薦

2021-03-26 09:00:00

開發(fā)框架React

2016-11-14 15:51:42

JavaScriptAngular.jsReact.js

2018-01-24 07:58:47

框架組件技術(shù)棧開源

2020-11-17 09:17:58

框架組件基礎(chǔ)服務(wù)

2019-03-21 08:28:23

框架AngularVue

2023-07-17 06:26:45

Strve 項(xiàng)目JSX語法

2020-03-27 15:03:17

React JS框架開發(fā)平臺

2018-02-27 15:25:00

前端JavascriptAngular JS

2023-12-04 06:55:16

2010-01-15 09:43:20

IT企業(yè)騰訊

2021-08-15 21:36:00

框架開發(fā)JavaScript

2025-01-14 08:40:00

VueReactAngular

2020-02-25 09:00:00

React前端框架

2024-03-04 07:33:39

RemixReact框架

2020-10-12 17:33:32

JavaScript框架技術(shù)

2024-01-22 06:56:45

StrveJavaScrip模板字符串

2020-12-28 14:36:03

辦公

2022-05-17 17:18:40

Kite字節(jié)跳動微服務(wù)框架

2015-12-18 10:14:08

Angular框架時代

2021-04-21 14:22:08

前端開發(fā)技術(shù)
點(diǎn)贊
收藏

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