Closed phillipskevin closed 7 years ago
Do you have a script that will produce this? I would want to look at the profiler.
I pushed the code I used here: https://github.com/phillipskevin/donejs-modlet-comparison.
I ran the test 3 times with 10 components. Here are the results:
Run | Requests / Second with modlets | Requests / Second with .component |
---|---|---|
1 | 134.74 | 81.38 |
2 | 136.06 | 85.46 |
3 | 133.60 | 84.05 |
I have a theory on what might be the issue. Going to try a couple of things.
So, my suspicion was that this is because of <can-import>
. Any can-import, even the static variety, causes a call to System.import(name)
. This call is more expensive for plugins than for any other identifier (although it is expensive in both cases) because the plugin has to be normalized twice (once for each side of the bang).
What I did was go inside of node_modules/can-view-import/can-view-import.js
and add a return
to the top of the tag callback. This prevents it from importing the module each time.
This will work in this app because there are only static imports. If you have dynamic imports you'd have to account for that, (maybe add a static
attribute or something so you can tell the difference). Here are the results:
Run | Requests / Second with modlets | Requests / Second with .component |
---|---|---|
1 | 227.98 | 177.75 |
2 | 225.25 | 176.75 |
3 | 226.89 | 174.92 |
So, as I suspected, the import calls are slowing down rendering. What's interesting here is that while the .component imports were helped (almost double the number of requests), the modlets are still faster.
So I wonder if it's possible that there is something else going on here as well. Note that the gap is about the same, 50ms or so faster for modlets.
I'm going to measure just the import
part and see how slow that is.
Looking more into it, it seems that a single import is very fast, maybe 1 or 2ms. However when multiple imports are taking place at once, in this case 10, it significantly slows down each one, to 10-20ms. I'm looking into why.
One thing we could possibly do is hook normalize and cache the value after a module has been imported. This would prevent it from having to do the expensive normalize algorithm every time. I'm going to give this a shot.
I'm also looking into the differences in how a .component
's view and a stache file get compiled and rendered.
I have a branch in steal that does cache of normalize
once an app is fully loaded. This prevents the extra normalization costs on requests.
This can be used with:
{
"devDependencies": {
"done-serve": "supercache",
"steal": "supercache"
}
}
Here are the results:
Run | Requests / Second with modlets | Requests / Second with .component |
---|---|---|
1 | 208.39 | 211.79 |
2 | 209.06 | 211.50 |
3 | 208.39 | 212.06 |
Using the supercache the .component modules can serve 2.5x as many requests per second. And are about the same as an app using modlets. This leads me to believe that normalization is the reason for this performance issue.
I'm going to think some more about whether the method for which this was implemented is the right way, or if this is better implemented as something like a done-ssr feature.
@phillipskevin I'm going to move this to done-ssr as I think it's a general SSR performance issue and done-component doesn't have anything specific about it that's causing it.
Issue moved to donejs/done-ssr #223 via ZenHub
I ran some tests in a freshly made DoneJS 1.0 app (built / minified) by creating nested
.component
files and then nested files using modlets. Here is what the10 .component
test looked like:I benchmarked this using 400 concurrent connections, 12 threads, and ran the test for 1 minute. Here is an example test run:
It seems there is a performance penalty to using
.component
files vs using modlets. Here are the results I have so far: