Preact is amazing, but it's boot-speed seems to be slow, per the tests referenced below.
I found this set of boot-speed tests, and added Preact and Mithril to the mix. The numbers are in milliseconds.
Preact: 563
https://plnkr.co/edit/GwYRps6ANxqgeCvcmf6S?p=preview
Vue: 236
http://plnkr.co/edit/KTqvngteLKmX3ZXMDyZO?p=preview
React: 104
https://plnkr.co/edit/TqrC3o5MIHQLWR0QIWaN?p=preview
Mithril: 40
https://plnkr.co/edit/JZtplOYAwA4u1exyebfO?p=preview
Mithril is hella fast. I'm surprised by Preact's performance. I thought I'd share.
@chrisdavies wow! Thanks for investigating this😍
I figured out a way to speed things up for the initial boot, and the number went from 560 to 60. I'll publish the fix ASAP!
Sweet!
I'm so happy you found this! This will also massively improve the performance of @PaulLewis' example he was needing the async renderer for!


A 10x improvement. Pretty impressive. Out of curiosity, what was the culprit?
Preact always inserts using .insertBefore(), but that's incredibly slow when appending to the end of a long list of elements. I just changed the diff so that if the iteration index is greater than the number of existing children, it always uses .appendChild().
using .insertBefore(), but that's incredibly slow when appending to the end of a long list of elements
huh, this sounds suspicious. in my testing insertBefore and appendChild had the same profiles. gonna have to check it out.
It might be a browser-specific thing, too. Not sure. My original results were Chrome on a relatively fast Mac.
It's likely that insertBefore was shifting the list. The diff dynamically accesses childNodes, perhaps that was the expensive part. Either way, when the index of the current child is greater than the total previous children, there's no reason to check if it's a match for the current child.
Yeah. Exactly. Shifting the list sounds like a reasonable explanation. Thanks for investigating and fixing so fast!
I'm actually super happy about this haha. Now I want to test paul's stress test!
yes, accessing childNodes is very expensive for large number of children. it was almost certainly this.
PROTIP: always use firstChild, lastChild, nextSibling and previousSibling for dom itereration.
@leeoniya yup, looking into that. innerDiffNode needs some love anyway, it's using sparse arrays.
I don't understand a thing about those DOM manipulation thing, but kudos.
That boot speed up is amazing ❤
Woot!! Any way we can get Inferno hooked up to this boot-time comparison? :innocent:
FYI, this boot test was using the dev version of Vue and not pre-compiling templates. It also is somewhat unfavorable against Vue (simple structure, large dataset count which makes Vue spend more time on data observation rather than rendering).
Aside from switching to prod mode, simply freezing inner items brings Vue's boot time to ~70ms: http://plnkr.co/edit/WDNuyd4WRYAuytNswoTf?p=preview
@yyx990803 good to know! Preact's score was like double Vue's anyway before the fix, I don't think anyone was trying to call Vue out 👍
Yeah. I didn't write the Vue tests. Just the preact one. I can't remember where I found these in the first place. I think it was in a Mithril support issue.
Most helpful comment
Preact always inserts using
.insertBefore(), but that's incredibly slow when appending to the end of a long list of elements. I just changed the diff so that if the iteration index is greater than the number of existing children, it always uses.appendChild().