Deferred Module Evaluation
TC39 January 2021,
Yulia Startsev
🇨🇦
“As performant as possible
under the circumstances”
What are the circumstances?
Is this a meaningful await?
Is there an alternative?
Maybe!
Goal:
Improve startup performance without sacrificing readability.
Goal:
Improve startup performance without sacrificing readability.
Goal:
Improve startup performance without sacrificing readability.
Deferring the module...
Deferring the module...
Deferring the module...
Deferring the module...
This.
Proposed API
alternatively...
Proposed API
alternatively...
Ignore this for now.
Proposed Semantics
Simplified module graph
Left side of parent module is marked as lazy
{ lazyInit: true }
This creates a lazy subgraph, with eagerly loaded modules
Invariant of children finishing evaluation before parents remains.
“Lazy” module graph
Also applies to overlapping lazy/eager graphs
Still eager
This is consistent recursively. Green here is a lazy subgraph of a lazy graph
Known Issues
Top Level Await
Throw?
Top Level Await
Throw?
Alternative: Async is treated eagerly
async module
Side-effectful Get on Local Names
As Global Getter
Problem...
I/O costs - is this really a benefit
Existing practice in frontend frameworks (link)
Code-splitting:
an important complementary tool
Frontend code, Suspense, cont. (link)
Usability in client-side code
Summary
Requesting Stage 1 for
Stage 1?
Question: How much startup time do we save?
Firefox Performance characteristics, ~45% spent loading/parsing (on SSD)
Firefox Performance characteristics ~54% spent running
Star configuration at time of profile
Question: Is “laziness” a feature of the edge or the node?
Shared lazy sub-graph, with module-edge level laziness
{ lazyInit: true }
What about a module that should always be lazy?
Marking a module as lazy within the module text (ie. a directive)
“use deferred-eval”
“use deferred-eval”
Shared lazy sub-graph, with module level laziness
“use deferred-eval”
Question: Can we do this with existing code? (link)
Question: Side-effects.
Side-effectful Get on Local Names
Throw?
Side-effectful Get on Local Names (link)
Stage 1?