Search code examples
javascriptnode.jsperformanceangularsystemjs

Will including all the angular2 bundles in index.html make imports get data from memory instead of requesting it from the server again?


I'm starting out with angular 2, coming from angular 1, which I'm very happy with (outstanding performance all around).

I got the quickstart going with a node backend and abysmal performance (40 seconds to fully load the page in firefox and over 500 requests!). I seriously thought of going back to angular 1 and staying there until angular 3 comes out (i.e. forever).

I searched around and aside from webpack, I found another interesting bit of information: Apparently, if you load all the bundles in the index.html file, the import statements no longer request each file from the server, but get their data from memory. That sounded great! I got all the relevant, minified bundles I could find into index.html and performance improved a good deal (I got ~10s in firefox and 3s in chrome). Still a far cry from angular 1.

Also, I still see over 500 requests of about 7mb total size... so, I'm wondering, are these still requesting the files from the server or are they actually getting the data from memory?

If they are getting their data from memory why are the requests still there and how can I check where they are getting it from?

If they are still requesting the data from the server, one file at a time, how can I force them to get it from memory (or wherever those bundles are stored clientside) when available?

Also, is there anything else I can do to improve performance? (aside from minifying everything into one file/using webpack)

Here is my index.html file:

<html>
<head>
<title>Angular 2 QuickStart</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--<link rel="stylesheet" href="styles.css">-->

<base href="/">

<!-- 1. Load libraries -->
<!-- Required polyfills, in order -->
<script src="es6-shim/es6-shim.min.js"></script>
<script src="angular2/es6/dev/src/testing/shims_for_IE.js"></script>
<script src="angular2/bundles/angular2-polyfills.min.js"></script>
<script src="systemjs/dist/system.js"></script>
<script src="rxjs/bundles/Rx.min.js"></script>
<script src="angular2/bundles/angular2.min.js"></script>
<script src="angular2/bundles/router.min.js"></script>
<script src="angular2/bundles/http.min.js"></script>

<script src="angular2-cookie/bundles/angular2-cookie.min.js"></script>

<script src="lodash/lodash.min.js"></script>
<!-- 2. Configure SystemJS -->
<script>
    System.defaultJSExtensions = true;
    System.import('main').then(null, console.error.bind(console));
</script>
</head>
<!-- 3. Display the application -->
<body>
    <app>Loading...</app>
</body>

I'm exposing node_modules along with the public directory, so this all works just fine.


Solution

  • OK, I got it loading nice and fast. The trick, apparently, is to configure systemjs before loading your angular2 stuff; I just do it before loading anything else, like so:

    <html>
    <head>
        <title>Angular 2 QuickStart</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    
        <base href="/">
        <link rel="stylesheet" href="app/style.css">
    
        <!-- 1. Load libraries -->
        <!-- Configure SystemJS -->
        <script src="systemjs/dist/system.js"></script>
        <script>
            System.config({ defaultJSExtensions: true });
        </script>
    
        <!-- Angular libraries -->
        <script src="es6-shim/es6-shim.min.js"></script>
        <script src="angular2/es6/dev/src/testing/shims_for_IE.js"></script>
        <script src="angular2/bundles/angular2-polyfills.min.js"></script>
        <script src="rxjs/bundles/Rx.min.js"></script>
        <script src="angular2/bundles/angular2.min.js"></script>
        <script src="angular2/bundles/router.min.js"></script>
        <script src="angular2/bundles/http.min.js"></script>
        <script src="angular2-cookie/bundles/angular2-cookie.min.js"></script>
    
        <!-- Other libraries -->
        <script src="lodash/lodash.min.js"></script>
    
        <!-- 2. Configure SystemJS -->
        <script>
            System.import('main').then(null, console.error.bind(console));
        </script>
    </head>
    <!-- 3. Display the application -->
    <body>
    <app>Loading...</app>
    </body>
    </html>
    

    And there she goes!