• Stars
    star
    726
  • Rank 62,418 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🚅 - Hyper fast diffing algorithm for real DOM nodes

nanomorph stability

npm version build status downloads js-standard-style

Hyper fast diffing algorithm for real DOM nodes

Usage

var morph = require('nanomorph')
var html = require('nanohtml')

var tree = html`<div>hello people</div>`
document.body.appendChild(tree)
// document.body === <body><div>hello people</div></body>

morph(tree, html`<div>nanananana-na-no</div>`)
// document.body === <body><div>nanananana-na-no</div></body>

morph(tree, html`<div>teeny, tiny, tin bottle</div>`)
// document.body === <body><div>teeny, tiny, tin bottle</div></body>

Clearing Input Values

To remove values from inputs, there's a few options:

html`<input class="beep" value=${null}>` // set the value to null
html`<input class="beep">`               // omit property all together

Reordering Lists

It's common to work with lists of elements on the DOM. Adding, removing or reordering elements in a list can be rather expensive. To optimize this you can add an id attribute to a DOM node. When reordering nodes it will compare nodes with the same ID against each other, resulting in far fewer re-renders. This is especially potent when coupled with DOM node caching.

var el = html`
  <section>
    <div id="first">hello</div>
    <div id="second">world</div>
  </section>
`

Caching DOM elements

Sometimes we want to tell the algorithm to not evaluate certain nodes (and its children). This can be because we're sure they haven't changed, or perhaps because another piece of code is managing that part of the DOM tree. To achieve this nanomorph evaluates the .isSameNode() method on nodes to determine if they should be updated or not.

var el = html`<div>node</div>`

// tell nanomorph to not compare the DOM tree if they're both divs
el.isSameNode = function (target) {
  return (target && target.nodeName && target.nodeName === 'DIV')
}

Prevent Morphing Particular Elements

There are situations where two elements should never be morphed, but replaced. nanomorph automatically does this for elements with different tag names. But if we're implementing a custom component system, for example, components of different types should probably be treated as if they had different tags—even if they both render a <div> at their top level.

Nodes can have an optional data-nanomorph-component-id attribute. nanomorph will only ever morph nodes if they both have the same value in this attribute. If the values differ, the old node is replaced with the new one.

var el = html`<div data-nanomorph-component-id="a">hello</div>`
var el2 = html`<div data-nanomorph-component-id="b">goodbye</div>`

assert.equal(nanomorph(el, el2), el2)

nanomorph doesn't have an opinion on the values of the data-nanomorph-component-id attribute, so we can decide the meaning we give it on a case by case basis. There could be a unique ID for every type of component, or a unique ID for every instance of a component, or any other meaning.

FAQ

How is this different from morphdom?

It's quite similar actually; the API of this library is completely compatible with morphdom and we've borrowed a fair few bits. The main difference is that we copy event handlers like onclick, don't support browsers that are over a decade old, and don't provide custom behavior by removing all hooks. This way we can guarantee a consistent, out-of-the box experience for all your diffing needs.

Why doesn't this work in Node?

Node has no concept of a DOM - server side rendering is basically fancy string concatenation. If you want to combine HTML strings in Node, check out hyperstream.

This library seems cool, I'd like to build my own!

Nanomorph was optimized for simplicity, but different situations might require different tradeoffs. So in order to allow folks to build their own implementation we expose our test suite as a function you can call. So regardless if you're doing it to solve a problem, or just for fun: you can use the same tests we use for your own implementation. Yay!

API

tree = nanomorph(oldTree, newTree)

Diff a tree of HTML elements against another tree of HTML elements and create a patched result that can be applied on the DOM.

⚠️ nanomorph will modify the newTree and it should be discarded after use

Installation

$ npm install nanomorph

See Also

Similar Packages

Further Reading

Authors

License

MIT

More Repositories

1

choo

🚂🚋 - sturdy 4kb frontend framework
JavaScript
6,776
star
2

bankai

🚉 - friendly web compiler
JavaScript
1,088
star
3

hyperx

🏷 - tagged template string virtual dom builder
JavaScript
1,010
star
4

nanohtml

🐉 HTML template strings for the Browser with support for Server Side Rendering in Node.
JavaScript
687
star
5

nanographql

Tiny graphQL client library
JavaScript
421
star
6

nanocomponent

🚃 - create performant HTML components
JavaScript
366
star
7

wayfarer

👓 composable trie based router
JavaScript
332
star
8

choo-handbook

🚂✋📖 - Learn the choo framework through a set of exercises
HTML
268
star
9

nanobus

🚎 - Tiny message bus
JavaScript
225
star
10

awesome-choo

🌅 Awesome things related with choo framework
197
star
11

create-choo-app

🚞 - create a fresh choo application
JavaScript
181
star
12

nanostate

🚦- Small Finite State Machines
JavaScript
170
star
13

nanorouter

🛤 - Small frontend router
JavaScript
116
star
14

nanocomponent-adapters

🔌 - Convert a nanocomponent to a component for your favourite API or library (web components, (p)react, angular)
JavaScript
96
star
15

choop

🚂⚛️ - choo architecture for preact
JavaScript
93
star
16

on-idle

😴 - Detect when the browser is idle
JavaScript
82
star
17

nanologger

📜 - Cute browser logs
JavaScript
80
star
18

nanoanimation

👨‍🎨 - Safety wrapper around the Web Animation API
JavaScript
72
star
19

nanoraf

🎞 - Only call RAF when needed
JavaScript
71
star
20

choo-devtools

💼 - Expose a choo instance on the window
JavaScript
53
star
21

nanoquery

📇 - Tiny querystring module
JavaScript
49
star
22

nanotask

Microtask queue scheduler for the browser
JavaScript
47
star
23

choo-log

📃 - Development logger for choo
JavaScript
47
star
24

nanoscheduler

Schedule work to be completed when the user agent is idle.
JavaScript
46
star
25

website

🚇 - Hyper Train Transfer Protocol (HTTP)
JavaScript
46
star
26

nanohref

⛓ - Tiny href click handler library
JavaScript
41
star
27

nanotick

process.nextTick() batching utility
JavaScript
37
star
28

choo-store

Lightweight state structure for choo apps.
JavaScript
37
star
29

nanotiming

⏲ - Small timing library
JavaScript
35
star
30

create-choo-electron

:electron: - Create a fresh Choo Electron application
JavaScript
29
star
31

object-change-callsite

Determine the callsite of an object change using Proxies
JavaScript
27
star
32

choo-reload

⛽️ - Livereloading package for choo
JavaScript
27
star
33

on-performance

Listen for performance timeline events
JavaScript
26
star
34

nanobeacon

Small navigator.sendBeacon wrapper
JavaScript
25
star
35

choo-service-worker

👷 - Service worker loader for choo
JavaScript
24
star
36

choo-scaffold

🏗 - Scaffold out files for a Choo project
JavaScript
24
star
37

choo-notification

Web Notification plugin for Choo
JavaScript
22
star
38

nanobounce

Smol debounce package
JavaScript
19
star
39

choo-choo

🎓 learn choo from the command line!
JavaScript
19
star
40

nanomount

Mount a DOM tree on a target node
JavaScript
19
star
41

choo-redirect

🎬 - Redirect a view to another view
JavaScript
19
star
42

persist-storage

🗄 - Enable persistent storage in the browser
JavaScript
19
star
43

nanohistory

Small browser history library
JavaScript
14
star
44

choo-hooks

🎣 - Hook into Choo's events and timings
JavaScript
12
star
45

nanolocation

📍- Small window.location library
JavaScript
10
star
46

discuss

🎭 – Discuss project organization, initiatives, and anything else!
8
star
47

nanocache

Cache Nanocomponents.
JavaScript
7
star
48

bankai-website

JavaScript
6
star
49

choo-umd

🙈 - umd build for choo framework
HTML
3
star