Jump to content

英文维基 | 中文维基 | 日文维基 | 草榴社区

Virtual DOM

From Wikipedia, the free encyclopedia

A virtual DOM is a lightweight JavaScript representation of the Document Object Model (DOM) used in declarative web frameworks such as React, Vue.js, and Elm.[1] Since generating a virtual DOM is relatively fast, any given framework is free to rerender the virtual DOM as many times as needed relatively cheaply. The framework can then find the differences between the previous virtual DOM and the current one (diffing), and only makes the necessary changes to the actual DOM (reconciliation).[2][3] While technically slower than using just vanilla JavaScript, the pattern makes it much easier to write websites with a lot of dynamic content, since markup is directly coupled with state.

Similar techniques include Ember.js' Glimmer and Angular's incremental DOM.[4][5]

History

[edit]

The JavaScript DOM API has historically been inconsistent across browsers, clunky to use, and difficult to scale for large projects. While libraries like jQuery aimed to improve the overall consistency and ergonomics of interacting with HTML,[6] it too was prone to repetitive code that didn't describe the nature of the changes being made well and decoupled logic from markup.

The release of AngularJS in 2010 provided a major paradigm shift in the interaction between JavaScript and HTML with the idea of dirty checking.[7] Instead of imperatively declaring and destroying event listeners and modifying individual DOM nodes, changes in variables were tracked and sections of the DOM were invalidated and rerendered when a variable in their scope changed. This digest cycle provided a framework to write more declarative code that coupled logic and markup in a more logical way.

While AngularJS aimed to provide a more declarative experience, it still required data to be explicitly bound to and watched by the DOM, and performance concerns were cited over the expensive process of dirty checking hundreds of variables.[8] To alleviate these issues, React was the first major library to adopt a virtual DOM in 2013, which removed both the performance bottlenecks (since diffing and reconciling the DOM was relatively cheap) and the difficulty of binding data (since components were effectively just objects).[9] Other benefits of a virtual DOM included improved security since XSS was effectively impossible and better extensibility since a component's state was entirely encapsulated.[10] Its release also came with the advent of JSX, which further coupled HTML and JavaScript with an XML-like syntax extension.

Following React's success, many other web frameworks copied the general idea of an ideal DOM representation in memory, such as Vue.js in 2014, which used a template compiler instead of JSX and had fine-grained reactivity built as part of the framework.[11]

In recent times, the virtual DOM has been criticized for being slow due to the additional time required for diffing and reconciling DOM nodes.[12] This has led to the development of frameworks without a virtual DOM, such as Svelte, and frameworks that edit the DOM in-place such as Angular 2.

Implementations

[edit]

React

[edit]

React pioneered the use of a virtual DOM to make components declaratively. Virtual DOM nodes are constructed using the createElement() function, but are often transpiled from JSX to make writing components more ergonomic.[13] In class-based React, virtual DOM nodes are returned from the render() function, while in functional hook-based components, the return value of the function itself serves as the page markup.

Vue.js

[edit]

Vue.js uses a virtual DOM to handle state changes, but is usually not directly interacted with; instead, a compiler is used to transform HTML templates into virtual DOM nodes as an implementation detail.[14] While Vue supports writing JSX and custom render functions,[15] it's more typical to use the template compiler since a build step isn't required that way.

Svelte

[edit]

Svelte does not have a virtual DOM, with its creator Rich Harris calling the virtual DOM "pure overhead".[16] Instead of diffing and reconciling DOM nodes at runtime, Svelte uses compile-time reactivity to analyze markup and generate JavaScript code that directly edits the HTML, drastically increasing performance.[17]

See also

[edit]

References

[edit]
  1. ^ "Beginning Elm". Elm Programming. Retrieved 2020-12-11.
  2. ^ "Virtual DOM and Internals – React". reactjs.org. Retrieved 2020-12-11.
  3. ^ "React: The Virtual DOM". Codecademy. Retrieved 2020-12-11.
  4. ^ google/incremental-dom, 2020-12-08, retrieved 2020-12-11
  5. ^ "React Virtual DOM vs Incremental DOM vs Ember's Glimmer: Fight". Auth0 - Blog. Retrieved 2020-12-11.
  6. ^ openjsf.org, OpenJS Foundation-. "The jQuery Object | jQuery Learning Center". Retrieved 2024-11-11.
  7. ^ "Make Your Own AngularJS, Part 1: Scopes And Digest". 2014-01-30. Archived from the original on 2014-01-30. Retrieved 2024-11-11.{{cite web}}: CS1 maint: bot: original URL status unknown (link)
  8. ^ Utley, Tatum. "The death of AngularJS and why you should care". blog.core10.io. Retrieved 2024-11-11.
  9. ^ JSConf (2013-10-30). Pete Hunt: React: Rethinking best practices -- JSConf EU. Retrieved 2024-11-11 – via YouTube.
  10. ^ "Why did we build React? – React Blog". legacy.reactjs.org. Retrieved 2024-11-11.
  11. ^ "Reactivity in Depth — Vue.js". v2.vuejs.org. Retrieved 2024-11-11.
  12. ^ Harris, Rich (2018-12-27). "Virtual DOM is pure overhead". svelte.dev. Retrieved 2024-11-11.
  13. ^ "Writing Markup with JSX – React". react.dev. Retrieved 2024-11-11.
  14. ^ "Rendering Mechanism". Vue.js.
  15. ^ "Render Functions & JSX". Vue.js.
  16. ^ Dec 27 2018, Rich Harris Thu (27 December 2018). "Virtual DOM is pure overhead". svelte.dev. Retrieved 2020-12-11.{{cite web}}: CS1 maint: numeric names: authors list (link)
  17. ^ Harris, Rich (2019-04-22). "Svelte 3: Rethinking reactivity". svelte.dev. Retrieved 2024-11-11.