Skip to content

Commit 5759e99

Browse files
ngokevindmarcos
authored andcommitted
skip buildData if just updating component directly, ~2x speed boost for component update (fixes #3875) (#3835)
* skip buildData if just updating component directly (fixes #3875) * set attribute performance test
1 parent c20f248 commit 5759e99

File tree

11 files changed

+286
-127
lines changed

11 files changed

+286
-127
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>.setAttribute Performance Test - A-Frame</title>
5+
<meta name="description" content="">
6+
<script src="../../../dist/aframe-master.js"></script>
7+
<script>
8+
AFRAME.registerComponent('dummy', {
9+
schema: {
10+
foo: {default: 0},
11+
bar: {default: ''},
12+
baz: {default: true},
13+
qux: {default: true},
14+
qaz: {default: true},
15+
a: {default: true},
16+
b: {default: true},
17+
c: {default: true},
18+
d: {default: true},
19+
e: {default: true},
20+
f: {default: true},
21+
g: {default: true},
22+
h: {default: true},
23+
i: {default: true},
24+
j: {default: true},
25+
k: {default: true}
26+
},
27+
28+
multiple: true
29+
});
30+
31+
AFRAME.registerComponent('set-attribute-test', {
32+
dependencies: ['dummy__1'],
33+
34+
play: function () {
35+
const t0 = window.performance.now();
36+
for (let i = 0; i < 100000; i++) {
37+
this.el.setAttribute('dummy__1', 'foo', i);
38+
}
39+
const t1 = window.performance.now();
40+
console.log((t1 - t0) / 100000, 'ms');
41+
}
42+
});
43+
</script>
44+
</head>
45+
<body>
46+
<a-scene>
47+
<a-mixin id="foo" dummy__1="foo: 1"></a-mixin>
48+
<a-mixin id="bar" dummy__1="foo: 2"></a-mixin>
49+
<a-mixin id="baz" dummy__1="foo: 3"></a-mixin>
50+
51+
<a-entity mixin="foo bar baz" dummy__1="a: false; b: false; c: false; d: false; e: false; f: false; g: false" set-attribute-test></a-entity>
52+
</a-scene>
53+
</body>
54+
</html>
55+

src/components/geometry.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var dummyGeometry = new THREE.Geometry();
1212
module.exports.Component = registerComponent('geometry', {
1313
schema: {
1414
buffer: {default: true},
15-
primitive: {default: 'box', oneOf: geometryNames},
15+
primitive: {default: 'box', oneOf: geometryNames, schemaChange: true},
1616
skipCache: {default: false}
1717
},
1818

src/components/light.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ module.exports.Component = registerComponent('light', {
1919
distance: {default: 0.0, min: 0, if: {type: ['point', 'spot']}},
2020
intensity: {default: 1.0, min: 0, if: {type: ['ambient', 'directional', 'hemisphere', 'point', 'spot']}},
2121
penumbra: {default: 0, min: 0, max: 1, if: {type: ['spot']}},
22-
type: {default: 'directional', oneOf: ['ambient', 'directional', 'hemisphere', 'point', 'spot']},
22+
type: {
23+
default: 'directional',
24+
oneOf: ['ambient', 'directional', 'hemisphere', 'point', 'spot'],
25+
schemaChange: true
26+
},
2327
target: {type: 'selector', if: {type: ['spot', 'directional']}},
2428

2529
// Shadows.

src/components/material.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module.exports.Component = registerComponent('material', {
2626
offset: {type: 'vec2', default: {x: 0, y: 0}},
2727
opacity: {default: 1.0, min: 0.0, max: 1.0},
2828
repeat: {type: 'vec2', default: {x: 1, y: 1}},
29-
shader: {default: 'standard', oneOf: shaderNames},
29+
shader: {default: 'standard', oneOf: shaderNames, schemaChange: true},
3030
side: {default: 'front', oneOf: ['front', 'back', 'double']},
3131
transparent: {default: false},
3232
vertexColors: {type: 'string', default: 'none', oneOf: ['face', 'vertex']},

src/core/a-entity.js

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ var proto = Object.create(ANode.prototype, {
466466
updateComponent: {
467467
value: function (attr, attrValue, clobber) {
468468
var component = this.components[attr];
469+
469470
if (component) {
470471
// Remove component.
471472
if (attrValue === null && !checkComponentDefined(this, attr)) {
@@ -586,12 +587,54 @@ var proto = Object.create(ANode.prototype, {
586587
}
587588
},
588589

590+
/**
591+
* When mixins updated, trigger init or optimized-update of relevant components.
592+
*/
589593
mixinUpdate: {
590-
value: function (newMixins, oldMixins) {
591-
oldMixins = oldMixins || this.getAttribute('mixin');
592-
this.updateMixins(newMixins, oldMixins);
593-
this.updateComponents();
594-
}
594+
value: (function () {
595+
var componentsUpdated = [];
596+
597+
return function (newMixins, oldMixins) {
598+
var component;
599+
var mixinEl;
600+
var mixinIds;
601+
var i;
602+
603+
oldMixins = oldMixins || this.getAttribute('mixin');
604+
mixinIds = this.updateMixins(newMixins, oldMixins);
605+
606+
// Loop over current mixins.
607+
componentsUpdated.length = 0;
608+
for (i = 0; i < this.mixinEls.length; i++) {
609+
for (component in this.mixinEls[i].componentCache) {
610+
if (componentsUpdated.indexOf(component) === -1) {
611+
if (this.components[component]) {
612+
// Update. Just rebuild data.
613+
this.components[component].handleMixinUpdate();
614+
} else {
615+
// Init. buildData will gather mixin values.
616+
this.initComponent(component, null);
617+
}
618+
componentsUpdated.push(component);
619+
}
620+
}
621+
}
622+
623+
// Loop over old mixins to call for data rebuild.
624+
for (i = 0; i < mixinIds.oldMixinIds.length; i++) {
625+
mixinEl = document.getElementById(mixinIds.oldMixinIds[i]);
626+
if (!mixinEl) { continue; }
627+
for (component in mixinEl.componentCache) {
628+
if (componentsUpdated.indexOf(component) === -1) {
629+
if (this.components[component]) {
630+
// Compoennt removed. Rebuild data if not yet rebuilt.
631+
this.components[component].handleMixinUpdate();
632+
}
633+
}
634+
}
635+
}
636+
};
637+
})()
595638
},
596639

597640
/**

src/core/a-node.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ module.exports = registerElement('a-node', {
148148
value: (function () {
149149
var newMixinIdArray = [];
150150
var oldMixinIdArray = [];
151+
var mixinIds = {};
151152

152153
return function (newMixins, oldMixins) {
153154
var i;
@@ -159,6 +160,9 @@ module.exports = registerElement('a-node', {
159160
newMixinIds = newMixins ? utils.split(newMixins.trim(), /\s+/) : newMixinIdArray;
160161
oldMixinIds = oldMixins ? utils.split(oldMixins.trim(), /\s+/) : oldMixinIdArray;
161162

163+
mixinIds.newMixinIds = newMixinIds;
164+
mixinIds.oldMixinIds = oldMixinIds;
165+
162166
// Unregister old mixins.
163167
for (i = 0; i < oldMixinIds.length; i++) {
164168
if (newMixinIds.indexOf(oldMixinIds[i]) === -1) {
@@ -180,6 +184,8 @@ module.exports = registerElement('a-node', {
180184
window.HTMLElement.prototype.setAttribute.call(this, 'mixin',
181185
this.computedMixinStr);
182186
}
187+
188+
return mixinIds;
183189
};
184190
})()
185191
},

0 commit comments

Comments
 (0)