虚拟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

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

  1. VirtualBox中虚拟Ubuntu添加新的虚拟硬盘

    VirtualBox中装好Ubuntu后,发现硬盘空间不够使用 了.以下是搜集整理的解决办法: 1. 添加新硬盘 设置 -> Storage -> SATA控制器->右击,选择&qu ...

  2. 虚拟dom_通过编写简易虚拟DOM,来学习虚拟DOM 的原理

    茫茫人海中与你相遇 相信未来的你不会很差 作者:前端小智 来源:https://segmentfault.com/a/1190000037599333 要构建自己的虚拟DOM,需要知道两件事.你甚至不 ...

  3. 虚拟dom_虚拟DOM与dom diff

    什么是虚拟DOM 虚拟DOM是一颗以JavaScript对象(node节点)作为基础的树,用对象属性来描述节点,他是对真实DOM的抽象,通过一些列操作使这棵树映射到真实环境上 虚拟dom就是能代表DO ...

  4. javascript --- 将DOM结构转换成虚拟DOM 虚拟DOM转换成真实的DOM结构

    虚拟DOM的实现 使用虚拟DOM的原因: 减少回流与重绘 将DOM结构转换成对象保存到内存中 <img /> => { tag: 'img'} 文本节点 => { tag: u ...

  5. [react] 什么是虚拟dom?虚拟dom比操作原生dom要快吗?虚拟dom是如何转变成真实dom并渲染到页面的?

    壹 ❀ 引 虚拟DOM(Virtual DOM)在前端领域也算是老生常谈的话题了,若你了解过vue或者react一定避不开这个话题,因此虚拟DOM也算是面试中常问的一个点,那么通过本文,你将了解到如下 ...

  6. lnmp环境如何添加域名和虚拟主机

    2019独角兽企业重金招聘Python工程师标准>>> 当你在centOS系统中安装设置lnmp环境之后,接下来要做的就是添加域名和虚拟主机了.提示:如果输入有错误需要删除时,可以按 ...

  7. LNMP添加、删除虚拟主机及伪静态使用教程

    一般情况下每个虚拟主机就是一个网站,网站一般通过域名进行访问. LNMP 1.2的网站添加过程和LNMP 1.1的基本类似,但是增加了FTP和数据库的创建.LNMP1.2的防跨目录也由原来在php.i ...

  8. 玩转PDF虚拟打印机添加文本功能

    pdfFactory Pro是一款非常容易上手的虚拟打印机,利用这款虚拟打印机,可以完成很多特殊的任务,如文件加密.添加文本.快照等等. 相信很多小伙伴们在打印的时候突然想起来某些地方需要" ...

  9. 编写一键备份MYSQL数据库脚本; 一键Nginx虚拟主机添加、删除脚本;

    1.编写一键备份MYSQL数据库脚本: 1)支持任意单个或者多个数据库的备份: 2)支持多个数据库.所有库备份: 思路: 备份mysql数据库命令 #到处mysql所有库的数据到mysql_all.s ...

最新文章

  1. C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例
  2. vscode使用教程python-用VSCode写python的正确姿势
  3. stm32无法进入串口接收中断
  4. 吴恩达机器学习(第一章)——初识机器学习
  5. 怎么连接屏幕_触控一体机怎么实现无线投屏功能
  6. Anaconda是什么?Anconda下载安装教程 - Python零基础入门教程
  7. 摩拜单车又涨价了!真的要骑不起了
  8. ios 对日期的处理(包括计算昨天时间、明天时间)
  9. 村上隆首场中国直播,火山同传打造“影院级字幕”
  10. php如何安装pdflib,使用pdflib及PHP生成pdf文件(文件内容中有中文)的方法
  11. 即时语音提示软件php,即时语音提示校对专家
  12. eoLinker-API_Shop_知识类API调用的代码示例合集:驾考题库、ISBN书号查询、万年历查询等...
  13. TOGAF ADM指导
  14. 自考-计算机程序设计-1-概论
  15. 同城滴滴啦啦啦啦啦啦啦啦
  16. 初创企业购买企业邮箱_应用创意可为2019年及以后的初创企业带来收入
  17. 「备忘录」MacOS终端获取电脑硬件信息序列号UUID
  18. 判断一点是否在多边形内(附Java实现代码)
  19. 2021年化工自动化控制仪表及化工自动化控制仪表模拟考试
  20. Linux查看系统信息命令总结

热门文章

  1. 一招彻底帮你搞定HashMap源码,项目实战
  2. Java-进阶:Java-File--IO—1
  3. linux下安装nginx1.10,Linux(RHEL7.0)下安装nginx-1.10.2(示例代码)
  4. python基础03——数据类型string
  5. 老生常谈:抽象工厂模式
  6. BZOJ 1176: [Balkan2007]Mokia
  7. spring boot mybatis拦截器
  8. Logic-算法-八个箱子找一个最轻的
  9. 天津海运[600751]股票
  10. 《在你身边,为你设计》-哪位知道下载、在线阅读地址啊?