Skip to content

Commit 26348d6

Browse files
committed
Updated the README
1 parent 736a92a commit 26348d6

File tree

1 file changed

+178
-2
lines changed

1 file changed

+178
-2
lines changed

Chapter_07/README.md

Lines changed: 178 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,180 @@
1-
Chapter 7: Prod Deployment
1+
Chapter 7: Production Deployment
22
==========================
33

4-
WIP...
4+
# Running the Sample App
5+
6+
Before running the app, make sure you run the code generators (see below for
7+
more info) like so:
8+
9+
```
10+
dart -c bin/generator.dart
11+
```
12+
13+
# Overview
14+
15+
When deploying your app in production you need to make sure that:
16+
17+
1. compiled ([dart2js][dart2js]) output is small
18+
1. application performs as well in JavaScript as it does in Dart VM
19+
1. application runs not only in Chrome, but other supported modern browsers
20+
21+
AngularDart and di heavily rely on [dart:mirrors][dart-mirrors-api] APIs.
22+
Mirrors allow AngularDart to provide super fast developer friendly edit-refresh
23+
cycle, without needing to run slow compilers and code generators.
24+
However, mirrors come at a cost:
25+
26+
1. use of mirrors disables very important optimizations performed by
27+
[dart2js][dart2js] compiler, such as tree-shaking, which allows removal
28+
of unused code from the output, resulting in very large JavaScript file.
29+
1. mirrors are much slower compared to static Dart code, which might not be
30+
an issue for smaller/medium applications, but in larger apps might become
31+
noticeable. Dart team is constantly working on improving performance of
32+
mirrors, so long-term it's not a problem, but in short-term it's something
33+
you might need to think about.
34+
35+
Here we will provide some tip on these subjects.
36+
37+
# Managing Compiled Code Size
38+
39+
## Minification
40+
41+
dart2js allows you to minify the resulting JavaScript, which:
42+
43+
* removes unnecessary whitespace
44+
* shortens the class and field names
45+
46+
Minification can reduce your resulting JavaScript by 2-3x.
47+
48+
All you need to do, is to include ```--minify``` flag in dart2js command line.
49+
50+
```
51+
dart2js web/main.dart --minify -o web/main.dart.js
52+
```
53+
54+
## ```@MirrorsUsed```
55+
56+
To help manage the code size of applications that use mirrors, Dart provides
57+
[```@MirrorsUsed```][mirrors-used] annotation using which you can tell dart2js
58+
compiler which targets (classes, libraries, annotations, etc.) are being
59+
reflected on. This way dart2js can skip all the unused stuff thus radically
60+
reducing the output size.
61+
62+
```@MirrorsUsed``` is often hard to get right as it really depends on how/if
63+
you use code generation (discussed later in "Optimizing Runtime Performance"
64+
chapter). Assuming you do use code generation (as we do in this chapter) your
65+
annotation could look something like this:
66+
67+
```
68+
@MirrorsUsed(
69+
targets: const [
70+
'angular.core',
71+
'angular.core.dom',
72+
'angular.core.parser',
73+
'angular.routing',
74+
NodeTreeSanitizer
75+
],
76+
metaTargets: const [
77+
NgInjectableService,
78+
NgComponent,
79+
NgDirective,
80+
NgController,
81+
NgFilter,
82+
NgAttr,
83+
NgOneWay,
84+
NgOneWayOneTime,
85+
NgTwoWay,
86+
NgCallback
87+
],
88+
override: '*'
89+
)
90+
import 'dart:mirrors';
91+
```
92+
93+
Here you are essentually telling dart2js that your application reflects on
94+
```angular.core```, ```angular.core.dom```, ```angular.core.parser```, etc.
95+
libraries, as well as on ```NodeTreeSanitizer``` class, and annotations
96+
(metaTargets) like ```NgInjectableService```, ```NgComponent```,
97+
```NgDirective```, etc.
98+
99+
### Debugging
100+
101+
If it happens that you have misconfigured ```@MirrorsUsed```, you will likely
102+
be seeing errors like "Cannot find class for: Foo" or your
103+
directives/components/controllers will be ignored when running in JavaScript.
104+
Usually, the easiest fix is to just add that class (or the whole library)
105+
to ```@MirrorsUsed.targets```.
106+
107+
108+
# Optimizing Runtime Performance
109+
110+
Currently there are two code generators: di and AngularDart Parser generators.
111+
112+
## di Code Generator
113+
114+
di.dart Injector uses dart:mirrors APIs for retrieving types of constructor
115+
parameters and invoking the constructor to create new instances. The generator
116+
generates static code for creating new instances and resolving dependencies.
117+
118+
You can find an example of how to use the di generator in
119+
```bin/generator.dart``` file.
120+
121+
## AngularDart Parser Generator
122+
123+
AngularDart Parser Generator extracts all expressions from your application
124+
and then compiles them into Dart, so at runtime it doesn't have to parse those
125+
expressions and while invoking the expressions it uses pre-generated code to
126+
access fields and methods, so it doesn't have to use mirrors.
127+
128+
You can find an example of how to use the parser generator in
129+
```bin/generator.dart``` file.
130+
131+
## Code Generators and Development Mode
132+
133+
You should not be using code generators during development, as they are slow
134+
and can significanly degrade productivity. Instead, during development it's
135+
better to use dynamic versions of di Injector and Parser and use generators
136+
only for testing and production.
137+
138+
In ```lib/main.dart``` you can see ```initializer-prod.dart``` file being
139+
imported, which has ```initializer-dev.dart``` counterpart. Switching between
140+
those two file will allow you to switch between prod and dev modes. You will
141+
need to run the generator script before using the prod mode.
142+
143+
It is highly recommended that you automate (via a script or a flag on the
144+
server) the prod/dev mode switching to minimize the chance of dev mode being
145+
released into production.
146+
147+
# Cross-browser Support
148+
149+
Angular components use [Shadow DOM][shadowdom101], but unfortunately it's not
150+
natively supported in all modern browsers, so you would need to use a
151+
[polyfill][shadow-dom-polyfill].
152+
153+
Make sure you include ```shadow_dom``` package in dependencies in pubspec.yaml.
154+
155+
```
156+
dependencies:
157+
shadow_dom: any
158+
```
159+
160+
And include the script tag:
161+
162+
```
163+
<script src="packages/shadow_dom/shadow_dom.debug.js"></script>
164+
```
165+
166+
or the debug version:
167+
168+
```
169+
<script src="packages/shadow_dom/shadow_dom.debug.js"></script>
170+
```
171+
172+
**NOTE:** using the polyfill has [some limitations][shadowdom-limitations],
173+
so make sure you are aware of those limitations before you start using it.
174+
175+
[dart-mirrors-api]: https://api.dartlang.org/docs/channels/stable/latest/dart_mirrors.html
176+
[shadowdom101]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/
177+
[shadowdom-limitations]: https://github.com/polymer/ShadowDOM#known-limitations
178+
[shadow-dom-polyfill]: http://pub.dartlang.org/packages/shadow_dom
179+
[dart2js]: https://www.dartlang.org/docs/dart-up-and-running/contents/ch04-tools-dart2js.html
180+
[mirrors-used]: https://api.dartlang.org/docs/channels/stable/latest/dart_mirrors/MirrorsUsed.html

0 commit comments

Comments
 (0)