11# Developer Tools for Dart
22
3- Here you will find a collection of tools and tips for keeping your application
4- perform well and contain fewer bugs .
3+ Use these tools and techniques to increase your app's performance
4+ and reliability .
55
6- ## Angular debug tools in the dev console
6+ * [ Angular debugging tools] ( #angular-debugging-tools )
7+ * [ Code size] ( #code-size )
8+ * [ Performance] ( #performance )
79
8- Angular provides a set of debug tools that are accessible from any browser's
9- developer console. In Chrome the dev console can be accessed by pressing
10- Ctrl + Shift + j.
1110
12- ### Enabling debug tools
11+ ## Angular debugging tools
1312
14- By default the debug tools are disabled. You can enable debug tools as follows:
13+ Starting with alpha.38, Angular provides a set of debugging tools
14+ that are accessible from any browser's developer console.
15+ In Chrome, you can get to the dev console by pressing
16+ Ctrl + Shift + J (on Mac: Cmd + Opt + J).
17+
18+ ### Enabling the debugging tools
19+
20+ By default the debugging tools are disabled.
21+ Enable the debugging tools as follows:
1522
1623``` dart
1724import 'package:angular2/tools.dart';
1825
19- main() {
26+ main() async {
2027 var appRef = await bootstrap(Application);
2128 enableDebugTools(appRef);
2229}
2330```
2431
25- ### Using debug tools
32+ <!-- Change function name to enableDebuggingTools? -->
2633
27- In the browser open the developer console (Ctrl + Shift + j in Chrome). The
28- top level object is called ` ng ` and contains more specific tools inside it.
2934
30- Example:
35+ ### Using the debugging tools
36+
37+ In the browser, open the dev console. The top-level object is called ` ng ` and
38+ contains more specific tools inside it.
39+
40+ For example, to run the change detection profiler on your app:
41+ <!-- QUESTION: is "on your app" accurate?
42+ is "run the change detection profiler on your app" the best wording? -->
3143
3244``` javascript
45+ // In the dev console:
3346ng .profiler .timeChangeDetection ();
3447```
3548
49+ The [ Change detection profiler] ( #change-detection-profiler ) section
50+ has more details.
51+ <!-- Point to API docs when they're published, if they're useful.
52+ They should be under
53+ http://www.dartdocs.org/documentation/angular2/latest
54+ and/or
55+ https://angular.io/docs/js/latest/api/. -->
56+
57+
3658## Code size
3759
38- Code needs to be downloaded, parsed and executed. Too much code could lead to
60+ Code must be downloaded, parsed, and executed. Too much code can lead to
3961slow application start-up time, especially on slow networks and low-end devices.
40- The tools below will help you identify contributors to code size and keep them
41- in check .
62+ The tools and techniques in this section can help you to identify
63+ unnecessarily large code and to reduce code size .
4264
4365### Finding contributors to code size
4466
67+ Options for investigating code size include the ` --dump-info ` dart2js option,
68+ ng2soyc, ` reflector.trackUsage() ` , and code coverage information
69+ from the Dart VM.
70+
4571#### --dump-info
4672
47- ` dart2js ` has an option ` --dump-info ` that outputs information about what
48- happened during compilation. Enable this option in your transformer options
49- like this:
73+ The ` --dump-info ` option of ` dart2js ` outputs information about what happened
74+ during compilation. You can specify ` --dump-info ` in ` pubspec.yaml ` :
5075
5176``` yaml
5277transformers :
@@ -56,35 +81,39 @@ transformers:
5681 - --dump-info
5782` ` `
5883
59- Use the [visualizer](https://github.com/dart-lang/dump-info-visualizer) to
60- analyze the output or any of the command-line tools documented
61- [here](http://dart-lang.github.io/dart2js_info/doc/api/index.html).
84+ The [Dump Info Visualizer](https://github.com/dart-lang/dump-info-visualizer)
85+ can help you analyze the output.
86+ For more information, see the
87+ [dart2js_info API reference](http://dart-lang.github.io/dart2js_info/doc/api/).
6288
6389#### ng2soyc.dart
6490
6591[ng2soyc](https://github.com/angular/ng2soyc.dart) is a utility for analyzing
6692code size contributors in Angular 2 applications. It groups code size by
67- library. It also assumes your library names follow
68- "package.library.sub-library..." convention and gives code size breakdown at
69- each level. To reduce noise in the output (for very large apps) it also provides
93+ library and, assuming your library names follow
94+ [standard naming conventions](https://www.dartlang.org/articles/style-guide/#do-prefix-library-names-with-the-package-name-and-a-dot-separated-path)
95+ (package.library.sublibrary...), gives the code size breakdown at
96+ each level. To reduce noise in the output of very large apps, ng2soyc provides
7097an option to hide libraries that are too small, so you can focus on the biggest
7198contributors.
7299
73100#### Track unused reflection data
74101
75- Call ` reflector.trackUsage()` to cause it to track reflection information used
102+ <!-- QUESTION: How do you get access to reflector & ReflectionInfo? -->
103+
104+ Call ` reflector.trackUsage()` to track reflection information used
76105by the application. Reflection information (`ReflectionInfo`) is a data
77106structure that stores information about your application that Angular uses for
78107locating DI factories, generated change detectors and other code related to a
79108given type. After exercising your application, call `reflector.listUnusedKeys()`
80109to get a list of types and functions whose reflection information was retained
81- but was never used by the application.
110+ but never used by the application.
82111
83112# ### Use code coverage to find dead code
84113
85- When running in Dartium (or in Dart VM in general) you can request code
114+ When running in Dartium (or in the Dart VM, in general) you can request code
86115coverage information from the VM. You can either use
87- [observatory](https://www.dartlang.org/tools/observatory/), or download
116+ [observatory](https://www.dartlang.org/tools/observatory/) or download
88117the coverage file and use your own tools to inspect it. Lines of code that are
89118not covered are top candidates for dead code.
90119
@@ -93,10 +122,16 @@ code, only necessary evidence. It is perfectly possible that you simply didn't
93122exercise your application in a way that triggers the execution of uncovered
94123code. A common example is error handling code. Just because your testing never
95124encountered an error does not mean the error won't happen in production. You
96- therefore do not have to rush and remove all the `catch` blocks.
125+ therefore don't have to rush and remove all the `catch` blocks.
97126
98127# ## Reducing code size
99128
129+ To reduce code size, you can disable reflection,
130+ enable minification, and manually remove dead code.
131+ You can also try less safe options such as
132+ telling dart2js to trust type annotations.
133+
134+
100135# ### Disable reflection
101136
102137` dart:mirrors` allows discovering program metadata at runtime. However, this
@@ -129,19 +164,19 @@ example:
129164/// This function decides which serialization format to use
130165void setupSerializers() {
131166 if (server.doYouSupportProtocolBuffers()) {
132- useProtobufSerializaers ();
167+ useProtobufSerializers ();
133168 } else {
134- useJsonSerializaers ();
169+ useJsonSerializers ();
135170 }
136171}
137172` ` `
138173
139174In this example the application asks the server what kind of serialization
140- format it uses and dynamically chooses one or the other. `dart2js` could never
141- tell whether the server responds with yes or no and so it must retain both
142- kinds of serializers. However, you, as the developer of the application, may
143- know in advance that your server supports protocol buffers and so you could
144- remove that `if` block entirely and default to protocol buffers.
175+ format it uses and dynamically chooses one or the other. `dart2js` can't
176+ tell whether the server responds with yes or no, so it must retain both
177+ kinds of serializers. However, if you know that your server supports
178+ protocol buffers, you can remove that `if` block entirely and default to
179+ protocol buffers.
145180
146181Code coverage (see above) is a good way to find dead code in your app.
147182
@@ -163,7 +198,7 @@ booleans are never `null` when performing arithmetic, and that your program
163198does not run into range error when operating on lists, letting the compiler
164199remove some of the error checking code.
165200
166- These options are specified in `pubspec.yaml`.
201+ Specify these options in `pubspec.yaml`.
167202
168203Example :
169204
@@ -196,35 +231,36 @@ Change detection profiler repeatedly performs change detection without invoking
196231any user actions, such as clicking buttons or entering text in input fields. It
197232then computes the average amount of time it took to perform a single cycle of
198233change detection in milliseconds and prints it to the console. This number
199- depends on the current state of the UI. You will likely see different numbers
234+ depends on the current state of the UI. You are likely to see different numbers
200235as you go from one screen in your application to another.
201236
202237# ### Running the profiler
203238
204- Enable debug tools (see above), then in the dev console enter the following :
239+ Enable the debugging tools (see above),
240+ then in the dev console enter the following :
205241
206242` ` ` javascript
207243ng.profiler.timeChangeDetection();
208244` ` `
209245
210- The results will be printed to the console.
246+ The results are printed to the console.
211247
212- # ### Recording CPU profile
248+ # ### Recording CPU profiles
213249
214- Pass `{record : true}` an argument :
250+ To record a profile, pass `{record : true}` to `timeChangeDetection()` :
215251
216252` ` ` javascript
217253ng.profiler.timeChangeDetection({record: true});
218254` ` `
219255
220- Then open the " Profiles" tab. You will see the recorded profile titled
221- " Change Detection" . In Chrome, if you record the profile repeatedly, all the
222- profiles will be nested under " Change Detection" .
256+ Then open the ** Profiles** tab. The recorded profile has the title
257+ ** Change Detection** . In Chrome, if you record the profile repeatedly, all the
258+ profiles are nested under Change Detection.
223259
224260# ### Interpreting the numbers
225261
226- In a properly- designed application repeated attempts to detect changes without
227- any user actions should result in no changes to be applied on the UI. It is
262+ In a properly designed application, repeated attempts to detect changes without
263+ any user actions result in no changes to the UI. It is
228264also desirable to have the cost of a user action be proportional to the amount
229265of UI changes required. For example, popping up a menu with 5 items should be
230266vastly faster than rendering a table of 500 rows and 10 columns. Therefore,
@@ -248,24 +284,26 @@ Then look for hot spots using
248284# ### Reducing change detection cost
249285
250286There are many reasons for slow change detection. To gain intuition about
251- possible causes it would help to understand how change detection works. Such a
252- discussion is outside the scope of this document (TODO link to docs), but here
253- are some key concepts in brief.
287+ possible causes it helps to understand how change detection works. Such a
288+ discussion is outside the scope of this document,
289+ but here are some key concepts.
290+
291+ <!-- TODO : link to change detection docs -->
254292
255- By default Angular uses "dirty checking" mechanism for finding model changes.
293+ By default, Angular uses a _dirty checking_ mechanism to find model changes.
256294This mechanism involves evaluating every bound expression that's active on the
257295UI. These usually include text interpolation via `{{expression}}` and property
258296bindings via `[prop]="expression"`. If any of the evaluated expressions are
259- costly to compute they could contribute to slow change detection. A good way to
297+ costly to compute, they might contribute to slow change detection. A good way to
260298speed things up is to use plain class fields in your expressions and avoid any
261- kinds of computation. Example :
299+ kind of computation. For example :
262300
263301` ` ` dart
264302@View(
265303 template: '<button [enabled]="isEnabled">{{title}}</button>'
266304)
267305class FancyButton {
268- // GOOD: no computation, just return the value
306+ // GOOD: no computation, just returns the value
269307 bool isEnabled;
270308
271309 // BAD: computes the final value upon request
@@ -274,11 +312,13 @@ class FancyButton {
274312}
275313` ` `
276314
277- Most cases like these could be solved by precomputing the value and storing the
315+ Most cases like these can be solved by precomputing the value and storing the
278316final value in a field.
279317
280- Angular also supports a second type of change detection - the "push" model. In
281- this model Angular does not poll your component for changes. Instead, the
282- component " tells" Angular when it changes and only then does Angular perform
318+ Angular also supports a second type of change detection : the _push_ model. In
319+ this model, Angular does not poll your component for changes. Instead, the
320+ component tells Angular when it changes, and only then does Angular perform
283321the update. This model is suitable in situations when your data model uses
284- observable or immutable objects (also a discussion for another time).
322+ observable or immutable objects.
323+
324+ <!-- TODO : link to discussion of push model -->
0 commit comments