X Tutup
Skip to content

Commit f56df65

Browse files
Tim Blasikegluneq
authored andcommitted
perf(dart/transform): Only process deferred libs when necessary
Previously, every .dart file in a package was processed to ensure proper initialization of deferred loaded libraries. Update the transformer to avoid processing libraries which we know do not import any deferred libraries. Closes #6745
1 parent 3a40cd7 commit f56df65

File tree

3 files changed

+73
-11
lines changed

3 files changed

+73
-11
lines changed

modules_dart/transform/lib/src/transform/common/names.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const SETUP_METHOD_NAME = 'initReflector';
66
const REFLECTOR_VAR_NAME = 'reflector';
77
const TRANSFORM_DYNAMIC_MODE = 'transform_dynamic';
88
const CSS_EXTENSION = '.css';
9+
const DEFERRED_EXTENSION = '.dart.deferredCount';
910
const SHIMMED_STYLESHEET_EXTENSION = '.css.shim.dart';
1011
const NON_SHIMMED_STYLESHEET_EXTENSION = '.css.dart';
1112
const META_EXTENSION = '.ng_meta.json';
@@ -21,8 +22,10 @@ const TEMPLATE_EXTENSION = '.template.dart';
2122

2223
/// Note that due to the implementation of `_toExtension`, ordering is
2324
/// important. For example, putting '.dart' first in this list will cause
24-
/// incorrect behavior.
25+
/// incorrect behavior because it will (incompletely) match '.template.dart'
26+
/// files.
2527
const ALL_EXTENSIONS = const [
28+
DEFERRED_EXTENSION,
2629
META_EXTENSION,
2730
SUMMARY_META_EXTENSION,
2831
TEMPLATE_EXTENSION,
@@ -36,6 +39,7 @@ const ALL_EXTENSIONS = const [
3639
/// any files named like transformer outputs will be reported as generated.
3740
bool isGenerated(String uri) {
3841
return const [
42+
DEFERRED_EXTENSION,
3943
META_EXTENSION,
4044
NON_SHIMMED_STYLESHEET_EXTENSION,
4145
SHIMMED_STYLESHEET_EXTENSION,
@@ -44,6 +48,10 @@ bool isGenerated(String uri) {
4448
].any((ext) => uri.endsWith(ext));
4549
}
4650

51+
/// Returns `uri` with its extension updated to [DEFERRED_EXTENSION].
52+
String toDeferredExtension(String uri) =>
53+
_toExtension(uri, ALL_EXTENSIONS, DEFERRED_EXTENSION);
54+
4755
/// Returns `uri` with its extension updated to [META_EXTENSION].
4856
String toMetaExtension(String uri) =>
4957
_toExtension(uri, ALL_EXTENSIONS, META_EXTENSION);

modules_dart/transform/lib/src/transform/deferred_rewriter/transformer.dart

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import 'rewriter.dart';
1414
/// Transformer responsible for rewriting deferred library loads to enable
1515
/// initializing the reflector in a deferred way to keep the code with the
1616
/// deferred library.
17-
class DeferredRewriter extends Transformer implements LazyTransformer {
17+
class DeferredRewriter extends AggregateTransformer implements LazyTransformer {
1818
final TransformerOptions options;
1919

2020
DeferredRewriter(this.options);
@@ -25,23 +25,60 @@ class DeferredRewriter extends Transformer implements LazyTransformer {
2525
}
2626

2727
@override
28-
bool isPrimary(AssetId id) =>
29-
id.extension.endsWith('dart') && _isNotGenerated(id);
28+
dynamic classifyPrimary(AssetId id) {
29+
// Map <name>.dart and <name>.dart.deferredCount => <name>.
30+
// Anything else to `null`.
31+
var extension = null;
32+
if (id.path.endsWith(DEFERRED_EXTENSION)) {
33+
extension = DEFERRED_EXTENSION;
34+
} else if (id.path.endsWith('.dart') && !isGenerated(id.path)) {
35+
extension = '.dart';
36+
} else {
37+
return null;
38+
}
39+
return id.path.substring(0, id.path.length - extension.length);
40+
}
3041

3142
@override
32-
Future apply(Transform transform) async {
43+
Future apply(AggregateTransform transform) async {
3344
return zone.exec(() async {
34-
var asset = transform.primaryInput;
35-
var reader = new AssetReader.fromTransform(transform);
36-
var transformedCode = await rewriteDeferredLibraries(reader, asset.id);
45+
final dartAsset = await _assetToProcess(transform);
46+
if (dartAsset == null) return;
47+
48+
var transformedCode = await rewriteDeferredLibraries(
49+
new AssetReader.fromTransform(transform), dartAsset.id);
3750
if (transformedCode != null) {
38-
transform.addOutput(new Asset.fromString(asset.id, transformedCode));
51+
transform
52+
.addOutput(new Asset.fromString(dartAsset.id, transformedCode));
3953
}
4054
}, log: transform.logger);
4155
}
42-
}
4356

44-
bool _isNotGenerated(AssetId id) => !isGenerated(id.path);
57+
/// Returns the asset we need to process or `null` if none exists.
58+
///
59+
/// Consumes the .dart.deferredCount asset if it is present.
60+
Future<Asset> _assetToProcess(AggregateTransform transform) async {
61+
// We only need to process .dart files that have an associated
62+
// .dart.deferredCount file with a value != "0".
63+
//
64+
// The .dart.deferredCount file is generated by a previous phase for files
65+
// which have deferred imports. An absent .dart.deferredCount asset is the
66+
// treated the same as a .dart.deferredCount asset with value "0".
67+
var dartAsset, deferredCountAsset;
68+
await for (Asset a in transform.primaryInputs) {
69+
if (a.id.path.endsWith(DEFERRED_EXTENSION)) {
70+
deferredCountAsset = a;
71+
} else if (a.id.path.endsWith('.dart')) {
72+
dartAsset = a;
73+
}
74+
}
75+
if (deferredCountAsset == null) return null;
76+
// No longer necessary.
77+
transform.consumePrimary(deferredCountAsset.id);
78+
if ((await deferredCountAsset.readAsString()) == "0") return null;
79+
return dartAsset;
80+
}
81+
}
4582

4683
// Visible for testing
4784
Future<String> rewriteDeferredLibraries(AssetReader reader, AssetId id) async {

modules_dart/transform/lib/src/transform/directive_processor/transformer.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class DirectiveProcessor extends Transformer implements LazyTransformer {
3333

3434
@override
3535
declareOutputs(DeclaringTransform transform) {
36+
transform.declareOutput(_deferredAssetId(transform.primaryId));
3637
transform.declareOutput(_ngSummaryAssetId(transform.primaryId));
3738
}
3839

@@ -49,6 +50,17 @@ class DirectiveProcessor extends Transformer implements LazyTransformer {
4950
}
5051
transform.addOutput(new Asset.fromString(
5152
_ngSummaryAssetId(primaryId), _encoder.convert(ngMeta.toJson())));
53+
54+
var deferredCount = 0;
55+
if (ngMeta.ngDeps != null) {
56+
deferredCount = ngMeta.ngDeps.imports.where((i) => i.isDeferred).length;
57+
}
58+
if (deferredCount > 0) {
59+
// The existence of this file with the value != "0" signals
60+
// DeferredRewriter that the associated .dart file needs attention.
61+
transform.addOutput(new Asset.fromString(
62+
_deferredAssetId(primaryId), deferredCount.toString()));
63+
}
5264
}, log: transform.logger);
5365
}
5466
}
@@ -57,3 +69,8 @@ AssetId _ngSummaryAssetId(AssetId primaryInputId) {
5769
return new AssetId(
5870
primaryInputId.package, toSummaryExtension(primaryInputId.path));
5971
}
72+
73+
AssetId _deferredAssetId(AssetId primaryInputId) {
74+
return new AssetId(
75+
primaryInputId.package, toDeferredExtension(primaryInputId.path));
76+
}

0 commit comments

Comments
 (0)
X Tutup