|
| 1 | +# Developer Tools for Dart |
| 2 | + |
| 3 | +Here you will find a collection of tools and tips for keeping your application |
| 4 | +perform well and contain fewer bugs. |
| 5 | + |
| 6 | +## Code size |
| 7 | + |
| 8 | +Code needs to be downloaded, parsed and executed. Too much code could lead to |
| 9 | +slow application start-up time, especially on slow networks and low-end devices. |
| 10 | +The tools below will help you identify contributors to code size and keep them |
| 11 | +in check. |
| 12 | + |
| 13 | +### Finding contributors to code size |
| 14 | + |
| 15 | +#### --dump-info |
| 16 | + |
| 17 | +`dart2js` has an option `--dump-info` that outputs information about what |
| 18 | +happened during compilation. Enable this option in your transformer options |
| 19 | +like this: |
| 20 | + |
| 21 | +```yaml |
| 22 | +transformers: |
| 23 | +... |
| 24 | +- $dart2js: |
| 25 | + commandLineOptions: |
| 26 | + - --dump-info |
| 27 | +``` |
| 28 | +
|
| 29 | +Use the [visualizer](https://github.com/dart-lang/dump-info-visualizer) to |
| 30 | +analyze the output or any of the command-line tools documented |
| 31 | +[here](http://dart-lang.github.io/dart2js_info/doc/api/index.html). |
| 32 | +
|
| 33 | +#### ng2soyc.dart |
| 34 | +
|
| 35 | +[ng2soyc](https://github.com/angular/ng2soyc.dart) is a utility for analyzing |
| 36 | +code size contributors in Angular 2 applications. It groups code size by |
| 37 | +library. It also assumes your library names follow |
| 38 | +"package.library.sub-library..." convention and gives code size breakdown at |
| 39 | +each level. To reduce noise in the output (for very large apps) it also provides |
| 40 | +an option to hide libraries that are too small, so you can focus on the biggest |
| 41 | +contributors. |
| 42 | +
|
| 43 | +#### Use code coverage to find dead code |
| 44 | +
|
| 45 | +When running in Dartium (or in Dart VM in general) you can request code |
| 46 | +coverage information from the VM. You can either use |
| 47 | +[observatory](https://www.dartlang.org/tools/observatory/), or download |
| 48 | +the coverage file and use your own tools to inspect it. Lines of code that are |
| 49 | +not covered are top candidates for dead code. |
| 50 | +
|
| 51 | +Keep in mind, however, that uncovered code is not sufficient evidence of dead |
| 52 | +code, only necessary evidence. It is perfectly possible that you simply didn't |
| 53 | +exercise your application in a way that triggers the execution of uncovered |
| 54 | +code. A common example is error handling code. Just because your testing never |
| 55 | +encountered an error does not mean the error won't happen in production. You |
| 56 | +therefore do not have to rush and remove all the `catch` blocks. |
| 57 | + |
| 58 | +### Reducing code size |
| 59 | + |
| 60 | +#### Disable reflection |
| 61 | + |
| 62 | +`dart:mirrors` allows discovering program metadata at runtime. However, this |
| 63 | +means that `dart2js` needs to retain that metadata and thus increase the size |
| 64 | +of resulting JS output. In practice, however, it is possible to extract most |
| 65 | +metadata necessary for your metaprogramming tasks statically using a |
| 66 | +transformer and `package:analyzer`, and act on it before compiling to JS. |
| 67 | + |
| 68 | +#### Enable minification |
| 69 | + |
| 70 | +Minification shortens all your `longMethodNames` into 2- or 3-letter long |
| 71 | +symbols. `dart2js` ensures that this kind of renaming is done safely, without |
| 72 | +breaking the functionality of your programs. You can enable it in `pubspec.yaml` |
| 73 | +under `$dart2js` transformer: |
| 74 | + |
| 75 | +```yaml |
| 76 | +transformers: |
| 77 | +... |
| 78 | +- $dart2js: |
| 79 | + minify: true |
| 80 | +``` |
| 81 | + |
| 82 | +#### Manually remove dead code |
| 83 | + |
| 84 | +`dart2js` comes with dead code elimination out-of-the-box. However, it may not |
| 85 | +always be able to tell if a piece of code could be used. Consider the following |
| 86 | +example: |
| 87 | + |
| 88 | +```dart |
| 89 | +/// This function decides which serialization format to use |
| 90 | +void setupSerializers() { |
| 91 | + if (server.doYouSupportProtocolBuffers()) { |
| 92 | + useProtobufSerializaers(); |
| 93 | + } else { |
| 94 | + useJsonSerializaers(); |
| 95 | + } |
| 96 | +} |
| 97 | +``` |
| 98 | + |
| 99 | +In this example the application asks the server what kind of serialization |
| 100 | +format it uses and dynamically chooses one or the other. `dart2js` could never |
| 101 | +tell whether the server responds with yes or no and so it must retain both |
| 102 | +kinds of serializers. However, you, as the developer of the application, may |
| 103 | +know in advance that your server supports protocol buffers and so you could |
| 104 | +remove that `if` block entirely and default to protocol buffers. |
| 105 | + |
| 106 | +Code coverage (see above) is a good way to find dead code in your app. |
| 107 | + |
| 108 | +#### Unsafe options |
| 109 | + |
| 110 | +Dart also provides more aggressive optimization options. However, you have to |
| 111 | +be careful when using them and as of today the benefits aren't that clear. If |
| 112 | +your type annotations are inaccurate you may end up with non-Darty runtime |
| 113 | +behavior, including the classic "undefined is not a function" tautology, as |
| 114 | +well as the "keep on truckin'" behavior, e.g. `null + 1 == 1` and |
| 115 | +`{} + [] == 0`. |
| 116 | + |
| 117 | +`--trust-type-annotations` tells `dart2js` to trust that your type annotations |
| 118 | +are correct. So if you have a function `foo(Bar bar)` the compiler can omit the |
| 119 | +check that `bar` is truly `Bar` when calling methods on it. |
| 120 | + |
| 121 | +`--trust-primitives` tells `dart2js` that primitive types, such as numbers and |
| 122 | +booleans are never `null` when performing arithmetic, and that your program |
| 123 | +does not run into range error when operating on lists, letting the compiler |
| 124 | +remove some of the error checking code. |
| 125 | + |
| 126 | +These options are specified in `pubspec.yaml`. |
| 127 | + |
| 128 | +Example: |
| 129 | + |
| 130 | +```yaml |
| 131 | +transformers: |
| 132 | +... |
| 133 | +- $dart2js: |
| 134 | + commandLineOptions: |
| 135 | + - --trust-type-annotations |
| 136 | + - --trust-primitives |
| 137 | +``` |
0 commit comments