虚拟dom添加虚拟dom_虚拟DOM缓慢。 认识记忆化的DOM

虚拟dom添加虚拟dom

by Sindre Osen Aarsaether

通过Sindre Osen Aarsaether

虚拟DOM缓慢。 符合已记忆的DOM。 (The Virtual DOM is slow. Meet the Memoized DOM.)

超越虚拟DOM和状态管理 (Moving beyond the Virtual DOM and State Management)

The virtual DOM was a fantastic innovation. It brought about a much more productive way of writing web applications by allowing us to write our views in a declarative manner.

虚拟DOM是一项了不起的创新。 通过允许我们以声明的方式编写视图,它带来了一种更加高效的Web应用程序编写方式。

This big benefit has little to do with performance of the initial render. Instead, it is the process of updating the DOM to reflect changes in your state has become much faster.

这个很大的好处与初始渲染的性能无关。 相反,它是更新DOM以反映您状态变化的过程,变得更快。

This process of bringing the DOM in sync with the state is often referred to as DOM reconciliation.

使DOM与状态同步的过程通常称为DOM协调 。

If we had an infinitely fast reconciler, we could vastly simplify our applications by rendering everything on every single frame. The state layer would never need to know about views at all — much less send out events and track which views need to react when certain parts of the state change. The view would always be in sync with the data, no matter what you threw at it.

如果我们有一个无限快的协调器,则可以通过在每个帧上渲染所有内容来极大地简化我们的应用程序。 状态层根本不需要了解视图,更不用说发出事件并跟踪在状态的某些部分发生变化时需要响应的视图。 无论您对视图进行什么操作,视图都将始终与数据保持同步。

Sadly, virtual DOM implementations are not infinitely fast. They are, in fact, surprisingly slow. Thankfully, many have jumped on the Immutability™ bandwagon, in which case the virtual DOM thanks you! Others wrap all state in observables (e.g. mobx), and keep track of which view depends on what state. This allows you to reconcile only parts of your view, but comes with its own set of drawbacks.

令人遗憾的是,虚拟DOM实现并非无限快。 实际上,它们出奇地慢。 值得庆幸的是,许多人跃跃欲试,在这种情况下,虚拟DOM谢谢您! 其他人则将所有状态都包裹在可观察对象(例如mobx)中,并跟踪哪个视图取决于哪个状态。 这使您只能协调部分视图,但有其自身的缺点。

The biggest issue is that we tend to decide how to manage our application state based on our view layer. What if we could get better performance in a world where the data layer and view layer don’t really know or care about each other?

最大的问题是,我们倾向于根据视图层决定如何管理应用程序状态。 如果在一个数据层和视图层并不真正了解或关心彼此的世界中,我们可以获得更好的性能怎么办?

认识记忆化的DOM (Meet the Memoized DOM)

Imba is a programming language for the web. It powers the interactive screencasting platform scrimba.com, of which I am the lead developer. Imba was born to make developing web applications fun again. It features a clean and readable syntax inspired by Ruby. It compiles to readable and performant JavaScript, and works inside the existing ecosystem.

Imba是一种网络编程语言。 它为交互式截屏平台scrimba.com提供了动力 ,我是其中的首席开发人员。 Imba的诞生再次使开发Web应用程序变得有趣。 它具有受Ruby启发的简洁易读的语法。 它可以编译为可读和高性能JavaScript,并可以在现有的生态系统中运行。

Besides a clean and readable syntax, the biggest benefit of Imba is that it truly treats DOM elements as first-class citizens, on a much deeper level than JSX. It allows you to write views declaratively, yet it does not use a virtual DOM. Instead, Imba compiles views to a memoized DOM, which turns out to be an order of magnitude faster.

除了简洁易懂的语法外,Imba的最大好处是,它在比JSX更深的层次上真正将DOM元素视为一流的公民。 它允许您声明性地编写视图,但不使用虚拟DOM。 取而代之的是,Imba将视图编译为已记忆的DOM,事实证明它快了一个数量级

这个怎么运作 (How it works)

The general idea is that we create lightweight wrappers around DOM elements, and compile declarative views to chains of setters, each modifying the underlying DOM directly.

