Swizz / snabbdom-pragma

'NotReact.createElement' jsx pragma although for snabbdom
MIT License
47 stars 16 forks source link

Performance improvements #11

Open Swizz opened 7 years ago

Swizz commented 7 years ago

I'm curious to know more about how to measure performance in op/sec, to have a comparison between :

Swizz commented 7 years ago

Bad news...

Snabbdom-pragma@1  =>  20346 op/s [avg: 0.491ms]
Snabbdom-pragma@2  =>  9622 op/s [avg: 1.039ms]
Snabbdom/h  =>  65803 op/s [avg: 0.152ms]

for

Snabbdom.createElement('div', null, 'Hello', 13)
Swizz commented 7 years ago

Plan to move to ~Ramda~ Lodash instead of builtin map/reduce/filter ?

Swizz commented 7 years ago

Partial lodash experiment :

Snabbdom-pragma@1  =>  21607 op/s [avg: 0.462ms]
Snabbdom-pragma@2  =>  27133 op/s [avg: 0.368ms] (lodash here)
Snabbdom/h  =>  67558 op/s [avg: 0.148ms]
Swizz commented 7 years ago

Which is better ? Speed or Weight ?

Swizz commented 7 years ago

I aimed to be dependency free. So what about using is and lodash and produce a dist file which be dependency free with tree shacking ?

Swizz commented 7 years ago

@jvanbruegge Are Snabbdom-pragma performances for Snabbdom and Cyclejs users a priority ?

jvanbruegge commented 7 years ago

I would go for dependency free, as this is affecting the users bundle size. I think Prepack can get rid of the snabbdom-pragma overhead. Can you test it too?

Swizz commented 7 years ago

I made a brief tests, and seen a tiny difference regarding the lodash implementation ones.

The prepack stuffs need to be done after the project use of Snabbdom.createElement, at our state, this is unrelevant.

Only the dist/index.js is used in most case with the basic import ... from .... So, it could be good to import with tree shacking only the requested functionnalities from Lodash, isnt it ?

jvanbruegge commented 7 years ago

what is the compiled js after prepack? Sorry, I'm on mobile

Swizz commented 7 years ago

On mobile too, I'll take a look after lunch.

Swizz commented 7 years ago

Here you are

Prepack isnt in love with exports/require, so it needed to do some hacks to work with.. Prepack didn't replace Array.prototype.map, Array.prototype.reduce, etc.., functions that are costly for us. Prepack works fine for the finnal duty at the production bundling, not our case. Prepack will be good after transpiling, to catch Snabbdom.createElement invariant results.

jvanbruegge commented 7 years ago

I mean prepack on the file that is using JSX. I assume that it optimizes snabbdom-pragma away and replaces it with just the correct h call

jvanbruegge commented 7 years ago

How much does lodash add to the size?

Swizz commented 7 years ago

Following @caridy response :

It does return just an object, and yes, h() does more, it has a great deal of flexibility in the order of the arguments, and it supports compound sel value, but neither of those are things that you care about because they can't be express in JSX, so, for you it will be the same. I also recommend creating a custom h() for projects that are mores restrictive, and expect better perf by removing all that logic that we have in h().

Snabbdom@2 is not calling h() anymore


In fact, we loose in perf due to the switch from for loop to map/reduce.

Snabbdom-pragma@1 was 2.76 KB (1.67 KB compressed) Snabbdom-pragma@2 is 4.9 KB (3.0 KB compressed)

I were happy to rewrite Snabbdom-pragma in a more FP way following the Snabbdom contributor advice, but I realise, it was a big loss in all points.

Some ES6 features I overuse result to a big transpiled code. Destructuring, rest operator, etc..


For lodash size, I'll need to try, but we can count 3 or 4 functions : flatten, map, reduce, fromPairs (?). So we can hope no more than 1 KB.

Swizz commented 7 years ago

I dont know how this is calculated, but npm-cost, give me other results : https://cost-of-modules.herokuapp.com/?p=snabbdom-pragma@2.2.0 https://cost-of-modules.herokuapp.com/?p=snabbdom-pragma@1.10.0

snabbdom-pragma@1 : 3.49 KB snabbdom-pragma@2 : 3.56 KB

blikblum commented 6 years ago

Snabbdom-pragma@1 => 20346 op/s [avg: 0.491ms] Snabbdom-pragma@2 => 9622 op/s [avg: 1.039ms] Snabbdom/h => 65803 op/s [avg: 0.152ms]

How do you get those numbers? I'm interested in trying to improve the performance

Swizz commented 6 years ago

I was using a custom implementation using time/timeEnd.

But we should use mafintosh/nanobench

blikblum commented 6 years ago

Do you have any script that i can get and run myself?