With Mapbox GL JS switching to Rollup, I've spent some time researching its performance and whether we could do anything to significantly improve it. Here's an except from the top of the performance profile for a full bundle of GL JS (done with node --prof rollup ...):
[JavaScript]:
ticks total nonlib name
444 6.1% 6.1% LoadIC: A load IC from the snapshot
206 2.8% 2.9% Builtin: InterpreterEntryTrampoline
197 2.7% 2.7% Builtin: KeyedLoadIC_Megamorphic
154 2.1% 2.1% StoreIC: A store IC from the snapshot
The bottom-up view shows that those are related to the syntax tree and its nodes in Rollup. What this profile seems to suggest is that most property accesses and assignments in AST nodes operated by Rollup can't be properly optimized by V8 — it can't reliably determine the hidden class of every node for that.
Digging further, it looks like this happens because of the way Rollup "enhances" the AST returned by Acorn:
|
const type = nodes[rawNode.type] || UnknownNode; |
|
(<any>rawNode).__proto__ = type.prototype; |
To augment the nodes with Rollup-specific methods, it reassigns its __proto__ value. This excellent StackOverflow exchange seems to suggest that this completely wrecks JS engine optimizations.
I'm not entirely sure how much eliminating this hack will affect performance in practice, but it could be quite significant. Also, doing so may require a substantial rewrite of Rollup architecture, and it's not yet clear which exact approach to take. Let's discuss/investigate further!
cc @guybedford @lukastaegert @anandthakker
With Mapbox GL JS switching to Rollup, I've spent some time researching its performance and whether we could do anything to significantly improve it. Here's an except from the top of the performance profile for a full bundle of GL JS (done with
node --prof rollup ...):The bottom-up view shows that those are related to the syntax tree and its nodes in Rollup. What this profile seems to suggest is that most property accesses and assignments in AST nodes operated by Rollup can't be properly optimized by V8 — it can't reliably determine the hidden class of every node for that.
Digging further, it looks like this happens because of the way Rollup "enhances" the AST returned by Acorn:
rollup/src/ast/enhance.ts
Lines 61 to 62 in c02e60d
To augment the nodes with Rollup-specific methods, it reassigns its
__proto__value. This excellent StackOverflow exchange seems to suggest that this completely wrecks JS engine optimizations.I'm not entirely sure how much eliminating this hack will affect performance in practice, but it could be quite significant. Also, doing so may require a substantial rewrite of Rollup architecture, and it's not yet clear which exact approach to take. Let's discuss/investigate further!
cc @guybedford @lukastaegert @anandthakker