通常的想法是,我们围绕DOM元素创建轻量级包装,并将声明式视图编译为设置器链,每个视图都直接修改基础DOM。

tag AppView    def render        <self>            <h1.title> "Welcome"            <p.desc .red=(Math.random > 0.5)> "Roulette"

The Imba view above will roughly compile into the following javascript:

上方的Imba视图将大致编译为以下javascript:

class AppView extends Imba.Tag {  render() {    var $ = this.$; // inline cache for tag    return this.setChildren($.$ = $.$ || [      Imba.tag('h1',$).flag('title').setText("Welcome"),      Imba.tag('p',$).flag('desc').setText("Roulette")    ]).synced(      $[1].flagIf('red',Math.random() > 0.5)    );  }}

This is a very simple example to illustrate the basic concept. During compilation we split creation and updates into separate branches. The first time render is called for an <AppView> the children will be created and static attributes will be set. On all subsequent calls the only real work we do is flip the className of our <p>. Albeit much more complex, the same concept is used for conditionals, loops, and everything else inside tag trees.

这是一个非常简单的示例,用于说明基本概念。 在编译过程中,我们将创建和更新分为单独的分支。 第一次为<AppVi ew>调用渲染时,将创建子代并设置静态属性。 在所有后续调用,我们要做的唯一的真正的工作是翻转的classNameØ fo乌尔<P>。 尽管非常复杂,但相同的概念用于条件树,循环以及标签树中的所有其他内容。

If you’re interested in how it really works I recommend reading this intro.

如果您对它的实际工作方式感兴趣,建议阅读此介绍 。

基准测试 (Benchmark)

React is fast, they said. React is fast enough, they said. React Fiber will be fast enough, they said.
他们说,React很快。 他们说,React足够快。 他们说,React Fiber将足够快。

Most benchmarks test things like “insert/shuffle/remove 1000 rows”. This gives little indication about real-world performance. When there are hundres of changes, most of the difference is eaten up by actual DOM mutations, repainting, etc. It fails to measure the most important metric.

大多数基准测试都会测试“插入/随机播放/删除1000行”之类的内容。 这几乎没有提供有关实际性能的指示。 当存在数百种变化时,大多数差异会被实际的DOM突变,重绘等吞噬掉。它无法衡量最重要的指标。

If you truly want to test the performance of DOM reconciliation, you need to look at how quickly the implementation brings the DOM in sync with the state, especially when there are few/no changes.

如果您确实想测试DOM协调的性能,则需要查看实现使DOM与状态同步的速度, 尤其是在更改很少/没有更改的情况下

So, to capture a realistic view of the reconciler performance, we could change a small part of the application state in each iteration, and then measure the time it takes to forcefully bring the view in sync with this changed state. The view should not be listening to any part of the state, and the state should not need to notify anyone whether it has changed.

因此,为了捕获协调器性能的真实视图,我们可以在每次迭代中更改应用程序状态的一小部分,然后测量将视图强制与此更改状态同步所需的时间。 该视图不应监听状态的任何部分,并且该状态不需要通知任何人它是否已更改。

This benchmark steps through a deterministic sequence of state alterations, doing at most one change per iteration. We are measuring the time it takes to reconcile the whole application view after:

该基准测试逐步执行确定性的状态更改序列, 每次迭代最多进行一次更改 。 在以下情况下,我们正在测量协调整个应用程序视图所需的时间:

  1. Toggling the completion of a task

    切换任务的完成
  2. Removing a task

    删除任务
  3. Inserting a task

    插入任务
  4. Renaming a task

    重命名任务
  5. Doing nothing

    什么也不做

结果 (Results)

Running the benchmark on an iMac (4GHz i7) yields the following results:

在iMac(4GHz i7)上运行基准测试会产生以下结果:

Safari 11 (Safari 11)

  • Imba 1.3: 360458 ops / sec

    Imba 1.3: 每秒360458次操作

  • React 16.2: 9752 ops / sec — 36.96x slower

    React 16.2: 9752操作/秒- 慢36.96倍

  • Vue 2.5: 8719 ops / sec — 41.34x slower

    Vue 2.5:每秒8719次操作- 慢41.34倍

Chrome65 (Chrome 65)

  • Imba 1.3: 282484 ops / sec

    Imba 1.3: 282484次操作/秒

  • React 16.2: 8882 ops / sec — 31.81x slower

    React 16.2: 8882次操作/秒- 慢31.81倍

  • Vue 2.5: 8103 ops / sec — 34.86x slower

    Vue 2.5:每秒8103次操作- 慢34.86倍

Firefox 58 (Firefox 58)

  • Imba 1.3: 234334 ops / sec

    Imba 1.3: 每秒234334次操作

  • React 16.2: 5075 ops / sec — 46.17x slower

    React 16.2: 5075次操作/秒- 慢46.17倍

  • Vue 2.5: 3119 ops / sec — 75.13x slower

    Vue 2.5:每秒3119次操作- 慢75.13倍

This seems outrageous right? Surely, it cannot be right.

这似乎太离谱了吧? 当然,这是不对的。

  • All implementations are really reconciling on every step.

    所有实现真正和解的每一步。

  • All implementations are blocking, synchronous, and deterministic.

    所有实现都是阻塞,同步和确定性的。
  • All implementations are performing the same amount of DOM mutations.

    所有实现都执行相同数量的DOM突变。
  • Yes, we are using the minified production build of React. The development version is 200x slower than Imba on the same test.

    是的,我们使用的是最小化的React生产版本。 在同一测试中,开发版本比Imba 慢200倍。

  • The memoized DOM creates practically no garbage during an iteration, uses less memory overall, and is conceptually very simple.

    备注DOM在迭代过程中几乎不产生垃圾,总体上使用较少的内存,并且从概念上讲非常简单。

All the implementations can probably be optimized more. I’m very happy to accept pull-requests at GitHub. To be clear, I have tremendous respect for what React has achieved, and I truly love Vue. Imba has taken a lot of inspiration from it. I suspect it should be possible to compile Vue templates using a similar approach, and would love for someone to give it a go!

所有实现可能都可以进行更多优化。 我很高兴在GitHub接受请求请求。 明确地说,我对React所取得的成就深表敬意,并且我真的很喜欢Vue。 Imba从中汲取了很多灵感。 我怀疑应该可以使用类似的方法来编译Vue模板,并且希望有人可以尝试一下!

剖析 (Profiling)

Let’s test the raw reconciler performance when there aren’t even any changes. This removes the time spent doing actual DOM mutations from the equation, and gives us a good picture about how much work is going on during reconciliation. The charted CPU profile from Chrome gives a visual indication of how much less work is done with the memoized DOM technique.

当没有任何变化时,让我们测试原始调节器性能。 这消除了从等式中进行实际DOM突变所花费的时间,并为我们提供了有关协调期间正在进行的工作量的清晰图片。 Chrome的图表CPU配置文件直观显示了使用DOM技术的工作量。

英巴1.3 (Imba 1.3)

React16.2 (React 16.2)

Vue 2.5 (Vue 2.5)

可以缩放吗? (Does it scale?)

“There are A LOT, and I mean, A LOT of small little projects that claim more speed, easier development, but on closer inspection usually lack very important features (such as module life cycle hooks) and, of course without them the performance is higher, but the flexibility to use those libraries beyond a todo list application is limited.”
“有很多,我的意思是,很多小的项目要求更快,更轻松的开发,但是仔细检查通常会缺少非常重要的功能(例如模块生命周期挂钩),当然,如果没有它们,性能是更高,但是在待办事项列表应用程序之外使用这些库的灵活性受到限制。”

This is a quote from someone who read through an early draft of this article, and I would like to tackle it head on. The performance difference is not limited to a simple test, quite the contrary. Imba has been used in production for several years at scrimba.com, but it is still not for the faint of heart. For most developers the massive ecosystems for Vue and React will be hard (and probably unwise) to leave behind. The Imba documentation still leaves a lot to be desired, but we are improving it every day.

这是从阅读本文初稿的人那里引用的,我想直接解决。 相反,性能差异不仅限于简单的测试。 Imba已在scrimba.com上用于生产多年,但仍不是出于胆小。 对于大多数开发人员而言,Vue和React的庞大生态系统将很难(可能不明智)落在后面。 Imba文档仍然有很多不足之处,但是我们每天都在改进它。

有关系吗? (Does it matter?)

I’m sure you’ve heard that React is fast enough. But fast enough for what? It doesn’t really matter if React was 15% faster, but with an order of magnitude improvement we can start to explore simpler ways to build applications.

我确定您已经听说过React足够快。 但是足够快吗? React是否快15%并不重要,但是随着数量级的提高,我们可以开始探索构建应用程序的更简单方法。

It’s not about the perceived speed, but about what it lets you do. At scrimba.com we don’t worry about keeping the view in sync with the state. We don’t worry about tracking when state has changed. Our data models are not observable. We just render. Whenever. And it’s liberating.

这与感知的速度无关,而与它可以做什么相关。 在scrimba.com,我们不必担心视图与状态保持同步。 我们不必担心状态更改的时间。 我们的数据模型是不可观察的。 我们只是渲染。 每当。 它正在解放。

翻译自: https://www.freecodecamp.org/news/the-virtual-dom-is-slow-meet-the-memoized-dom-bb19f546cc52/

虚拟dom添加虚拟dom

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/392986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编写一个字节数的rtu C语言校验程序,Modbus通信协议中CRC校验的快速C语言算法

Modbus通信协议中CRC校验的快速C语言算法2004年第11期            福 建 电 脑  63Modbus通信协议中CRC校验的快速C语言算法孟开元(西安石油大学计算机学院陕西西安710065)【摘 要】 本文主要讨论了Modbus通信协议的RTU帧格式中常用的错误校验方法,即循环冗…

leetcode1319. 连通网络的操作次数(并查集)

用以太网线缆将 n 台计算机连接成一个网络&#xff0c;计算机的编号从 0 到 n-1。线缆用 connections 表示&#xff0c;其中 connections[i] [a, b] 连接了计算机 a 和 b。 网络中的任何一台计算机都可以通过网络直接或者间接访问同一个网络中其他任意一台计算机。 给你这个…

Codeforces 600E Lomsat gelral (树上启发式合并)

题目链接 Lomsat gelral 占坑……等深入理解了再来补题解…… #include <bits/stdc.h>using namespace std;#define rep(i, a, b) for (int i(a); i < (b); i)typedef long long LL;const int N 600010;int n; int cc[N], col[N], sz[N], son[N]; LL ans[N];vect…

如何让CloudStack使用KVM创建Windows实例成功识别并挂载数据盘

问题产生背景&#xff1a; 使用CloudStack KVM组合进行资源池纳管工作&#xff0c;通过ISO镜像文件创建了两个模板&#xff1a; RHEL6U3 64位系统以及WindowsServer2008 R2 SP1 64位系统。然后通过模板创建实例&#xff0c;挂载外接存储&#xff0c;实例启动后&#xff0c;通过…

云计算openstack介绍

转载于:https://www.cnblogs.com/WIU1905/p/11107593.html

C语言Node lt T gt,c语言论坛填空;#includelt;stdio.hgt;# 爱问知识人

填空&#xff1b;#include #include #define N 6typedef struct node {int data;struct node *next;填空&#xff1b;#include #include #define N 6typedef struct node {int data;struct node *next;} NODE;void fun(NODE *h){ NODE *p, *q; int t;/**********found*********…

gitlab设置邮件服务器_如何设置您自己的一次性电子邮件服务器

gitlab设置邮件服务器by Oren Geva由Oren Geva 如何设置您自己的一次性电子邮件服务器 (How To Setup Your Own Disposable Email Server) Disposable email services are online services that provide temporary email addresses for registering or signing up on websites…

leetcode442. 数组中重复的数据

给定一个整数数组 a&#xff0c;其中1 ≤ a[i] ≤ n &#xff08;n为数组长度&#xff09;, 其中有些元素出现两次而其他元素出现一次。 找到所有出现两次的元素。 你可以不用到任何额外空间并在O(n)时间复杂度内解决这个问题吗&#xff1f; 示例&#xff1a; 输入: [4,3,2…

C语言基础注意点

一、基础知识篇 &#xff08;一&#xff09;关键字 1&#xff0c;存储类型 A、auto 声明自动变量&#xff0c;一般不使用 B、static 声明静态变量 C、extern 声明变量是在其他文件正声明&#xff08;可看做引用变量&#xff09; D、register 声明积有器变量 2、常用…

**加密解密基础、PKI及SSL、创建私有CA**

进程间通信 socket通信 客户端-->请求--> 路由转发 --> 服务端&#xff0c;取出资源 --> 封装为可响应给客户端的请求报文从接收请求端口发出 SSL/TLS协议的实现 OpenSSL OpenSSL程序组件 1234[rootlocalhost CA]# rpm -ql openssl /usr/lib/libcrypto.so.10 //加…

json 文件打读取

1。获取文件路径 /** BookController.class.getClassLoader().getResource("static/json/book_nav.json").getPath() 获取当期运行时的项目json文件路径*/JSONObject json JsonResourceUtils.getJsonObjFromResource(BookController.class.getClassLoader().getReso…

16F877A和24C02通信汇编语言,pic单片机IIC通信读24C02程序例 16F877A 主频4M

#define _iic_h_//pic单片机IIC通信初始化函数声明void iiccsh(void);//pic单片机IIC通信读外围设备函数声明//功能&#xff1a;传送一个8位地址&#xff0c;返回一个8位数据unsigned char iicread(unsigned char data);//pic单片机IIC通信给外围器件发送函数声明//功能&#x…

如何从XMLHttpRequest创建自定义获取API

What is your worst nightmare?你最可怕的噩梦是什么&#xff1f; That sounded dark, but it’s not a rhetorical question. I really want to know because I am about to tell you mine. Along the way, we will learn some things like how the fetch API works and als…

leetcode637. 二叉树的层平均值

给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。示例 1&#xff1a;输入&#xff1a;3/ \9 20/ \15 7 输出&#xff1a;[3, 14.5, 11] 解释&#xff1a; 第 0 层的平均值是 3 , 第1层是 14.5 , 第2层是 11 。因此返回 [3, 14.5, 11] 。/*** Definition for a b…

5.3 上午

观看英语课程——《恋练有词》 学习Linux 转载于:https://www.cnblogs.com/bgd140206110/p/6801164.html

AD库转换为KiCAD库的方法

AD库转换为KiCAD库的方法 参照博主另外一篇文档&#xff1a; AD转换为KiCAD的方法&#xff0c;点击此处转载于:https://www.cnblogs.com/zhiqiang_zhang/p/11109560.html

遗传算法求解装箱问题c语言,求解装箱问题的遗传算法-南昌航空大学期刊网.pdf...

求解装箱问题的遗传算法-南昌航空大学期刊网1998 2 Journal of Nanchang Institute of Aeronautical Technology 21998方 平    李 娟( 南昌航空工业学院)  ( 西北工业大学): ( Bin Packing) ,, , D( irst it De-creasing) ,: ; ; ;: TP301. 6( )( Bin Packing) , :1 2 …

mysql索引随记

为什么80%的码农都做不了架构师&#xff1f;>>> 先了解下Btree&#xff1a;https://my.oschina.net/u/3646190/blog/1593094 为什么每个数据项&#xff0c;即索引字段要尽量的小&#xff0c;比如int占4字节&#xff0c;要比bigint8字节少一半&#xff1f; 通过上面…

leetcode79. 单词搜索(回溯算法)

给定一个二维网格和一个单词&#xff0c;找出该单词是否存在于网格中。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。 示例: board [ [‘A’,‘…

react钩子_迷上了钩子:如何使用React的useReducer()

react钩子So the React Conference just happened and as always something new happened. Hooks happened! The React team talked about suspense, lazy loading, concurrent rendering, and hooks :D.因此&#xff0c;React会议刚刚发生&#xff0c;并且一如既往地发生了一些…