-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create Rows & Create Many Rows Benchmark (krause) #1260
Comments
I had a thought on this. Part of the problem at present is probably that we're creating all the fragment methods anew for each fragment: function create_each_block(component, state) {
var cat = state.cat, each_value = state.each_value, cat_index = state.cat_index;
var li, a, text_value = cat.name, text, a_href_value;
return {
c: function create() {
li = createElement("li");
a = createElement("a");
text = createText(text_value);
this.h();
},
h: function hydrate() {
a.target = "_blank";
a.href = a_href_value = cat.video;
},
m: function mount(target, anchor) {
insertNode(li, target, anchor);
appendNode(a, li);
appendNode(text, a);
},
p: function update(changed, state) {
cat = state.cat;
each_value = state.each_value;
cat_index = state.cat_index;
if ((changed.cats) && text_value !== (text_value = cat.name)) {
text.data = text_value;
}
if ((changed.cats) && a_href_value !== (a_href_value = cat.video)) {
a.href = a_href_value;
}
},
u: function unmount() {
detachNode(li);
},
d: noop
};
} We'd probably make life a bit easier on ourselves by using prototypes instead: function EachBlock(component, context) {
this.component = component;
this.context = context;
this.nodes = Array(3);
}
var EachBlockProto = EachBlock.prototype;
EachBlockProto.c = function create() {
this.nodes[0] = createElement("li");
this.nodes[1] = createElement("a");
this.nodes[2] = createText(this.context.cat.name);
this.h();
};
EachBlockProto.h = function hydrate() {
this.nodes[1].target = "_blank";
this.nodes[1].href = this.context.cat.video;
};
EachBlockProto.m = function mount(target, anchor) {
insertNode(this.nodes[0], target, anchor);
appendNode(this.nodes[1], this.nodes[0]);
appendNode(this.nodes[2], this.nodes[1]);
};
EachBlockProto.p = function update(changed, context) {
if (changed.cats) {
if (context.cat.name !== (this.context.cat.name = context.cat.name)) {
text.data = context.cat.name;
}
if (context.cat.video !== (this.context.cat.video = context.cat.video)) {
this.nodes[1].href = context.cat.video;
}
}
};
EachBlockProto.u = function unmount() {
detachNode(this.nodes[0]);
};
EachBlockProto.d = noop; Obviously there's some handwaving there, and there are ways that it could be improved further. But this feels like a worthwhile avenue of exploration. |
Another thought. We could potentially speed things up by using Usual caveats about micronbenchmarks notwithstanding, this seems to suggest that it would indeed give us a perf boost. In theory it should take less memory as well. (It doesn't tell us whether the gains would be outweighed by slower property access from having to walk up the prototype chain, in some cases.) |
I think the main reason that vanillajs beats Svelte by quite a bit is that is creates one row of the table and then repeatedly clones it whereas we create the row from scratch each time. Perhaps we could do the same thing. If we see that a component is ever used in an |
I got a really significant speedup in the benchmark by copying stage0's index.js (which is quite small) into the compiled Svelte script and then using it to do fragment creation:
I used a template string for my own convenience during testing, which wouldn't be compatible with IE11, but I think that could be fixed by just doing string concatenation instead (Freak613/stage0#33) We couldn't use stage0 directly because it uses #-syntax. We'd have to create our own version that uses mustache syntax. Or we could use the solution @Rich-Harris suggested in #3898 |
I forgot to mention this one: #2919. Had a more performant version using event delegation. Just needed someone from the project to give a nod since it would make svelte's version have more code and I knew that is possibly in conflict with a principle goal. |
Closing since Svelte 5 is much faster at these benchmarks |
After the keyed swap rows benchmark, the next piece of "low hanging fruit" is the create rows benchmarks.
Is there a reason why Svelte cannot be among the fastest in these benchmarks? It seems like optimizing the create rows operation would speed up Svelte whenever the each block is being used.
http://www.stefankrause.net/js-frameworks-benchmark7/table.html
The text was updated successfully, but these errors were encountered: