Top Related Projects
⚛️ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.
The library for web and native user interfaces.
This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
web development for the rest of us
A rugged, minimal framework for composing JavaScript behavior in your markup.
:fire: An extremely fast, React-like JavaScript library for building modern user interfaces
Quick Overview
Morphdom is a lightweight JavaScript library for efficiently updating the DOM by comparing and morphing an existing DOM tree to match a new DOM tree. It aims to provide a fast and efficient way to update the DOM without the need for a virtual DOM, making it suitable for various web applications and frameworks.
Pros
- Lightweight and fast performance compared to virtual DOM-based solutions
- Works with plain HTML and JavaScript, making it framework-agnostic
- Preserves existing DOM nodes when possible, reducing unnecessary reflows and repaints
- Supports custom element handling and attribute updates
Cons
- May not be as feature-rich as some full-fledged UI libraries or frameworks
- Requires manual DOM manipulation, which can be error-prone for complex applications
- Limited documentation and examples compared to more popular libraries
- May have a steeper learning curve for developers used to declarative UI frameworks
Code Examples
- Basic usage:
import morphdom from 'morphdom';
const oldNode = document.getElementById('app');
const newHtml = '<div id="app"><h1>Updated Content</h1></div>';
morphdom(oldNode, newHtml);
- Using a custom function to create the new DOM:
import morphdom from 'morphdom';
const oldNode = document.getElementById('app');
const newNode = document.createElement('div');
newNode.innerHTML = '<h1>New Content</h1>';
morphdom(oldNode, newNode);
- Using options to customize behavior:
import morphdom from 'morphdom';
const oldNode = document.getElementById('app');
const newHtml = '<div id="app"><h1>Updated Content</h1></div>';
morphdom(oldNode, newHtml, {
onBeforeElUpdated: function(fromEl, toEl) {
if (fromEl.tagName === 'INPUT') {
const isSame = fromEl.value === toEl.value;
if (isSame) {
return false; // don't update this element
}
}
return true;
}
});
Getting Started
- Install morphdom using npm:
npm install morphdom
- Import and use morphdom in your JavaScript file:
import morphdom from 'morphdom';
const oldNode = document.getElementById('app');
const newHtml = '<div id="app"><h1>Hello, Morphdom!</h1></div>';
morphdom(oldNode, newHtml);
This will update the existing DOM to match the new HTML structure efficiently.
Competitor Comparisons
⚛️ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.
Pros of Preact
- Full-featured UI library with component-based architecture
- Smaller bundle size (3KB) compared to React, suitable for performance-critical applications
- Compatible with React ecosystem, making it easy to migrate existing React projects
Cons of Preact
- Less extensive documentation and community support compared to morphdom
- May introduce unnecessary complexity for simple DOM manipulation tasks
- Steeper learning curve for developers not familiar with React-like libraries
Code Comparison
morphdom:
var morphdom = require('morphdom');
var el1 = document.createElement('div');
el1.innerHTML = 'Hello World';
var el2 = document.createElement('div');
el2.innerHTML = 'Hello Morphdom';
morphdom(el1, el2);
Preact:
import { h, render } from 'preact';
const App = () => <div>Hello Preact</div>;
render(<App />, document.body);
Summary
morphdom is a lightweight library focused on efficient DOM diffing and patching, while Preact is a more comprehensive UI library with a virtual DOM implementation. morphdom is better suited for simple DOM updates, whereas Preact offers a complete component-based architecture for building complex user interfaces. The choice between the two depends on the project's requirements and the developer's familiarity with React-like libraries.
The library for web and native user interfaces.
Pros of React
- Comprehensive ecosystem with extensive libraries and tools
- Virtual DOM for efficient updates and rendering
- Component-based architecture for reusable UI elements
Cons of React
- Steeper learning curve, especially for beginners
- Larger bundle size, potentially impacting initial load times
- Requires additional tools and setup for optimal performance
Code Comparison
React:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(element, document.getElementById('root'));
Morphdom:
var morphdom = require('morphdom');
var el1 = document.createElement('div');
el1.innerHTML = 'Hello World';
var el2 = document.createElement('div');
el2.innerHTML = 'Hello Universe';
morphdom(el1, el2);
Key Differences
- React uses a component-based approach, while Morphdom focuses on efficient DOM updates
- React requires JSX and a build step, Morphdom works with plain JavaScript
- React manages state and props, Morphdom simply updates the DOM based on changes
Use Cases
- React: Complex, interactive web applications with frequent updates
- Morphdom: Simpler applications or when integrating with existing vanilla JavaScript projects
Performance Considerations
- React excels in large-scale applications with frequent updates
- Morphdom can be more efficient for smaller applications or when fine-grained control over DOM updates is needed
This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
Pros of Vue
- Comprehensive framework with a full ecosystem for building complex applications
- Reactive data binding and component-based architecture for efficient UI updates
- Extensive documentation and large community support
Cons of Vue
- Steeper learning curve for beginners compared to simpler DOM manipulation libraries
- Potentially heavier bundle size for small projects that don't require a full framework
- May introduce unnecessary complexity for simple DOM updates
Code Comparison
Vue:
new Vue({
el: '#app',
data: { message: 'Hello Vue!' },
template: '<div>{{ message }}</div>'
})
morphdom:
var morphdom = require('morphdom');
var el = document.getElementById('app');
morphdom(el, '<div>Hello morphdom!</div>');
Key Differences
- Vue is a full-fledged framework, while morphdom is a lightweight library for DOM diffing and patching
- Vue uses a virtual DOM and reactive data binding, whereas morphdom directly manipulates the real DOM
- Vue offers a component-based architecture, while morphdom focuses solely on efficient DOM updates
Use Cases
- Vue: Large-scale applications, single-page applications, and projects requiring a comprehensive framework
- morphdom: Simple DOM updates, server-side rendering, and scenarios where minimal overhead is crucial
Both libraries have their strengths, and the choice depends on the specific requirements of your project, such as complexity, performance needs, and development team expertise.
web development for the rest of us
Pros of Svelte
- Comprehensive framework with built-in state management and reactivity
- Compiles to highly optimized vanilla JavaScript
- Smaller bundle sizes and better runtime performance
Cons of Svelte
- Steeper learning curve due to its unique syntax and concepts
- Smaller ecosystem compared to more established frameworks
- Limited server-side rendering capabilities out of the box
Code Comparison
Svelte:
<script>
let count = 0;
function increment() {
count += 1;
}
</script>
<button on:click={increment}>
Clicks: {count}
</button>
Morphdom:
const button = document.createElement('button');
let count = 0;
button.addEventListener('click', () => {
count += 1;
morphdom(button, `<button>Clicks: ${count}</button>`);
});
document.body.appendChild(button);
Svelte provides a more declarative approach with built-in reactivity, while Morphdom requires manual DOM manipulation and updates. Svelte's syntax is more concise and easier to read, but Morphdom offers more flexibility for integrating with existing JavaScript codebases. Svelte compiles to efficient JavaScript, whereas Morphdom is a runtime library for efficient DOM updates.
A rugged, minimal framework for composing JavaScript behavior in your markup.
Pros of Alpine
- Provides a complete lightweight framework for building interactive UIs
- Offers declarative syntax and directives for easy DOM manipulation
- Includes built-in state management and reactivity
Cons of Alpine
- Larger bundle size compared to Morphdom's focused approach
- Steeper learning curve due to its framework-like nature
- May be overkill for simple DOM updates
Code Comparison
Alpine:
<div x-data="{ open: false }">
<button @click="open = !open">Toggle</button>
<span x-show="open">Content</span>
</div>
Morphdom:
import morphdom from 'morphdom';
const newDOM = document.createElement('div');
newDOM.innerHTML = '<span>Updated Content</span>';
morphdom(existingElement, newDOM);
Summary
Alpine is a lightweight JavaScript framework that provides a complete solution for building interactive UIs with declarative syntax and built-in reactivity. It offers more features out of the box but comes with a larger bundle size and steeper learning curve.
Morphdom, on the other hand, is a focused library for efficiently updating DOM elements. It's smaller in size and simpler to use for basic DOM updates but lacks the framework features of Alpine.
Choose Alpine for more complex interactive UIs, and Morphdom for simple, efficient DOM updates in existing projects.
:fire: An extremely fast, React-like JavaScript library for building modern user interfaces
Pros of Inferno
- Full-featured JavaScript library for building user interfaces, offering a complete solution
- Extremely fast performance, often outperforming React in benchmarks
- Smaller bundle size compared to React, making it suitable for lightweight applications
Cons of Inferno
- Smaller community and ecosystem compared to more established libraries
- Less documentation and learning resources available
- May require more setup and configuration for complex applications
Code Comparison
Inferno:
import { render } from 'inferno';
function MyComponent({ name }) {
return <div>Hello, {name}!</div>;
}
render(<MyComponent name="World" />, document.getElementById('app'));
Morphdom:
import morphdom from 'morphdom';
const oldNode = document.getElementById('app');
const newNode = document.createElement('div');
newNode.innerHTML = 'Hello, World!';
morphdom(oldNode, newNode);
Key Differences
- Inferno is a complete UI library, while Morphdom is a focused DOM diffing utility
- Inferno uses a virtual DOM approach, whereas Morphdom directly manipulates the real DOM
- Inferno provides a React-like API, making it easier for React developers to adopt
- Morphdom is more lightweight and can be easily integrated into existing projects without a full framework commitment
Both libraries aim to improve performance in web applications, but they approach the problem from different angles. Inferno offers a full-featured solution, while Morphdom provides a specialized tool for efficient DOM updates.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
morphdom
Lightweight module for morphing an existing DOM node tree to match a target DOM node tree. It's fast and works with the real DOMâno virtual DOM needed!
This module was created to solve the problem of updating the DOM in response to a UI component or page being rerendered. One way to update the DOM is to simply toss away the existing DOM tree and replace it with a new DOM tree (e.g., myContainer.innerHTML = newHTML
). While replacing an existing DOM tree with an entirely new DOM tree will actually be very fast, it comes with a cost. The cost is that all of the internal state associated with the existing DOM nodes (scroll positions, input caret positions, CSS transition states, etc.) will be lost. Instead of replacing the existing DOM tree with a new DOM tree we want to transform the existing DOM tree to match the new DOM tree while minimizing the number of changes to the existing DOM tree. This is exactly what the morphdom
module does! Give it an existing DOM node tree and a target DOM node tree and it will efficiently transform the existing DOM node tree to exactly match the target DOM node tree with the minimum amount of changes.
morphdom
does not rely on any virtual DOM abstractions. Because morphdom
is using the real DOM, the DOM that the web browser is maintaining will always be the source of truth. Even if you have code that manually manipulates the DOM things will still work as expected. In addition, morphdom
can be used with any templating language that produces an HTML string.
The transformation is done in a single pass of both the original DOM tree and the target DOM tree and is designed to minimize changes to the DOM while still ensuring that the morphed DOM exactly matches the target DOM. In addition, the algorithm used by this module will automatically match up elements that have corresponding IDs and that are found in both the original and target DOM tree.
Support for diffing the real DOM with a virtual DOM was introduced in v2.1.0
. Virtual DOM nodes are expected to implement the minimal subset of the real DOM API required by morphdom
and virtual DOM nodes are automatically upgraded real DOM nodes if they need to be moved into the real DOM. For more details, please see: docs/virtual-dom.md.
Usage
First install the module into your project:
npm install morphdom --save
NOTE: Published npm packages:
dist/morphdom-umd.js
dist/morphdom-esm.js
The code below shows how to morph one <div>
element to another <div>
element.
var morphdom = require('morphdom');
var el1 = document.createElement('div');
el1.className = 'foo';
var el2 = document.createElement('div');
el2.className = 'bar';
morphdom(el1, el2);
expect(el1.className).to.equal('bar');
You can also pass in an HTML string for the second argument:
var morphdom = require('morphdom');
var el1 = document.createElement('div');
el1.className = 'foo';
el1.innerHTML = 'Hello John';
morphdom(el1, '<div class="bar">Hello Frank</div>');
expect(el1.className).to.equal('bar');
expect(el1.innerHTML).to.equal('Hello Frank');
NOTE: This module will modify both the original and target DOM node tree during the transformation. It is assumed that the target DOM node tree will be discarded after the original DOM node tree is morphed.
Examples
See: ./examples/
Browser Support
- IE9+ and any modern browser
- Proper namespace support added in
v1.4.0
API
morphdom(fromNode, toNode, options) : Node
The morphdom(fromNode, toNode, options)
function supports the following arguments:
- fromNode (
Node
)- The node to morph - toNode (
Node
|String
) - The node that thefromNode
should be morphed to (or an HTML string) - options (
Object
) - See below for supported options
The returned value will typically be the fromNode
. However, in situations where the fromNode
is not compatible with the toNode
(either different node type or different tag name) then a different DOM node will be returned.
Supported options (all optional):
- getNodeKey (
Function(node)
) - Called to get theNode
's unique identifier. This is used bymorphdom
to rearrange elements rather than creating and destroying an element that already exists. This defaults to using theNode
'sid
property. (Note that form fields must not have aname
corresponding to forms' DOM properties, e.g.id
.) - addChild (
Function(parentNode, childNode)
) - Called when adding a new child to a parent. By default,parentNode.appendChild(childNode)
is invoked. Use this callback to customize how a new child is added. - onBeforeNodeAdded (
Function(node)
) - Called before aNode
in theto
tree is added to thefrom
tree. If this function returnsfalse
then the node will not be added. Should return the node to be added. - onNodeAdded (
Function(node)
) - Called after aNode
in theto
tree has been added to thefrom
tree. - onBeforeElUpdated (
Function(fromEl, toEl)
) - Called before aHTMLElement
in thefrom
tree is updated. If this function returnsfalse
then the element will not be updated. if this function returns an instance ofHTMLElement
, it will be used as the new fromEl tree to proceed with morphing for that branch, otherwise the current fromEl tree is used. - onElUpdated (
Function(el)
) - Called after aHTMLElement
in thefrom
tree has been updated. - onBeforeNodeDiscarded (
Function(node)
) - Called before aNode
in thefrom
tree is discarded. If this function returnsfalse
then the node will not be discarded. - onNodeDiscarded (
Function(node)
) - Called after aNode
in thefrom
tree has been discarded. - onBeforeElChildrenUpdated (
Function(fromEl, toEl)
) - Called before the children of aHTMLElement
in thefrom
tree are updated. If this function returnsfalse
then the child nodes will not be updated. - childrenOnly (
Boolean
) - Iftrue
then only the children of thefromNode
andtoNode
nodes will be morphed (the containing element will be skipped). Defaults tofalse
. - skipFromChildren (
Function(fromEl)
) - called when indexing a thefromEl
tree. False by default. Returntrue
to skip indexing the from tree, which will keep current items in place after patch rather than removing them when not found in thetoEl
.
var morphdom = require('morphdom');
var morphedNode = morphdom(fromNode, toNode, {
getNodeKey: function(node) {
return node.id;
},
addChild: function(parentNode, childNode) {
parentNode.appendChild(childNode);
},
onBeforeNodeAdded: function(node) {
return node;
},
onNodeAdded: function(node) {
},
onBeforeElUpdated: function(fromEl, toEl) {
return true;
},
onElUpdated: function(el) {
},
onBeforeNodeDiscarded: function(node) {
return true;
},
onNodeDiscarded: function(node) {
},
onBeforeElChildrenUpdated: function(fromEl, toEl) {
return true;
},
childrenOnly: false,
skipFromChildren: function(fromEl, toEl) {
return false;
}
});
FAQ
Can I make morphdom blaze through the DOM tree even faster? Yes.
morphdom(fromNode, toNode, {
onBeforeElUpdated: function(fromEl, toEl) {
// spec - https://dom.spec.whatwg.org/#concept-node-equals
if (fromEl.isEqualNode(toEl)) {
return false
}
return true
}
})
This avoids traversing through the entire subtree when you know they are equal. While we haven't added this to the core lib yet due to very minor concerns, this is an easy way to make DOM diffing speeds on par with virtual DOM.
Isn't the DOM slow?
UPDATE: As of v2.1.0
, morphdom
supports both diffing a real DOM tree with another real DOM tree and diffing a real DOM tree with a virtual DOM tree. See: docs/virtual-dom.md for more details.
No, the DOM data structure is not slow. The DOM is a key part of any web browser so it must be fast. Walking a DOM tree and reading the attributes on DOM nodes is not slow. However, if you attempt to read a computed property on a DOM node that requires a relayout of the page then that will be slow. However, morphdom
only cares about the following properties and methods of a DOM node:
node.firstChild
node.nextSibling
node.nodeType
node.nodeName
node.nodeValue
node.attributes
node.value
node.selected
node.disabled
actualize(document)
(non-standard, used to upgrade a virtual DOM node to a real DOM node)hasAttributeNS(namespaceURI, name)
isSameNode(anotherNode)
What about the virtual DOM?
Libraries such as a React and virtual-dom solve a similar problem using a Virtual DOM. That is, at any given time there will be the real DOM (that the browser rendered) and a lightweight and persistent virtual DOM tree that is a mirror of the real DOM tree. Whenever the view needs to update, a new virtual DOM tree is rendered. The new virtual DOM tree is then compared with the old virtual DOM tree using a diffing algorithm. Based on the differences that are found, the real DOM is then "patched" to match the new virtual DOM tree and the new virtual DOM tree is persisted for future diffing.
Both morphdom
and virtual DOM based solutions update the real DOM with the minimum number of changes. The only difference is in how the differences are determined. morphdom
compares real DOM nodes while virtual-dom
and others only compare virtual DOM nodes.
There are some drawbacks to using a virtual DOM-based approach even though the Virtual DOM has improved considerably over the last few years:
- The real DOM is not the source of truth (the persistent virtual DOM tree is the source of truth)
- The real DOM cannot be modified behind the scenes (e.g., no jQuery) because the diff is done against the virtual DOM tree
- A copy of the real DOM must be maintained in memory at all times (albeit a lightweight copy of the real DOM)
- The virtual DOM is an abstraction layer that introduces code overhead
- The virtual DOM representations are not standardized and will vary by implementation
- The virtual DOM can only efficiently be used with code and templating languages that produce a virtual DOM tree
The premise for using a virtual DOM is that the DOM is "slow". While there is slightly more overhead in creating actual DOM nodes instead of lightweight virtual DOM nodes, in practice there isnt much difference. In addition, as web browsers get faster the DOM data structure will also likely continue to get faster so there benefits to avoiding the abstraction layer.
Moreover, we have found that diffing small changes may be faster with actual DOM. As the diffing become larger, the cost of diffs slow down due to IO and virtual dom benefits begin to show.
See the Benchmarks below for a comparison of morphdom
with virtual-dom.
Which is better: rendering to an HTML string or rendering virtual DOM nodes?
There are many high performance templating engines that stream out HTML strings with no intermediate virtual DOM nodes being produced. On the server, rendering directly to an HTML string will always be faster than rendering virtual DOM nodes (that then get serialized to an HTML string). In a benchmark where we compared server-side rendering for Marko (with Marko Widgets) and React we found that Marko was able to render pages ten times faster than React with much lower CPU usage (see: Marko vs React: Performance Benchmark)
A good strategy to optimize for performance is to render a template to an HTML string on the server, but to compile the template such that it renders to a DOM/virtual DOM in the browser. This approach offers the best performance for both the server and the browser. In the near future, support for rendering to a virtual DOM will be added to the Marko templating engine.
What projects are using morphdom
?
morphdom
is being used in the following projects:
- Phoenix Live View (
v0.0.1+
) - Rich, real-time user experiences with server-rendered HTML - TS LiveView (
v0.1.0+
) - Build SSR realtime SPA with Typescript - Omi.js (
v1.0.1+
) - Open and modern framework for building user interfaces. - Marko Widgets (
v5.0.0-beta+
) - Marko Widgets is a high performance and lightweight UI components framework that uses the Marko templating engine for rendering UI components. You can see how Marko Widgets compares to React in performance by taking a look at the following benchmark: Marko vs React: Performance Benchmark - Catberry.js (
v6.0.0+
) - Catberry is a framework with Flux architecture, isomorphic web-components and progressive rendering. - Composer.js (
v1.2.1
) - Composer is a set of stackable libraries for building complex single-page apps. It uses morphdom in its rendering engine for efficient and non-destructive updates to the DOM. - yo-yo.js (
v1.2.2
) - A tiny library for building modular UI components using DOM diffing and ES6 tagged template literals. yo-yo powers a tiny, isomorphic framework called choo (v3.3.0
), which is designed to be fun. - vomit.js (
v0.9.19
) - A library that uses the power of ES6 template literals to quickly create DOM elements that you can update and compose with Objects, Arrays, other DOM elements, Functions, Promises and even Streams. All with the ease of a function call. - CableReady(
v4.0+
) - Server Rendered SPAs. CableReady provides a standard interface for invoking common client-side DOM operations from the server via ActionCable. - Integrated Haskell Platform(
all versions
) - A complete platform for developing server-rendered web applications in Haskell. - Ema(
all versions
) - A change-aware static site generator library for Haskell. morphdom is used to provide hot reload in the live server. - CableReady (
v4.0+
) - Server Rendered SPAs. CableReady provides a standard interface for invoking common client-side DOM operations from the server via ActionCable. - Integrated Haskell Platform (
all versions
) - A complete platform for developing server-rendered web applications in Haskell. - morphdom-swap for htmx) (
all versions
) - an extension that usesmorphdom
as the swapping mechanism for htmx. - simply.js(
all versions
) - Simple web-component library for simple web-apps.
NOTE: If you are using a morphdom
in your project please send a PR to add your project here
Benchmarks
Below are the results on running benchmarks on various DOM transformations for both morphdom
, nanomorph
and virtual-dom. This benchmark uses a high performance timer (i.e., window.performance.now()
) if available. For each test the benchmark runner will run 100
iterations. After all of the iterations are completed for one test the average time per iteration is calculated by dividing the total time by the number of iterations.
To run the benchmarks:
npm run benchmark
And then open the generated test-page.html
in the browser to view the results:
file:///HOME/path-to-morphdom/test/mocha-headless/generated/test-page.html
The table below shows some sample benchmark results when running the benchmarks on a MacBook Pro (2.3 GHz Intel Core i5, 8 GB 2133 MHz LPDDR3). Remember, as noted above, the larger the diff needed to evaluate, the more vdom will perform better. The average time per iteration for each test is shown in the table below:
- Total time for morphdom: 820.02ms
- Total time for virtual-dom: 333.81ms (winner)
- Total time for nanomorph: 3,177.85ms
morphdom | nanomorph | virtual-dom | |
attr-value-empty-string | 0.01ms | 0.02ms | 0.01ms |
change-tagname | 0.01ms | 0.00ms | 0.01ms |
change-tagname-ids | 0.02ms | 0.00ms | 0.02ms |
data-table | 0.60ms | 1.38ms | 0.80ms |
data-table2 | 2.72ms | 12.42ms | 0.84ms |
equal | 0.50ms | 1.33ms | 0.02ms |
id-change-tag-name | 0.03ms | 0.04ms | 0.04ms |
ids-nested | 0.08ms | 0.02ms | 0.01ms |
ids-nested-2 | 0.03ms | 0.02ms | 0.05ms |
ids-nested-3 | 0.03ms | 0.01ms | 0.02ms |
ids-nested-4 | 0.04ms | 0.04ms | 0.03ms |
ids-nested-5 | 0.04ms | 0.08ms | 0.06ms |
ids-nested-6 | 0.03ms | 0.03ms | 0.03ms |
ids-nested-7 | 0.02ms | 0.03ms | 0.02ms |
ids-prepend | 0.03ms | 0.03ms | 0.02ms |
input-element | 0.02ms | 0.04ms | 0.00ms |
input-element-disabled | 0.01ms | 0.02ms | 0.01ms |
input-element-enabled | 0.01ms | 0.02ms | 0.01ms |
large | 2.88ms | 12.11ms | 0.35ms |
lengthen | 0.03ms | 0.15ms | 0.04ms |
one | 0.01ms | 0.03ms | 0.01ms |
reverse | 0.03ms | 0.05ms | 0.02ms |
reverse-ids | 0.05ms | 0.07ms | 0.02ms |
select-element | 0.07ms | 0.14ms | 0.03ms |
shorten | 0.03ms | 0.07ms | 0.02ms |
simple | 0.02ms | 0.05ms | 0.02ms |
simple-ids | 0.05ms | 0.09ms | 0.04ms |
simple-text-el | 0.03ms | 0.04ms | 0.03ms |
svg | 0.03ms | 0.05ms | 0.01ms |
svg-append | 0.06ms | 0.06ms | 0.07ms |
svg-append-new | 0.02ms | 0.02ms | 0.18ms |
svg-no-default-namespace | 0.05ms | 0.09ms | 0.04ms |
svg-xlink | 0.01ms | 0.05ms | 0.00ms |
tag-to-text | 0.00ms | 0.00ms | 0.01ms |
text-to-tag | 0.00ms | 0.00ms | 0.01ms |
text-to-text | 0.00ms | 0.01ms | 0.00ms |
textarea | 0.01ms | 0.02ms | 0.01ms |
todomvc | 0.55ms | 3.05ms | 0.32ms |
todomvc2 | 0.05ms | 0.07ms | 0.09ms |
two | 0.01ms | 0.02ms | 0.01ms |
NOTE: Chrome 72.0.3626.121
Maintainers
- Patrick Steele-Idem (Twitter: @psteeleidem)
- Scott Newcomer (Twitter: @puekey)
Contribute
Pull Requests welcome. Please submit Github issues for any feature enhancements, bugs or documentation problems. Please make sure tests pass:
npm test
License
MIT
Top Related Projects
⚛️ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.
The library for web and native user interfaces.
This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
web development for the rest of us
A rugged, minimal framework for composing JavaScript behavior in your markup.
:fire: An extremely fast, React-like JavaScript library for building modern user interfaces
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot