Angular2
を使用してWebサイトを作成していますが、問題だと思われるものがあります。 my angularページの最初のロードで、SystemJS
はAngular2
ディレクトリ内のすべてのangular2/src
ファイルを取得するために5億件以上のリクエストを行っています。 、最初のロードで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>
そして、私の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>
パブリックフォルダーの構造は次のとおりです。
.
├── img
├── styles
├── app
├── libs
| └── angular2
| └── systemjs
| └── rxjs
| └── jquery
| └── lodash
| └── bootstrap
└── index.html
これらのリクエストをすべて回避する方法はありますか?
私はまったく同じ問題を抱えていて、実際にこの投稿で答えを探していました。これが私が問題を解決するためにしたことです。
npm install webpack -g
。インストールしたら、webpack -p
アプリのルートディレクトリから。これにより、ファイルサイズが約700 KBになりました20秒と350リクエストから3秒と7リクエストまで。
すでに回答がありますが、それはもちろん良いことです。しかし、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);
次に、gulpfile.jsで次のようなバンドルを作成します(system.config.js
およびtsconfig.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']));
そのため、「gulp build」を実行すると、必要なすべての「bundle.js」ファイルが取得されます。もちろん、このgulpバンドルタスクを機能させるには、さらにいくつかのパッケージが必要です。
npm install --save-dev github:gulpjs/gulp#4.0 gulp-TypeScript gulp-sourcemaps path systemjs-builder
また、tsconfig.jsonに"module":"commonjs"
があることを確認してください。 'ts'
gulpタスクで使用される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"
]
}
次に、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>
そしてそれだけです...私は600リクエスト、約5秒で4 mbから取得しました... 20リクエスト、1.6秒で1.4 mb(ローカル開発マシン)になりました。しかし、1.6秒でこれらの20のリクエストには、管理テーマに付属する他のjsおよびcssに加えて、最初の読み込みで必要になるいくつかのhtmlテンプレートが含まれます。外部テンプレート-templateUrl: component.tsファイルに記述されたインラインのもの。確かに、何百万人ものユーザーがいるアプリの場合、これではまだ十分ではありません。また、初期ロードとキャッシュシステムのサーバー側レンダリングを実装する必要があります。実際にangularユニバーサルでそれを行うことができましたが、Angular2ベータ版では(200-240ミリ秒上記の同じ管理アプリの初期レンダリングを読み込むには1.6秒かかります-私は知っています:WOW!)。現在、Angular2 RCがリリースされて以来、互換性はありませんが、特にng-confが登場するので、ユニバーサルをやっている人はすぐにスピードアップするでしょう。さらに、彼らはまた、PHP向けのAngular Universal、ASPおよびその他いくつかを計画しています-現在はNodejs専用です。
編集:実際、NG-CONFではAngular UniversalはすでにASPをサポートしていると言いました(しかしAngular2> beta.15をサポートしていません:))...しかし、少し時間を与えましょう。RCは数日前に登場しました
あなたの質問はこれに関連すると思います:
本番用の準備を整える(そして高速化する)には、パッケージ化する必要があります。
つまり、すべてのファイルをJavaScriptファイルに変換し、たとえばAngular2と同じ方法で連結します。これにより、複数のモジュールが単一のJSファイルに含まれます。この方法により、HTTP呼び出しの数を減らして、アプリケーションコードをブラウザーにロードします。
mgechevのangular2-seedリポジトリ でbrowserifyとuglifyjsを使用して、簡単な解決策を見つけました
これが私のバージョンです。
pacakge.json:
_{
...
"scripts": {
"build_prod": "npm run clean && npm run browserify",
"clean": "del /S/Q public\\dist",
"browserify": "browserify -s main public/YourMainModule.js > public/dist/bundle.js && npm run minify",
"minify": "uglifyjs public/dist/bundle.js --screw-ie8 --compress --mangle --output public/dist/bundle.min.js"
},
...
"devDependencies": {
"browserify": "^13.0.1",
"TypeScript": "^1.9.0-dev.20160625-1.0",
"typings": "1.0.4",
"uglifyjs": "^2.4.10"
}
}
_
index.html
_ファイルを編集します:System.import('YourMainModule')... ,
を実行する代わりに_<script src="/dist/bundle.min.js"></script>
_を追加しますMy angularページの最初のロードで、systemjsは、angular2/srcディレクトリ内のすべてのangle2ファイルを取得するために5億件以上のリクエストを行っています。合計で、最初のロードは4MB開始する14秒以上。
SystemJのワークフローはかなり新しく、最適な展開のための十分な調査がありません。
commonjs
+ webpack
に戻ることをお勧めします。詳細: https://basarat.gitbooks.io/TypeScript/content/docs/quick/browser.html
以下に例を示します。 https://github.com/AngularClass/angular2-webpack-starter
@ FreeBird72あなたの答えは素晴らしいです。
SystemJSを開発に使用し、本番サーバーの速度を上げたい場合。これをチェックしてください。
注:使用するコンポーネントのみをインポートし、パッケージ全体からインポートしないでください。
例:ng2-bootstrapからModalを使用する場合。
import {MODAL_DIRECTIVES} from "ng2-bootstrap/components/modal";
の代わりに:
import {MODAL_DIRECTIVES} from "ng2-bootstrap/ng2-bootstrap";
これにより、ng2-bootstrap全体ではなくモーダルコンポーネントがインポートされます。
その後、@ FreeBird72の回答に従ってください
このpackage.jsonを追加します
{
...
"scripts": {
...
"prod": "npm run tsc && npm run browserify",
"browserify": "browserify -s main dist/main.js > dist/bundle.js && npm run minify",
"minify": "uglifyjs dist/bundle.js --screw-ie8 --compress --mangle --output dist/bundle.min.js",
...
},
"devDependencies": {
...
"browserify": "^13.0.1",
"uglifyjs": "^2.4.10",
...
}
...
}
次に、npm run tsc
を開発時に、npm run prod
を実稼働サーバー上で使用できます。また、index.htmlからSystem.import(....
を削除し、<script src="/dist/bundle.min.js"></script>
に変更します。
SystemJSを使用したい場合は、アプリを [〜#〜] jspm [〜#〜] にバンドルできます。これまでのところ、JSPMのbundle-sfx
コマンドは、Angular 2つのアプリ用の単一のJSファイルを作成します。
Angularコマンドラインインターフェイスは、バンドルからのインポート(未使用のコードをインポートから取り除くツリーシェーキング)、ミニファイ、事前テンプレートのコンパイルをサポートするようになりました。リクエストが行われますが、バンドルも非常に小さくなります。
本番環境でのビルドは非常に簡単です。
ng build --prod --aot
AG2 RCバージョンを使用していますsystemjs-builderでMrCroftのソリューションを使用しているときに、次のような多くの問題に遭遇しました:エラーTS2304:名前 'Map'が見つかりませんエラーTS2304:名前 'Promise'が見つかりません...
何度も試した後、私は追加しました:///<reference path="../../typings/index.d.ts" />
をboot.tsに追加し、バンドルファイルをコンパイルしました。