-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perf: allow tree-shaking for built-in metadata managers #960
Comments
Just reminded that maybe annotating as pure could work. And it does indeed. See here an example to mark as pure the Open Graph image metadata provider: /**
* Manages the {@link OpenGraph.image} metadata
* @public
*/
export const OPEN_GRAPH_IMAGE_METADATA_PROVIDER =
/* @__PURE__ */ provideOpenGraphManager(
_GLOBAL_IMAGE,
/* @__PURE__ */ _withModuleManagerSameGlobalKey(),
/* @__PURE__ */ withManagerObjectMerging(),
/* @__PURE__ */ _withModuleManagerSetterFactory(
(metaElementsService: NgxMetaElementsService) => (value) => {
const imageUrl = value?.url?.toString()
const effectiveValue: OpenGraph[typeof _GLOBAL_IMAGE] = _isDefined(
imageUrl,
)
// ...
}
)
) This works in v18 with ESBuild via the Argument calls must be also be commented as explained in ESBuild docs:
|
Hence with this in mind, possible options change:
First, skipping first option and more options implying keeping
Better to deprecate them for those two reasons. And use functions by default from now on. This leaves us with options 2 and 3. And after balancing pros and cons, seems option 2 is the best one. Breaking changes are avoided, but the benefits of functions are introduced anyway. At some point, |
After findings in #891 , another thing that isn't tree shakeable right now are metadata managers.
Given the metadata manager
const
ants are defined by calling a helper function to create the provider. So when importing anything from a built-in module, allconst
ants exported are created by calling those helper functions. And given the bundler doesn't know if those calls have side-effects, they are not removed from the bundle even if unused.Implementing tree-shakeable ones is as easy as defining a function instead of a
const
. Given until the function isn't called, no side-effects may happen so the bundler safely removes those from bundle if unused.In few words:
The issue is that if just adding the new function-based tree-shakeable providers, existing ones will be kept in the bundle even if unused as they're not tree-shakeable. So in order to allow tree-shaking, old
const
ones must be removed.Warning
This change implies bundle size increase though
After quickly trying, here's the extra amount of uncompressed bytes added to the bundle if:
const
ones, not using them forprovideX
: 4 bytes x 26 managers = 104 bytesconst
ones, use them forprovideX
: 10 bytes x 26 managers = 260 bytesconst
ones, use function ones forprovideX
: 6 bytes x 26 managers = 156 bytesRemoving old
const
ones is a breaking change 🤔It's a beta version, so APIs are subject to change. But even in that scenario, I'd prefer to avoid any kind of breaking change. Or at least provide an auto-magic migration / schematic if can't be avoided like it seems the case.
Indeed adding schematics would help in other places such as deprecations
UPDATE: finally can do this without introducing a breaking change. TL;DR: pure annotations. See below 👇
The text was updated successfully, but these errors were encountered: