Skip to content
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

Optimize eyeglass asset installation. #226

Merged
merged 19 commits into from
Mar 28, 2019

Conversation

chriseppstein
Copy link
Contributor

Eyeglass assets are installed for each invocation of asset-url() which can add performance overhead at scale especially when the same asset is installed many times.

ember-cli-eyeglass now intercepts asset installation and records which assets are installed to which locations. It does this by writing all those assets into a single tree for the entire app and all addons and engines after they are built, which it only needs to do once per distinct url. To accomplish this, I wrote a new broccoli-plugin in this commit which makes in possible to symlink arbitrary files into an output tree.

This PR has the benefit of also ensuring that asset urls can be resolved to any path instead of forcing those urls to resolve to a location relative to the current tree, which fixes a long-standing annoyance that forced assets to be duplicated in engines (note: this patch doesn't change the asset installation locations -- a custom resolver is required to accomplish this for now).

This patch was made more tricky because of my bone-headed insistence of having a generic broccoli sass plugin as the base class for the broccoli eyeglass plugin. The pure sass plugin is in charge of the caching strategy so it uses events to delegate knowledge of how additional outputs are restored from cache to the external code that is invoking this plugin and doing weird things with assets outside the output tree.

A few other things to note:

  • ember-cli-eyeglass addons (and the broccoli eyeglass compiler plugin) have a slightly different annotation now (it will show the parent app as well as the addon/engine name). If there's code that's relying on the annotation names, it may break or cause reporting inconsistencies.
  • When persistent caching is enabled, it now automatically sets up any addons or engines to use a different persistent cache key instead of requiring each one to set their cache key in the configuration.
  • The format of the output cache data has changed... as such the cache key for that data has a version which has been incremented to forcibly invalidate all the old caches in the wrong format.
  • The old handling for non-css assets in ember apps has been removed because this new approach supersedes it.

TODO: I need to add some additional test cases.

If additional output from a sass compilation is written to a location
that is outside of the broccoli output tree we can't just ignore it
because the persistent cache hit would not create the same outputs. But
because the output locatio is outside of the tree, it's not this
plugin's responsbility to restore that output.

To manage this, the "additional-output" event can now provide a source
location and target url for the asset. When there's a persistent cache
hit, the "cached-asset" event is fired with the source location and
target url that was provided by "additional-output". In this way the
build integration that is using this plugin must decide how to restore
the cache for those files correctly.
Eyeglass assets are installed for each invocation of asset-url() which
can add performance overhead at scale especially when the same asset is
installed many times.

ember-cli-eyeglass now intercepts asset installation and records which
assets are installed to which locations. It does this by writing all
those assets into a single tree for the entire app and all addons and
engines.

This has the benefit of also ensuring that asset urls can be
resolved to any path instead of forcing those urls to resolve to a
location relative to the current tree, which fixes a long-standing
annoyance that forced assets to be duplicated in engines (note: this
patch doesn't change the asset installation locations -- a custom
resolver is required to accomplish this for now).
@chriseppstein chriseppstein force-pushed the perf_tuning_asset_install branch from 07509f2 to 8d0402a Compare March 21, 2019 10:51
@stefanpenner
Copy link
Member

@chriseppstein nice, I plan to take a thorough look this evening/weekend.

packages/broccoli-eyeglass/src/index.ts Show resolved Hide resolved
packages/broccoli-eyeglass/src/index.ts Show resolved Hide resolved
*
* BroccoliSymbolicLinker
*/
export class BroccoliSymbolicLinker extends BroccoliPlugin {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this plugin likely needs to be tested, https://github.com/broccolijs/broccoli-test-helper can be quite helpful for that.

packages/ember-cli-eyeglass/src/index.ts Outdated Show resolved Hide resolved
packages/ember-cli-eyeglass/src/index.ts Show resolved Hide resolved
packages/ember-cli-eyeglass/src/index.ts Outdated Show resolved Hide resolved
packages/ember-cli-eyeglass/src/index.ts Show resolved Hide resolved
@stefanpenner
Copy link
Member

@chriseppstein I think the overall approach here is very interesting. Good way to have a single "install" step.

@chriseppstein chriseppstein changed the base branch from perf_tuning to master March 28, 2019 20:28
@chriseppstein chriseppstein changed the base branch from master to perf_tuning March 28, 2019 20:28
@chriseppstein chriseppstein merged commit 50be128 into perf_tuning Mar 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants