[英]Angular2 too many file requests on load
我正在使用Angular2
創建一個網站,但我有一個問題。 在我的angular頁面的第一次加載中, SystemJS
發出了500多個請求來檢索angular2/src
目錄中的每個Angular2
文件。 總共,首次加載下載超過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
。 這使我的文件大小減小到約700KB 從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秒內的4mb)到20個請求(1.6秒內的1.4mb)(本地開發機器)。 但是這20個請求在1.6秒內達到約1.4mb,其中還包括管理主題附帶的其他js和CSS,以及一些首次加載時需要的html模板,我更喜歡使用外部模板-templateUrl:”,而不是內聯代碼,寫在我的component.ts文件中。 當然,對於擁有數百萬用戶的應用程序來說,這還遠遠不夠。 同樣應該為初始加載和緩存系統實現服務器端渲染,我實際上設法使用angular Universal做到了這一點,但是在Angular2 beta(花了大約200-240毫秒來加載同一個管理應用程序的初始渲染,而上述花費1.6秒-我知道: 哇! )。 自從Angular2 RC發布以來,它就已經不兼容了,但是我敢肯定,進行通用開發的人很快就會加快速度,特別是因為ng-conf即將推出。 此外,他們還計划將Angular Universal用於PHP,ASP和其他一些工具-現在僅適用於Node.js。
編輯:實際上,我剛剛發現他們在NG-CONF上說Angular Universal已經支持ASP(但是它不支持Angular2> beta.15:))...但是讓我們給他們一些時間,RC剛剛問世。幾天前
我認為您的問題與此有關:
要准備好某些東西以進行生產(並加快速度),您需要對其進行打包。
我的意思是將所有文件都轉換為JavaScript文件,然后像Angular2一樣將它們合並。 這樣,您將在單個JS文件中包含多個模塊。 這樣,您將減少將應用程序代碼加載到瀏覽器中的HTTP調用次數。
我找到了一個簡單的解決方案,在mgechev的angular2種子存儲庫上使用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>
在我的angular頁面的第一次加載中,systemjs發出了500多個請求來檢索angular2 / src目錄中的每個angular2文件。 總共,首次加載下載的大小超過4mb,並且開始耗時超過14s。
SystemJs工作流是相當新的,並且沒有足夠的研究來最好地進行部署。
建議回到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>
我正在使用AG2 RC版本在將MrCroft的解決方案與systemjs-builder一起使用時,我遇到了很多問題,例如:錯誤TS2304:找不到名稱“地圖”錯誤TS2304:找不到名稱“承諾” ...
經過多次嘗試,我在///<reference path="../../typings/index.d.ts" />
添加了///<reference path="../../typings/index.d.ts" />
,現在我的捆綁文件已編譯好。
Angular命令行界面現在支持捆綁(通過搖晃來從導入中刪除未使用的代碼),最小化和提前模板編譯,這不僅極大地減少了發出的請求數量,而且使捆綁非常小。 它在下面使用WebPack。
使用它進行生產構建非常容易:
ng build --prod --aot
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.