Automatic code extraction - top level utils #335
maiieul
started this conversation in
Proposals For Qwik
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
What is it about?
Automatically extracting code – namely top level utils – besides $ boundaries.
What's the motivation for this proposal?
Problems you are trying to solve:
The optimizer can produce segments code that contain both component code and shared helpers. This can lead to over-preloading on user-interaction or – more problematically – on visible tasks (e.g. instead of ~4-5 bundles to preload, it can easily become ~50-100). This happens because the optimizer doesn't split helpers into separate segments. So in practice if a
topLevelHelperfunction is declared in a separate file, the optimizer will leave it untouched, but if it is colocated in the same file as the component code, then the optimizer will output it in the same facade segment as the componentQrl, meaning that when thetopLevelHelperis imported by another module, not only thetopLevelHelperbut also the component and all its transitive dependencies will be eagerly preloaded (with 100% probability) as well.Now this means that if an on-click segment
imports { topLevelHelper } from "./test.js"andTestButton_component_uFrpfTnm3bAhas a lot of transitive dependencies, then the the preloader will end up eagerly preloading (100% probability)TestButton_component_uFrpfTnm3bAand all its transitive dependencies, even though we only needed to get a hold oftopLevelHelper.Goals you are trying to achieve:
Solution n°1
What do you propose?
Extract everything outside of component$ into a "test_helpers_hash.js" segment, and then do a side-effect
import "./test_utils_hash.js"in the component segment (test_hash.js) to keep the same initialization order. Then any consumer ofhelperwill import from test_utils_hash.js instead of from test_hash.js.Code examples
For
We would extract the globals into a separate file. See the diff here.
For this to work, we need to be able to resolve the aliases and verify if the function is a component or a util.
For a barrel file, the current optimizer would produce
but now it would have to be
which is not easy to achieve.
How can the optimizer know whether
topLevelHelperbelongs in test_utils_BBrpfTnm3BB or in test_components_AArpfTnm3AA?Same with
Now it would have to be
We can resolve the alias to
"../../../path-to-helpher/test.js"but how can we know if it belongs in belongs in test_utils_BBrpfTnm3BB or in test_components_AArpfTnm3AA.We can use the PascalCase convention to know that TestButton should be imported from the
_components_path, but it's quite brittle. A better solution is to resolve the aliases and process them to verify what the functions are but it is more expensive. We would need to do a first pass, where we'd create a Map containing the alias, the resolved path and the metadata of the functions imported by aliases.This is challenging with OXC and even more so with SWC.
diff here
Solution n°2
Alternatively we could extract each top level helper into its own segment with one globals segment, then we can simply deduce the import path by resolving the alias (no need to verify what the function is):
export { topLevelHelper } from './test_topLevelHelper_EErpfTnm3EE';and have each helper segment import from the globals segment as well as the component import the globals file as a side-effect.Similarly we need to resolve
import { topLevelHelper } from "@alias/lib";intoimport { topLevelHelper } from "../../../path-to-helper/test";because the developer could create an alias that points directly to the file itself such asimport { topLevelHelper } from "@alias/path-to-helper/test";in which case we can't guess that it's a barrel file alias import.Pros:
Cons:
This might work better but requires every cog in the machinery to be perfectly in place.
See this stackblitz for a minimal improved repro of Qwik's bundling. We currently use
manualChunksbut for a better result we could useemitFilewithimplicitlyLoadedAfterOneOfto specify which segments are entries (like in theinputarray), and which can be bundled together with those entries.Beta Was this translation helpful? Give feedback.
All reactions