[perf-optimization] skip unnecessary work in modules that can support memoization of the data structure consumed by them

pull/221/head
Caridy 8 years ago
parent 673e2a7e7b
commit 687db9f99b

@ -23,6 +23,7 @@ function updateAttrs(oldVnode: VNode, vnode: VNode): void {
attrs = (vnode.data as VNodeData).attrs, namespaceSplit: Array<string>;
if (!oldAttrs && !attrs) return;
if (oldAttrs === attrs) return;
oldAttrs = oldAttrs || {};
attrs = attrs || {};

@ -7,6 +7,7 @@ function updateClass(oldVnode: VNode, vnode: VNode): void {
klass = (vnode.data as VNodeData).class;
if (!oldClass && !klass) return;
if (oldClass === klass) return;
oldClass = oldClass || {};
klass = klass || {};

@ -8,6 +8,7 @@ function updateDataset(oldVnode: VNode, vnode: VNode): void {
key: string;
if (!oldDataset && !dataset) return;
if (oldDataset === dataset) return;
oldDataset = oldDataset || {};
dataset = dataset || {};

@ -7,6 +7,7 @@ function updateProps(oldVnode: VNode, vnode: VNode): void {
props = (vnode.data as VNodeData).props;
if (!oldProps && !props) return;
if (oldProps === props) return;
oldProps = oldProps || {};
props = props || {};

@ -14,6 +14,7 @@ function updateStyle(oldVnode: VNode, vnode: VNode): void {
style = (vnode.data as VNodeData).style;
if (!oldStyle && !style) return;
if (oldStyle === style) return;
oldStyle = oldStyle || {};
style = style || {};
var oldHasDel = 'delayed' in oldStyle;

@ -19,6 +19,19 @@ describe('attributes', function() {
assert.strictEqual(elm.getAttribute('minlength'), '1');
assert.strictEqual(elm.getAttribute('value'), 'true');
});
it('can be memoized', function() {
var cachedAttrs = {href: '/foo', minlength: 1, value: true};
var vnode1 = h('div', {attrs: cachedAttrs});
var vnode2 = h('div', {attrs: cachedAttrs});
elm = patch(vnode0, vnode1).elm;
assert.strictEqual(elm.getAttribute('href'), '/foo');
assert.strictEqual(elm.getAttribute('minlength'), '1');
assert.strictEqual(elm.getAttribute('value'), 'true');
elm = patch(vnode1, vnode2).elm;
assert.strictEqual(elm.getAttribute('href'), '/foo');
assert.strictEqual(elm.getAttribute('minlength'), '1');
assert.strictEqual(elm.getAttribute('value'), 'true');
});
it('are not omitted when falsy values are provided', function() {
var vnode1 = h('div', {attrs: {href: null, minlength: 0, value: false}});
elm = patch(vnode0, vnode1).elm;

@ -166,7 +166,7 @@ describe('snabbdom', function() {
assert.equal(elm.className, 'class');
});
});
describe('pathing an element', function() {
describe('patching an element', function() {
it('changes the elements classes', function() {
var vnode1 = h('i', {class: {i: true, am: true, horse: true}});
var vnode2 = h('i', {class: {i: true, am: true, horse: false}});
@ -185,6 +185,19 @@ describe('snabbdom', function() {
assert(elm.classList.contains('am'));
assert(!elm.classList.contains('horse'));
});
it('preserves memoized classes', function() {
var cachedClass = {i: true, am: true, horse: false};
var vnode1 = h('i', {class: cachedClass});
var vnode2 = h('i', {class: cachedClass});
elm = patch(vnode0, vnode1).elm;
assert(elm.classList.contains('i'));
assert(elm.classList.contains('am'));
assert(!elm.classList.contains('horse'));
elm = patch(vnode1, vnode2).elm;
assert(elm.classList.contains('i'));
assert(elm.classList.contains('am'));
assert(!elm.classList.contains('horse'));
});
it('removes missing classes', function() {
var vnode1 = h('i', {class: {i: true, am: true, horse: true}});
var vnode2 = h('i', {class: {i: true, am: true}});
@ -201,6 +214,15 @@ describe('snabbdom', function() {
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.src, 'http://localhost/');
});
it('preserves memoized props', function() {
var cachedProps = {src: 'http://other/'};
var vnode1 = h('a', {props: cachedProps});
var vnode2 = h('a', {props: cachedProps});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.src, 'http://other/');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.src, 'http://other/');
});
it('removes an elements props', function() {
var vnode1 = h('a', {props: {src: 'http://other/'}});
var vnode2 = h('a');

@ -28,6 +28,17 @@ describe('dataset', function() {
assert.equal(elm.dataset.baz, 'baz');
assert.equal(elm.dataset.foo, undefined);
});
it('can be memoized', function() {
var cachedDataset = {foo: 'foo', bar: 'bar'};
var vnode1 = h('i', {dataset: cachedDataset});
var vnode2 = h('i', {dataset: cachedDataset});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.dataset.foo, 'foo');
assert.equal(elm.dataset.bar, 'bar');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.dataset.foo, 'foo');
assert.equal(elm.dataset.bar, 'bar');
});
it('handles string conversions', function() {
var vnode1 = h('i', {dataset: {empty: '', dash: '-', dashed:'foo-bar', camel: 'fooBar', integer:0, float:0.1}});
elm = patch(vnode0, vnode1).elm;

@ -18,6 +18,17 @@ describe('style', function() {
elm = patch(vnode0, h('div', {style: {fontSize: '12px'}})).elm;
assert.equal(elm.style.fontSize, '12px');
});
it('can be memoized', function() {
var cachedStyles = {fontSize: '14px', display: 'inline'};
var vnode1 = h('i', {style: cachedStyles});
var vnode2 = h('i', {style: cachedStyles});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.style.fontSize, '14px');
assert.equal(elm.style.display, 'inline');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.style.fontSize, '14px');
assert.equal(elm.style.display, 'inline');
});
it('updates styles', function() {
var vnode1 = h('i', {style: {fontSize: '14px', display: 'inline'}});
var vnode2 = h('i', {style: {fontSize: '12px', display: 'block'}});

Loading…
Cancel
Save