Package Exports
- cache-element
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (cache-element) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
cache-element 
Cache a bel element. Makes rendering elements very fast™. Analogous to
React's .shouldComponentUpdate()
method, but only using native DOM methods.
Features
- makes rendering elements very fast™
- widget API helps with creating stateful wrappers around 3rd party libs
- implemented in only a couple of lines
- only uses native DOM methods
Usage
Caching
Here we take a regular element, and cache it so re-renders are fast:
const cache = require('cache-element')
const html = require('bel')
const renderEl = cache(function (name, age) {
return html`
<p>Name is ${name} and age is ${age}</p>
`
})
let el = renderEl('Tubi', 12) // creates new element
let el = renderEl('Tubi', 12) // returns cached element (proxy)
let el = renderEl('Babs', 25) // creates new element
Widget
Here we take a widget (e.g. d3, gmaps) and wrap it so it return a DOM node once, and then only has to worry about managing its lifecycle:
const widget = require('cache-element/widget')
const html = require('bel')
const renderEl = widget(function (update) {
let name = null
let age = null
update(onupdate)
return html`
<p onload=${onload} onunload=${onunload}>
Name is ${name} and age is ${age}
</p>
`
function onupdate (newName, newAge) {
name = newName
age = newAge
}
function onload () {
console.log('added to DOM')
}
function onunload () {
name = null
age = null
console.log('removed from DOM')
}
})
let el = renderEl('Tubi', 12) // creates new element
let el = renderEl('Tubi', 12) // returns cached element (proxy)
let el = renderEl('Babs', 25) // returns cached element (proxy)
API
createEl = cache(fn(...args))
Cache an element.
createEl = widget(fn(fn(...args)))
Render a widget.
el = createEl(...args)
Render an element, passing it arbitrary arguments.
FAQ
Where does this run?
Make sure you're running a diffing engine that checks for .isSameNode()
, if
it doesn't you'll end up with super weird results because proxy nodes will
probably be rendered which is not what should happen. Probably make sure you're
using morphdom. Seriously.
What's a proxy node?
It's a node that overloads Node.isSameNode()
to compare it to another node.
This is needed because a given DOM node can only exist in one DOM tree at the
time, so we need a way to reference mounted nodes in the tree without actually
using them. Hence the proxy pattern, and the recently added support for it in
certain diffing engines:
const html = require('bel')
const el1 = html`<div>pink is the best</div>`
const el2 = html`<div>blue is the best</div>`
// let's proxy el1
const proxy = html`<div></div>`
proxy.isSameNode = function (targetNode) {
return (targetNode === el1)
}
el1.isSameNode(el1) // true
el1.isSameNode(el2) // false
proxy.isSameNode(el1) // true
proxy.isSameNode(el2) // false
How does it work?
Morphdom is a diffing engine that diffs real DOM trees. It runs a series of checks between nodes to see if they should either be replaced, removed, updated or reordered. This is done using a series of property checks on the nodes.
Since v2.1.0 morphdom
also runs Node.isSameNode(otherNode)
. This
allows us to override the function and replace it with a custom function that
proxies an existing node. Check out the code to see how it works. The result is
that if every element in our tree uses cache-element
, only elements that have
changed will be recomputed and rerendered making things very fast.
What's the exact difference between cache and widget?
cache
return a proxy node if the arguments were the same. If arguments change, it'll rerender and return a new node.widget
will always return a proxy node. It also listens for the node to be unmounted from the DOM so it can clean up internal references, making it more expensive to use.
Installation
$ npm install cache-element