Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

feat(prod-deploy): add prod deploy chapter #3043

Merged
merged 7 commits into from
Jan 27, 2017

Conversation

filipesilva
Copy link
Contributor

This PR adds the Production Deployment Cookbook.

/cc @wardbell @Foxandxss @DeborahK

Copy link
Contributor

@DeborahK DeborahK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job! I reviewed the doc and here is my feedback.

* [Server configuration](#server-configuration)
* [Why fallback to `index.html`?](#why-fallback-to-index-html-)
* [Fallback configuration examples](#fallback-configuration-examples)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great way to organize this content!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

After creating your brand new Angular app you'll want to put it online for the world to see.

Your development setup is optimized for build speed and rapid iteration, but when
deployment to production you'll want to optimize for loading speed and payload size.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should "deployment" be "deploying" here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right you are, fixing.

It is already working locally after all, so it should work live.

1. Copy over your local project folder to your server.
2. In your server, edit `index.html` to have the right `<base href="/">` tag. If you are
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using "correct" instead of "right" here since right could mean right/left.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

The simplest possible way to deploy your app is to use your development environment.
It is already working locally after all, so it should work live.

1. Copy over your local project folder to your server.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my daughter's case, she had a limited amount of allocated space on the server and could not copy all of the node_module folder. Consider mentioning using npm install --production here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added note about production installs.

There are several techniques for achieving a smaller payload for your app:

- Bundling: concatenating several modules into a single file (bundle).
- Inlining: add html and css as strings inside components.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be "adding" to match the other "-ing" words used here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That one was added later and I forgot to do just that, good catch!


That is why the server needs to be configured to fallback to `index.html`.
When a user asks the server for any route (that isn't a file), you want the server to *always*
return default page that boots up Angular.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"return the" (missing "the")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

That is why the server needs to be configured to fallback to `index.html`.
When a user asks the server for any route (that isn't a file), you want the server to *always*
return default page that boots up Angular.
After Angular is loaded and bootstrapped the router will look at the address bar and take
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"will look" -> "looks" and "take" -> "takes"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

When a user asks the server for any route (that isn't a file), you want the server to *always*
return default page that boots up Angular.
After Angular is loaded and bootstrapped the router will look at the address bar and take
the user where he needs to go.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be avoiding he/she? Either "he" -> "they" or change to "takes the user to the appropriate route".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

works everywhere.

Following are configurations for some of the most popular servers.
The list is by no means exhausting, but should provide you with a good starting point.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exhausting -> exhaustive

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

These APIs need to send the `Access-Control-Allow-Origin: *` header on their HTTP responses,
otherwise the SPA will not be able to call them.
You can read more about how to enable CORS for specific servers in
[enable-cors.org](http://enable-cors.org/server.html)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really good info here! Great job pulling this together!

@filipesilva
Copy link
Contributor Author

Thanks for the review @DeborahK, I've incorporated all your feedback now.

I think I touched everything you once listed as questions your users had. If there's something missing let me know.

Copy link
Contributor

@johnpapa johnpapa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great chapter!

:marked
## Overview

After creating your brand new Angular app you'll want to put it online for the world to see.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest removing the word brand and just saying After creating your new Angular app.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may not want it to be online for the world to see. I may be building a corporate internal app. Recommend just saying deploy it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Your development setup is optimized for build speed and rapid iteration, but when
deploying to production you'll want to optimize for loading speed and payload size.

In this chapter you'll see how to deploy your app right now, techniques to reduce your
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove right now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

## Simplest deploy possible

The simplest possible way to deploy your app is to use your development environment.
It is already working locally after all, so it should work live.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest It is working locally, so it will work when published to a web server, too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

3. Configure your server to redirect requests for missing files to `index.html` instead.
[More on this later](#server-configuration).

And this is all you need to publish your app!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove And

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


And this is all you need to publish your app!

It's not a very good production deploy though.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of negative prose, I suggest ... You've deployed your app, but we can do better for production to optimize the app! Let's learn how.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

This allows Tree-Shaking to further remove exports.

You can read more about AoT Compilation in our [dedicated cookbook chapter](aot-compiler.html),
where you'll also find instructions on how to use Rollup to perform all the optimizations shown here.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest removing the word Rollup from here. Why? Because we may use something else later and it would be easier to edit just that doc later and not this one too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


The Angular Router allows you to configure NgModules as being
[Lazy Loaded](https://angular.io/docs/ts/latest/guide/router.html#!#asynchronous-routing),
which means that particular NgModule (and all it's code) is not loaded on the very first load.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's when possessive it its

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

are needed.

A common mistake to make while lazy loading a module is to *also* have that module imported via
a ES6 import.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a --> an

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

it to be imported directly instead of being imported via the Router.

It's important to note that your bundling configuration must take lazy loading into consideration.
Since there is no ES6 import for that module, bundlers don't know that they should also
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should just use ES import instead of ES6 import. That safeguards us for future versions ... it is also what I do for all of my material :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, across the doc.

Angular apps are
[Single Page Applications](https://en.wikipedia.org/wiki/Single-page_application) (SPAs),
which makes them the perfect candidates to be served by a simple static HTML server.
No preprocessors required!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know what this means, but will the reader know what a preprocessor is? either explain or remove.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded to

There is no need to have a server-side language composing the pages because
Angular will do it on the client-side.

WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@wardbell wardbell self-requested a review January 4, 2017 01:57
@wardbell
Copy link
Contributor

wardbell commented Jan 4, 2017

I very much like the tone, direction, and brevity of this cookbook!

I'll put copy edits elsewhere. Here are some stream-of-consciousness questions.

I ask a lot of "why" questions below. I'm not suggesting that we burden this page with a lengthy discourse about the "why" of everything. But we should know "why" ... and may want to condense the "why" into a sentence here and there.

  • I think we need a different title as "Production deploy" is a slang noun. Suggestions welcome. So far the best I have is "Deploy to production".

FS: Going-to-production Cookbook was actually the original name in our planning but I didn't see that
until you mentioned the name. @DeborahK and @johnpapa might have suggestions.

  • I'm not sure that this is a cookbook. There is a lot of high level advice but relatively little in the way of instructions for what to do after you've done the "simplest deployment possible". The notable exception is that highly detailed "Server configuration" section.

    Can we be more specific about how to do some/all of the tricks in your list? If we shouldn't be more specific here, where should people go to learn more?

FS: most of the optimizations related to build size itself are addressed in the Ahead-of-Time Compilation cookbook (I link to it in the appropriate bit), so I did not want to duplicate the scripts/commands to do that. I would like to review that one in the near future, though.
I think we will need to provide a simple way to do all of that in the quickstart repo, and also to apply it to our tooling so that we auto-run AoT in our e2e suite. That's actually how I started this chapter but then though it better to separate the two tasks.
Regarding the cookbook classification, we might need another section for these more general chapters. Perhaps "Tooling and Setup". The Setup Anatomy, TypeScript Configuration and Webpack chapters currently in advanced would also belong there.

  • We should separate "optimization" from "deployment". You do that yourself by offering a path that pushes the dev environment to the web: "Simplest deploy possible" ... love that title.

FS: They are conceptually different but in practice I don't think anyone cares for one without the other, except for internal demos. Maybe reordering the sections is enough to make the distinction.

  • I think we should be more clear about what we're optimizing for. Is it faster launch time? That seems to be what you're after. So what is the metric there? I've seen discussions that call out the time from click-to-app-usability. Maybe we should reference those?

FS: I elaborate a bit on how each optimization does different things after I present them. Perhaps it should be the other way around, presenting some axis on which to determine performance and how to navigate them.

  • Let's make a strong case for a published dev build; as @DeborahK as observed, that's often a crucial step in winning (and retaining) managment/stakeholder support.

FS: That is a useful tool in a dev's toolbox. I have used it myself several times.

  • In several places you say "optimize for loading speed and payload size". Is payload size a goal on its own? You suggest it makes a difference in transfer time and startup time. In what environments is that true? I haven't seen numbers that support this claim for desktop or mobile apps over 4G networks. I'm a skeptic.

FS: I haven't the numbers, but AFAIK it is especially relevant in emergent markets where smartphones are the primary web device and connection is very poor. That one was of the reasons for the big AoT push.

  • In any case, I think of a smaller payload as just one factor that contributes to faster loading. It's significance in that respect depends a great deal on the target environment, yes? In my (limited) experience, the far bigger factor, both in desktop and over mobile, is the number of trips to the server.

FS: I also put more stock in round trip number but both matter. Bundling (the solution to round trip numbers) is also somewhat shallow (you... bundle and that's it) so I don't feel there is as much to list there.

  • In several places, you conflate reduced payload size and number of files. They are separate issues and may be seen as inversely related: bundling, for example, reduces the number of files while increasing the payload size for each request.

    Which is more important? When?

    In my (limited) experience, the number of files matters a lot whereas (total net) payload size makes comparatively little difference in app launch and startup time ... at least for enterprise apps. Is that your experience?

    There may be good reasons to do both. My point is that a few optimizations (bundling and inlining?) may be more significant than the others combined in improving perceived app launch time. Bundling may be much easier to achieve than some or all of the extraordinary efforts to reduce total payload size.

FS: My experience is also that bundling/inlining is the biggest gain. I don't think it would would be significantly easier to do just one though. Most toolchains do all of them with a few lines. Setup is the hardest bit.

  • I confess to wondering about the nearly maniacal effort of the Angular team to shrink the payload. Where are the metrics for the benefit of that? @johnpapa may be able to weigh in from his corporate experience.

FS: I don't have these metrics myself but they would be a compelling reference in this chapter.

  • You wrote:

    For one, it has a lot of files that aren't even used when serving your site to users since it has all the development only packages.

    Why should I care? What is the cost of having extra files on the server now that storage is almost free?

FS: Deborah's experience was that in some hosting solutions it is very relevant due to storage caps. The quickstart setup by itself is 100mb for instance. Bigger setups might take a while to upload/deploy as well, once you consider upload speed.

  • I thought Tree Shaking was a technique for Dead Code Elimination. You list these as separate items. Why?

FS: They are slightly different. I also assumed they were the same before, but then read up a bit and there are technical differences: https://medium.com/@Rich_Harris/tree-shaking-versus-dead-code-elimination-d3765df85c80#.9wsa1wxwl

  • Why is the following statement under the "Template compilation" heading?

    Another great choice is Webpack 2 together with the Angular Ahead-of-Time Webpack Plugin.

    Perhaps you should say what it is.

FS: I should elaborate on that, yes.

  • Many people wonder if using SystemJS is "wrong" or means that you can't optimize for production. I don't think that is true, even if we are leaning to Webpack ourselves. What can we say to help people not worry about their use of SystemJS? Or should they worry?

FS: it's not true, no, but our setups don't help with that perception. We say that the quickstart is not meant for production, our AoT cookbook eschews it for the production builds, and Webpack doesn't use it either. As it stands we use SystemJS at dev time and that's it. We should address SystemJS and it's worth in the same way we do Webpack via a cookbook.

  • What would be the perf benefit of switching to umd scripts for Angular and other 3rd party libraries. Aren't these a good choice if you can't go the webpack way? That's what we do for plunkers. Or is this thought just a distraction?

FS: There is a big benefit at development time due to loading a single file instead of hundreds of modules. It's irrelevant for production because the build pipeline will optimize and bundle anyway. Switching back and forth requires specialized configuration for SystemJS that we do not address though.

  • The base tag section raises a concern but doesn't say how to ameliorate it. There is a line of index.html code that works everywhere I think: in local development and on any server. It's the one we use in generated plunkers:
    <script>document.write('<base href="' + document.location + '" />');</script>
    
    If that's true, should we recommend it?

FS: I actually have not looked into it in detail. I don't know what it's pitfalls are, if any. Can you consult with the Angular team about it? If it's a catch-all then we should always recommend it.

WB: It doesn't work, not that way. There may be some value in the APP_BASE_HREF but it requires more research. Stepped away from it.

  • Re: enableProdMode - why do you recommend setting that in main.ts. That defeats its purpose during development. Shouldn't it be inside a conditional that enables production mode in production builds?

FS: It needs to be set in main.ts, but only for the production build. To be honest I have a lot of reservations about how enableProdMode works. I don't have a good pattern to enable it without acrobatics that are highly dependent on the build system.

WB: I added what I think is an ok pattern.

  • The Lazy Loading section is a great start. I don't think we're as clear as we could/should be on how to recognize and overcome the mistake:

    A common mistake to make while lazy loading a module is to also have that module imported via an ES import. If you do that, the module will never really be lazy loaded since the import statement will cause it to be imported directly instead of being imported via the Router.

    That's something we can look at in copy editing.

FS: we need tooling for this. That is why the AoT Webpack Plugin exists, but that only works for Webpack. I didn't want to elaborate because similar tooling for SystemJS or Rollup does not exist and we need to produce it if we want lazy-loading to actually be used in those setups.

FS: Yes, it's a separate plugin that can be used in webpack in general. That page serves as documentation for it.

  • The Server Configuration section is excellent and unusually detailed compared to anything else on this page. I like that. But it feels a bit strange to be reading high-level advice and suddenly diving into details.

FS: That was a side-effect of my writing process actually. I did it all in one sitting almost, and the longer I was writing the more in the zone I got. Another factor was that a lot of the implementation of the optimization section is actually in the AoT cookbook.

  • Thanks for the CORS section!

FS: I wasn't going to put it in but Deborah reminded me of it. I figured a few lines would save a lot of headaches.

@filipesilva
Copy link
Contributor Author

@wardbell I edited your comment with my replies so as to not bloat this thread unnecessarily. My replies look like this:

FS: reply here

@johnpapa
Copy link
Contributor

johnpapa commented Jan 4, 2017

I can't edit the comment so I will respond here ...

Ward: In several places you say "optimize for loading speed and payload size". Is payload size a goal on its own? You suggest it makes a difference in transfer time and startup time. In what environments is that true? I haven't seen numbers that support this claim for desktop or mobile apps over 4G networks. I'm a skeptic.

I've seen many examples of this making a huge difference even on 4G. A large portion of our users use desktop/laptop on WiFi and the difference in 2 seconds to usability vs 3 has quantifiable effects on abandonment and revenue (per some companies I have seen stats from). We don't need to state this. 2 seconds is the bar that most folks I have spoken to have to deal with for public sites.

Even with internal apps, there is a focus (though more relaxed) on the speed. I'm sure many companies dont care ... but just as many do.

@DeborahK
Copy link
Contributor

DeborahK commented Jan 4, 2017

I would really like to see this come out sooner rather than later for several reasons:

  1. There is really good content here. We can edit/enhance over time.
  2. Just yesterday I received another "now how do I deploy" question. It would be great to have something to point them to.
  3. Talked to Joe and he did a chapter on deployment in the Fundamentals course. I would expect this to be coming out any day now. It would be great if we had something in the docs prior to then.

@johnpapa
Copy link
Contributor

johnpapa commented Jan 4, 2017

I agree its not a cookbook .. but the content is very valuable. I think we are have a very confusing organization of docs anyway ... we should focus on good content and simply create a master list of the topics.

My short term point is that we should publish this sooner rather than later wherever it goes. I highly doubt anyone knows the diff between cookbook and advanced and regular docs :)

@wardbell
Copy link
Contributor

wardbell commented Jan 5, 2017

Well I know the difference between a cookbook and guide :-)

For sure a cookbook contains detailed instructions you can follow. For sure it contains sample code. This PR offers neither.

I'm not judging. This is all I had reason to expect from the author, given the constraints I set for him. But I am stating facts.

Imagine a cookbook recipe called "Boil an egg" that talked about how chickens come from eggs (it might or might not mention that eggs come from chickens), and the relative merits of cooking in hot water versus steam, and how most people used gas stoves ... but never told you what to do. That is a guide at best, not a cookbook recipe at all.

At some point we have to go beyond musing about the factors and give people some real instructions. That isn't happening here to my satisfaction. There is one place that comes close to giving actual instruction for deploying to a server - the "Simplest possible deploy" - and even that omits crucial details or an example for even one server.

There is no accompanying code, nothing you can run, nothing you can see that looks like a production app.

I must repeat ... I'm not condemning the author. I asked for this and I got it.

Having said that, so pressing is the need for something that I agree to completing the review and copy-editing this week ... as a preliminary guide. Hold me to it!

@googlebot
Copy link

So there's good news and bad news.

👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there.

😕 The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter. We need to confirm that they're okay with their commits being contributed to this project. Please have them confirm that here in the pull request.

Note to project maintainer: This is a terminal state, meaning the cla/google commit status will not change from this state. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.

1 similar comment
@googlebot
Copy link

So there's good news and bad news.

👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there.

😕 The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter. We need to confirm that they're okay with their commits being contributed to this project. Please have them confirm that here in the pull request.

Note to project maintainer: This is a terminal state, meaning the cla/google commit status will not change from this state. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.

@googlebot googlebot added CLA: no and removed CLA: yes labels Jan 8, 2017
@wardbell wardbell force-pushed the prod-deploy branch 6 times, most recently from 3158397 to 3c083a7 Compare January 8, 2017 10:14
@wardbell wardbell removed their request for review January 8, 2017 10:15
@googlebot
Copy link

CLAs look good, thanks!

1 similar comment
@googlebot
Copy link

CLAs look good, thanks!

@googlebot googlebot added CLA: yes and removed CLA: no labels Jan 9, 2017

The `node_modules` folder is huge and slow to upload to the server.
It's typically 20,500+ files and 180+ MB.
The application itself requires a tiny fraction of that to run.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean with this, but my first impression (even when I know what you mean) is that we need like a mini node_modules folder in our deploy to make it work. Like... let's remove a bunch of files that we don't need and leave what we need.

@googlebot
Copy link

So there's good news and bad news.

👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there.

😕 The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter. We need to confirm that they're okay with their commits being contributed to this project. Please have them confirm that here in the pull request.

Note to project maintainer: This is a terminal state, meaning the cla/google commit status will not change from this state. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.

1 similar comment
@googlebot
Copy link

So there's good news and bad news.

👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there.

😕 The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter. We need to confirm that they're okay with their commits being contributed to this project. Please have them confirm that here in the pull request.

Note to project maintainer: This is a terminal state, meaning the cla/google commit status will not change from this state. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.

Copy link
Contributor

@robwormald robwormald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other notes:

  • we should probably mention the thing about Rx operators (importing them directly vs the entirety of Rx?)
  • maybe mention WebPageTest for verifying perf / succesful deployment>

This guide describes techniques for preparing and deploying an Angular application to a server running remotely.
The techniques progress from _easy but suboptimal_ to _more optimal and more involved_.

* The [simple way](#dev-deploy "Simplest deployment possible") is to copy the development environment to the server.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably not something we want to recommend, ever?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is value is describing how to deploy your dev code with the minimum set of changes. This is a question that comes up a couple of times every week.

I'll add a note that this isn't recommended per se, but rather a fallback.


1. Enable production mode as [described below](#enableprodmode) (optional).

That's all it takes to publish your app!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above. Concerned people will stop here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will reword to avoid that.

:marked
### Load npm packages from the web (SystemJS)

The `node_modules` folder of _npm packages_ is huge and slow to upload to the server.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets avoid pejorative words like "huge" and "slow: :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix.


Load the _npm packages_ from the web instead.

(1) Make a copy of `index.html` for deployment and replace all `node_module` scripts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think here, we want to use SystemJS builder instead. UMD bundles are a less optimal option and straight out won't work with AoT

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section is meant to show the simplest possible deploy. Adding a build step would go against that. I'll clarify that further.

There is also the concern of adding another interim build step that isn't further detailed or documented. It's better to jump directly to the rollup+aot configuration for optimization.

+makeExample('index.html', 'systemjs-config', '')(format=".")
:marked
(3) Add `systemjs.config.server.js` (shown in the code sample below) to the root folder.
This alternative version configures _SystemJS_ to load _UMD_ versions of Angular
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto. UMD !== deployment.

the app takes longer to launch than it would if you optimized it.
Several seconds may pass (or worse) before the user can see or do anything userful.

Does it matter? That depends upon business and technical factors you must evaluate for yourself.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a hard time with this. I can't see a scenario where it's beneficial to deploy to production without these things. Why even ask the question?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the docs meetings a couple of real world scenarios came up. Deploying demos was one, and for some projects there is no time/feature budget to actually produce an optimized deployment since the business does not need it.

- Minification: removes excess whitespace, comments, and optional tokens.
- Uglification: rewrites code to use short, cryptic variable and function names.
- Dead code elimination: removes unused code.
- Tree shaking: removes unreferenced modules.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code elimination is basically the same as Treeshaking, for the purposes of this doc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Tree shaking with rollup section talks a bit more about it, and links to an article that elaborates on the differences.

@filipesilva
Copy link
Contributor Author

@robwormald I added a commit addressing your suggestions:

  • added section about importing RxJs operators
  • added WebPageTest example
  • removed 'huge' and 'slow' in favor of a better description
  • added more encouragement to further pursue optimizations

@robwormald
Copy link
Contributor

This PR LGTM. couple of notes, more to @wardbell than anyone:

in any case, I think of a smaller payload as just one factor that contributes to faster loading. It's significance in that respect depends a great deal on the target environment, yes?

As of today, script parsing time (which is a function of how much JS you ship to browser) is the #1 (by far) cost of getting angular apps booted, especially on mobile devices. This is worse with mega-vendor bundles.

In my (limited) experience, the far bigger factor, both in desktop and over mobile, is the number of trips to the server.
In my (limited) experience, the number of files matters a lot whereas (total net) payload size makes comparatively little difference in app launch and startup time ... at least for enterprise apps. Is that your experience?

This is more server dependent (does your server support HTTP2 (push?) - if it does, somewhat counterintuitively, its much faster to load a bunch of smaller scripts over the single connection than one large script (!). This whole pattern is changing and I want to be cautious about getting overly prescriptive about these sorts of things while stuff is in flux.

:shipit:

@filipesilva filipesilva merged commit 8a537b1 into angular:master Jan 27, 2017
@filipesilva filipesilva deleted the prod-deploy branch January 27, 2017 00:40
@wardbell
Copy link
Contributor

@robwormald Thanks for the perf feedback and for demonstrating these points to me personally (Stephen did so too). I understand much better. I think we're silent on which factors are "more important" ... and silence is golden.

Thanks for your help!

abdel-ships-it pushed a commit to abdel-ships-it/angular.io that referenced this pull request Feb 11, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants