Angular2加载时文件请求太多

Mar*_*ldo 57 javascript typescript systemjs angular

我正在使用一个网站Angular2,我有我认为是一个问题.在我的角度页面的第一次加载时,SystemJS正在发出超过500个请求来检索目录中的每个Angular2文件angular2/src.总的来说,第一个负载下载超过4MB,启动时间超过14秒.

index.html的以下脚本包括:

<script src="libs/angular2/bundles/angular2-polyfills.js"></script>
<script src="libs/systemjs/dist/system.src.js"></script>
<script src="libs/rxjs/bundles/Rx.js"></script>
<script src="libs/angular2/bundles/angular2.min.js"></script>
<script src="libs/angular2/bundles/http.dev.js"></script>
<script src="libs/jquery/jquery.js"></script>
<script src="libs/lodash/lodash.js"></script>
<script src="libs/bootstrap/js/bootstrap.js"></script>
Run Code Online (Sandbox Code Playgroud)

我的systemJs初始化代码如下所示:

    <script>
      System.config({
        defaultJSExtensions: true,
        paths: {
          '*': 'libs/*',
          'app/*': 'app/*'
        },
        packageConfigPaths: ['libs/*/package.json'],
        packages: {
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/main')
            .then(null, console.error.bind(console));

    </script>
Run Code Online (Sandbox Code Playgroud)

我的公用文件夹具有以下结构:

.
??? img
??? styles
??? app
??? libs
|   ??? angular2
|   ??? systemjs
|   ??? rxjs
|   ??? jquery
|   ??? lodash
|   ??? bootstrap
??? index.html
Run Code Online (Sandbox Code Playgroud)

正在请求的一些js文件的几个屏幕截图: 在此输入图像描述

在此输入图像描述

有没有办法避免所有这些请求?

Dav*_*rod 47

我有完全相同的问题,实际上正在看这篇文章的答案.以下是我为解决问题所做的工作.

  1. 修改您的项目以使用webpack.按照这个简短的教程: Angular2 QuickStart SystemJS To Webpack
  2. 这个方法会给你一个单独的javascript文件但是它非常大(我的项目文件超过5MB)并且需要缩小.为此,我安装了webpack globaly : npm install webpack -g. 安装后,webpack -p从您的应用程序根目录运行.这使我的文件大小降低到大约700KB

从20秒和350个请求下降到3秒和7个请求.

  • 不要忘记在服务器上启用gzip.应将文件大小再降低50%. (4认同)
  • 我刚刚在官方文档中找到了这个链接:https://angular.io/docs/ts/latest/guide/webpack.html.也许它更相似,但也许它会帮助某人 (2认同)
  • 这是如此简单明了,这应该有1000个赞成!将我的加载时间从300多个请求减少到~20. (2认同)

MrC*_*oft 33

我看到你已经有了回应,当然这很好.但对于那些想要使用systemjs的人(比如我也这样),而不是去webpack,你仍然可以捆绑文件.但是,它确实涉及使用另一个工具(我使用gulp).所以......你会得到以下的systemjs配置(不是在html中,而是在一个单独的文件中 - 让我们称之为"system.config.js"):

(function(global) {

    // map tells the System loader where to look for things
    var map = {
        'app':                        'dist/app', // this is where your transpiled files live
        'rxjs':                       'node_modules/rxjs',
        'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api', // this is something new since angular2 rc.0, don't know what it does
        '@angular':                   'node_modules/@angular'
    };

    // packages tells the System loader how to load when no filename and/or no extension
    var packages = {
        'app':                        { main: 'boot.js',  defaultExtension: 'js' },
        'rxjs':                       { defaultExtension: 'js' },
        'angular2-in-memory-web-api': { defaultExtension: 'js' }
    };

    var packageNames = [
        '@angular/common',
        '@angular/compiler',
        '@angular/core',
        '@angular/http',
        '@angular/platform-browser',
        '@angular/platform-browser-dynamic',
        //'@angular/router', // I still use "router-deprecated", haven't yet modified my code to use the new router that came with rc.0
        '@angular/router-deprecated',
        '@angular/http',
        '@angular/testing',
        '@angular/upgrade'
    ];

    // add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
    packageNames.forEach(function(pkgName) {
        packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
    });

    var config = {
        map: map,
        packages: packages
    };

    // filterSystemConfig - index.html's chance to modify config before we register it.
    if (global.filterSystemConfig) { global.filterSystemConfig(config); }

    System.config(config);
})(this);
Run Code Online (Sandbox Code Playgroud)

然后,在您的gulpfile.js中,您将构建一个这样的包(使用来自system.config.jstsconfig.json文件的信息):

var gulp = require('gulp'),
    path = require('path'),
    Builder = require('systemjs-builder'),
    ts = require('gulp-typescript'),
    sourcemaps  = require('gulp-sourcemaps');

var tsProject = ts.createProject('tsconfig.json');

var appDev = 'dev/app'; // where your ts files are, whatever the folder structure in this folder, it will be recreated in the below 'dist/app' folder
var appProd = 'dist/app';

/** first transpile your ts files */
gulp.task('ts', () => {
    return gulp.src(appDev + '/**/*.ts')
        .pipe(sourcemaps.init({
            loadMaps: true
        }))
        .pipe(ts(tsProject))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(appProd));
});

/** then bundle */
gulp.task('bundle', function() {
    // optional constructor options
    // sets the baseURL and loads the configuration file
    var builder = new Builder('', 'dist/system.config.js');

    /*
       the parameters of the below buildStatic() method are:
           - your transcompiled application boot file (the one wich would contain the bootstrap(MyApp, [PROVIDERS]) function - in my case 'dist/app/boot.js'
           - the output (file into which it would output the bundled code)
           - options {}
    */
    return builder
        .buildStatic(appProd + '/boot.js', appProd + '/bundle.js', { minify: true, sourceMaps: true})
        .then(function() {
            console.log('Build complete');
        })
        .catch(function(err) {
            console.log('Build error');
            console.log(err);
        });
});

/** this runs the above in order. uses gulp4 */
gulp.task('build', gulp.series(['ts', 'bundle']));
Run Code Online (Sandbox Code Playgroud)

因此,在运行"gulp build"时,您将获得"bundle.js"文件,其中包含您需要的所有内容.当然,您还需要更多的软件包才能使用这个gulp bundle任务:

npm install --save-dev github:gulpjs/gulp#4.0 gulp-typescript gulp-sourcemaps path systemjs-builder
Run Code Online (Sandbox Code Playgroud)

另外,请确保在tsconfig.json中有"module":"commonjs".这是我的gulp 'ts'任务中使用的tsconfig.json :

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": false
    },
    "exclude": [
        "node_modules",
        "typings/main",
        "typings/main.d.ts"
    ]
}
Run Code Online (Sandbox Code Playgroud)

然后,在你的html文件中你只需要包含这个:

<!-- Polyfill(s) for older browsers -->
<script src="node_modules/es6-shim/es6-shim.min.js"></script>

<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="dist/app/bundle.js"></script>
Run Code Online (Sandbox Code Playgroud)

就是这样......我得到了600个请求,大约5秒内4mb ......到20个请求,1.6个1.6mb(本地开发机器).但这些20个请求在1.6秒内~1.4mb还包括管理主题附带的一些其他js和css以及第一次加载时需要的几个html模板,我更喜欢使用外部模板 - templateUrl:'',而不是内联的,用我的component.ts文件编写.当然,对于拥有数百万用户的应用程序,这仍然是不够的.还应该实现初始加载和缓存系统的服务器端渲染,我实际上设法使用角度通用,但在Angular2 beta上(花了大约200-240毫秒来加载上面需要的相同管理应用程序的初始渲染1.6秒 - 我知道:哇!).现在它与Angular2 RC出来后不相容,但我确信那些做普及的人会很快加速,特别是因为ng-conf即将到来.此外,他们还计划为PHP,ASP和其他一些人制作Angular Universal - 现在它只适用于Nodejs.

编辑: 实际上,我刚刚发现在NG-CONF上他们说Angular Universal已经支持ASP(但是它不支持Angular2> beta.15 :))但是让我们给他们一些时间,RC刚来了几天前出去了