¡Finalmente llegué a la lista de marcos JS y solo estoy 4 detrás de React!

prefacio

Como era de esperar, mi marco JavaScript desarrollado de forma independiente Strve.js marcó el comienzo de una versión principal 5.6.2. Ha pasado casi medio año desde que se lanzó la última versión principal esta vez, ¿por qué no se ha lanzado una nueva versión principal durante tanto tiempo? Es principalmente para estudiar cómo Strve.js admite componentes de un solo archivo, lo que hace que las indicaciones inteligentes del código y el formato del código sean más amigables. También se lanzó antes Strve SFC, pero debido a las engorrosas reglas gramaticales y varias razones para compilar en tiempo de ejecución, renuncié resueltamente a continuar con la investigación de este programa. Y esta versión 5.6.2resuelve con éxito los problemas de las solicitudes de código inteligente y el formato de código amigable, y también agrega muchas funciones de guinda al pastel, todo lo cual se debe a nuestro exitoso soporte de la sintaxis JSX en esta versión. Los amigos que están familiarizados con React saben que la sintaxis JSX es muy flexible. Y una característica importante de Strve.js es la operación flexible de los bloques de código. Podemos entender los bloques de código aquí como funciones, y la sintaxis JSX también satisface nuestras necesidades en ciertos escenarios.

Entonces, ¿cómo usamos la sintaxis JSX en el proyecto Strve? CreateStrveAppTenemos plantillas preestablecidas en la herramienta de creación de proyectos de Strve , puede elegir strve-jsxuna strve-jsx-appsplantilla. Después de usar CreateStrveApp para compilar el proyecto Strve, lo encontraremos y se instalará al mismo tiempo. babelPluginStrveEsto babelPluginJsxToStrvese debe a que necesitamos usar babelPluginJsxToStrve para convertir JSX en plantillas de etiquetas, y luego usar babelPluginStrve para convertir plantillas de etiquetas en DOM virtual. y luego lograr vistas de actualización diferenciadas.

intentar

Ahora que he lanzado una versión grande, estoy bastante satisfecho personalmente. Entonces, ¿cómo lo promociono a continuación? Después de todo, la auto-recomendación a veces es muy significativa. Entonces, planeo js-framework-benchmarkevaluar el desempeño a través de este proyecto.

¿Qué es js-framework-benchmark? Aquí presentamos brevemente js-framework-benchmark, que es un proyecto para comparar el rendimiento de los marcos de JavaScript. Su objetivo es evaluar el rendimiento de diferentes marcos en varios escenarios mediante la realización de una serie de pruebas comparativas. Estos puntos de referencia incluyen la representación de grandes cantidades de datos, la actualización de datos, el manejo de componentes de interfaz de usuario complejos y más. Al ejecutar estos puntos de referencia, es posible comparar el rendimiento de diferentes marcos en varios aspectos y ayudar a los desarrolladores a elegir el mejor marco para sus necesidades. El proyecto js-framework-benchmark proporciona un conjunto de referencia de varios marcos de JavaScript populares. Estos marcos incluyen Angular, React, Vue.js, Ember.js y más. Cada marco se ejecuta en el mismo escenario de prueba y se registran las métricas de rendimiento, como el tiempo de ejecución y el uso de la memoria. Al comparar estas métricas, se pueden dibujar las diferencias de rendimiento de diferentes marcos. El objetivo de este proyecto es ayudar a los desarrolladores a comprender las características de rendimiento de diferentes marcos de JavaScript para que puedan tomar decisiones más informadas al elegir un marco. Al mismo tiempo, también puede promover la competencia entre los desarrolladores de marcos y promover la mejora continua y la optimización del marco.

Entonces, ejecutaremos este proyecto con la mentalidad de intentarlo.

prueba

Ingresamos js-framework-benchmarka la página de inicio de Github, y luego clonedescargamos este proyecto.

git clone https://github.com/krausest/js-framework-benchmark.git

Luego, clonecuando seamos locales, abra README.mdel archivo para averiguar cómo evaluar el marco. Después de una descripción general, llegamos a la conclusión de que mediante el uso de nuestro propio marco para completar los js-framework-benchmarkelementos de práctica prescritos.

01.png

那么,我们就照着其他框架已经开发完成的示例进行开发吧!在开发之前,我们必须要了解js-framework-benchmark 中有两种模式。一种是keyed,另一种是non-keyed。在 js-framework-benchmark 中,"keyed" 模式是指通过给数据项分配一个唯一标识符作为 "key" 属性,从而实现数据项与 DOM 节点之间的一对一关系。当数据发生变化时,与之相关联的 DOM 节点也会相应更新。而 "non-keyed" 模式是指当数据项发生变化时,可能会修改之前与其他数据项关联的 DOM 节点。因为 Strve 暂时没有类似唯一标识符这种特性,所以我们选择non-keyed模式。

我们打开项目下/frameworks/non-keyed文件夹,找一个案例框架看一下它们开发的项目,我们选择 Vue 吧! 我们根据它开发的样例迁移到自己的框架中去。为了测试新版本,我们将使用JSX语法进行开发。

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

let selected = undefined;
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 $key>
      {rows.map((item) => (
        <tr
          class={item.id === selected ? "danger" : ""}
          data-label={item.label}
          $key
        >
          <td class="col-md-1" $key>
            {item.id}
          </td>
          <td class="col-md-4">
            <a onClick={() => select(item.id)} $key>
              {item.label}
            </a>
          </td>
          <td class="col-md-1">
            <a onClick={() => remove(item.id)} $key>
              <span
                class="glyphicon glyphicon-remove"
                aria-hidden="true"
              ></span>
            </a>
          </td>
          <td class="col-md-6"></td>
        </tr>
      ))}
    </tbody>
  );
}

function MainBody() {
  return (
    <>
      <div class="jumbotron">
        <div class="row">
          <div class="col-md-6">
            <h1>Strve-non-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>
    </>
  );
}

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

其实,我们虽然使用了JSX语法,但是你会发现有很多特性并不与JSX语法真正相同,比如我们可以直接使用 class 去表示样式类名属性,而不能使用 className 表示。

评估案例项目开发完成了,我们下一步就要测试一下项目是否符合评估标准。

npm run bench non-keyed/strve

02.gif

测试标准包括:

  • create rows:创建行,页面加载后创建 1000 行的持续时间(无预热)

  • replace all rows:替换所有行,替换表中所有 1000 行所需的时间(5 次预热循环)。该指标最大的价值就是了解当页面上的大部分内容发生变化时库的执行方式。

  • partial update:部分更新,对于具有 10000 行的表,每 10 行更新一次文本(进行 5 次预热循环)。该指标是动画性能和深层嵌套数据结构开销等方面的最佳指标。

  • select row:选择行,在单击行时高亮显示该行所需的时间(进行 5 次预热循环)。

  • swap rows:交换行,在包含 1000 行的表中交换 2 行的时间(进行 5 次预热迭代)。

  • remove row:删除行,在包含 1,000 行的表格上移除一行所需的时间(有 5 次预热迭代),该指标可能变化最少,因为它比库的任何开销更多地测试浏览器布局变化(因为所有行向上移动)。

  • create many rows:创建多行,创建 10000 行所需的时间(没有预热),该指标更容易受到内存开销的影响,并且对于效率较低的库来说,扩展性会更差。

  • append rows to large table:追加行到大型表格,在包含 10000 行的表格上添加 1000 行所需的时间(没有预热)。

  • clear rows:清空行,清空包含 10000 行的表格所需的时间(没有预热),该指标说明了库清理代码的成本,内存使用对这个指标的影响很大,因为浏览器需要更多的 GC。

最终,Strve 顶住了压力,通过了测试。

03.gif

看到了successful run之后,觉得特别开心!那种成就感是任何事物都难以代替的。

跑分

我们既然通过了测试,那么下一步我们将与前端两大框架Vue、React进行比较跑分,我们先在我自己本地环境上跑一下,看一下效果。

性能测试基准分为三类:

  • 持续时间
  • 启动指标
  • 内存分配

持续时间

04.png

启动指标

05.png

内存分配

06.png

总体而言,我感觉还不错,毕竟跟两个大哥在比较。到这里我还是觉得不够,跟其他框架比比呢!

提交

只要框架通过了测试,并且按照提交PR的规定提交,是可以被选录到 js-framework-benchmark 中去的。

好,那我们就去试试!

07.png

又一个比较有成就感的事!提交的PR被作者合并了!

成绩单

我迫不及待的去榜单上看下我的排名,会不会垫底啊!

因为浏览器版本发布的时差问题,暂时 Official results ( 官方结果 ) 还没有发布最新结果,我们可以先来 Snapshot of the results ( 快照结果 ) 中查看。

我们打开下方网址就可以看到JS框架的最新榜单了。

https://krausest.github.io/js-framework-benchmark/current.html

我们在持续时间这个类别下从后往前找,目前63个框架我居然排名 50 名,并且大名鼎鼎的 React 排名45名。

08.png

我们先不激动,我们再看下启动指标类别。Strve 平均分数是1.04,我看了看好几个框架分数是1.04。Strve 可以排到前8名。

09.png

我们再稳一下,继续看内存分配这个类别。Strve 平均分数是1.40,Strve 可以排到前12名。

10.png

意义

js-framework-benchmark 的测试结果是相对准确的,因为它是针对同样的测试样本和基准测试情境进行比较,可以提供框架之间的相对性能比较。然而,需要注意的是,这个测试结果也只是反映了测试条件下的性能表现。框架实际的性能可能还会受到很多方面的影响。 此外,js-framework-benchmark 测试结果也不应该成为选择框架的唯一指标。在选择框架时,还需要考虑框架的生态、开发效率、易用性等多方面因素,而不仅仅是性能表现。

虽然,Strve 跟 React 比较是有点招黑,但是不妨这样想,榜样的力量是巨大的!只有站在巨人的肩膀上才能望得更远!

Strve 要走的路还有很长,入选JS框架榜单使我更加明确了方向。我觉得做自己喜欢做得事情,这样才会有意义!

加油

Strve 要继续维护下去,我也会不断学习,继续精进。

Strve 源码仓库:github.com/maomincodin…

Strve 中文文档:maomincoding.gitee.io/strve-doc-z…

谢谢大家的阅读!如果大家觉得Strve不错,麻烦帮我点下Star吧!

Supongo que te gusta

Origin juejin.im/post/7256250499280158776
Recomendado
Clasificación