-
Notifications
You must be signed in to change notification settings - Fork 27.1k
perf(dart/transform): Only process deferred libs when necessary #6745
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,7 @@ import 'rewriter.dart'; | |
| /// Transformer responsible for rewriting deferred library loads to enable | ||
| /// initializing the reflector in a deferred way to keep the code with the | ||
| /// deferred library. | ||
| class DeferredRewriter extends Transformer implements LazyTransformer { | ||
| class DeferredRewriter extends AggregateTransformer implements LazyTransformer { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why this needs to be an AggregateTransformer? Instead all non-generated
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or is it just so you can consume the file?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, even better you could only mark
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes :)
So I could have both be primaries and have them interact in such a way that if the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ya ok, it seems a bit more complicated than it needs to be but I can't really think of a way to simplify it either :(. I do still think that the |
||
| final TransformerOptions options; | ||
|
|
||
| DeferredRewriter(this.options); | ||
|
|
@@ -25,23 +25,60 @@ class DeferredRewriter extends Transformer implements LazyTransformer { | |
| } | ||
|
|
||
| @override | ||
| bool isPrimary(AssetId id) => | ||
| id.extension.endsWith('dart') && _isNotGenerated(id); | ||
| dynamic classifyPrimary(AssetId id) { | ||
| // Map <name>.dart and <name>.dart.deferredCount => <name>. | ||
| // Anything else to `null`. | ||
| var extension = null; | ||
| if (id.path.endsWith(DEFERRED_EXTENSION)) { | ||
| extension = DEFERRED_EXTENSION; | ||
| } else if (id.path.endsWith('.dart') && !isGenerated(id.path)) { | ||
| extension = '.dart'; | ||
| } else { | ||
| return null; | ||
| } | ||
| return id.path.substring(0, id.path.length - extension.length); | ||
| } | ||
|
|
||
| @override | ||
| Future apply(Transform transform) async { | ||
| Future apply(AggregateTransform transform) async { | ||
| return zone.exec(() async { | ||
| var asset = transform.primaryInput; | ||
| var reader = new AssetReader.fromTransform(transform); | ||
| var transformedCode = await rewriteDeferredLibraries(reader, asset.id); | ||
| final dartAsset = await _assetToProcess(transform); | ||
| if (dartAsset == null) return; | ||
|
|
||
| var transformedCode = await rewriteDeferredLibraries( | ||
| new AssetReader.fromTransform(transform), dartAsset.id); | ||
| if (transformedCode != null) { | ||
| transform.addOutput(new Asset.fromString(asset.id, transformedCode)); | ||
| transform | ||
| .addOutput(new Asset.fromString(dartAsset.id, transformedCode)); | ||
| } | ||
| }, log: transform.logger); | ||
| } | ||
| } | ||
|
|
||
| bool _isNotGenerated(AssetId id) => !isGenerated(id.path); | ||
| /// Returns the asset we need to process or `null` if none exists. | ||
| /// | ||
| /// Consumes the .dart.deferredCount asset if it is present. | ||
| Future<Asset> _assetToProcess(AggregateTransform transform) async { | ||
| // We only need to process .dart files that have an associated | ||
| // .dart.deferredCount file with a value != "0". | ||
| // | ||
| // The .dart.deferredCount file is generated by a previous phase for files | ||
| // which have deferred imports. An absent .dart.deferredCount asset is the | ||
| // treated the same as a .dart.deferredCount asset with value "0". | ||
| var dartAsset, deferredCountAsset; | ||
| await for (Asset a in transform.primaryInputs) { | ||
| if (a.id.path.endsWith(DEFERRED_EXTENSION)) { | ||
| deferredCountAsset = a; | ||
| } else if (a.id.path.endsWith('.dart')) { | ||
| dartAsset = a; | ||
| } | ||
| } | ||
| if (deferredCountAsset == null) return null; | ||
| // No longer necessary. | ||
| transform.consumePrimary(deferredCountAsset.id); | ||
| if ((await deferredCountAsset.readAsString()) == "0") return null; | ||
| return dartAsset; | ||
| } | ||
| } | ||
|
|
||
| // Visible for testing | ||
| Future<String> rewriteDeferredLibraries(AssetReader reader, AssetId id) async { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
ALL_EXTENSIONSappropriate here? I thought this would be onlyconst ['.dart'].There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought it would be confusing to have the behavior of
toDeferredExtensionbe different from the otherto*Extensionmethods in this file.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well,
toShimmedStylesheetExtensionandtoNonShimmedStylesheetExtensionuseconst [CSS_EXTENSION].Maybe these all really need to be updated, and should
assertthat the uri passed in matches the expected extension?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think of CSS resources as being in a different bucket -- they don't interact with .dart files and vice versa.
What would be the benefit of such a change? I'm against doing the work for performance reasons (unless we can demonstrate that they're actually hurting us). If these are hurting readability, I'm not opposed. It would require searching through the transformers to find wherever these are used & determine the expected extensions and then require updates if we ever want to use them with a new "from" extension, so I don't want to do the work unless there's a clear benefit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update to
to*Extensionfunctions in #6753