Angular2로드시 너무 많은 파일 요청
나는 웹 사이트를 사용 Angular2
하고 있는데 문제가 있다고 생각합니다. 내 각도 페이지의 첫 번째로드 에서 디렉토리의 SystemJS
모든 Angular2
파일 을 검색하기 위해 5 억 개 이상의 요청을 작성합니다 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>
그리고 내 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
이러한 요청을 모두 피할 수있는 방법이 있습니까?
나는 똑같은 문제가 있었고 실제로이 게시물에서 답변을 찾고있었습니다. 문제를 해결하기 위해 내가 한 일이 있습니다.
- 웹팩을 사용하도록 프로젝트를 수정하십시오. 이 짧은 튜토리얼을 따르십시오 : Angular2 QuickStart SystemJS To Webpack
- 이 방법은 하나의 자바 스크립트 파일을 제공하지만 크기가 상당히 커서 (내 프로젝트 파일이 5MB 이상) 축소해야합니다. 이를 위해 webpack globaly를 설치했습니다
npm install webpack -g
. 설치되면webpack -p
앱 루트 디렉토리에서 실행 하십시오. 이것은 내 파일 크기를 약 700KB로 줄였습니다.
20 초 및 350 개의 요청에서 3 초 및 7 개의 요청으로 감소합니다.
당신은 이미 응답을 가지고 있습니다. 물론 좋습니다. 하지만 systemjs 를 사용 하고 (저와 마찬가지로) 웹팩으로 이동하지 않으려는 사람들을 위해 파일을 번들로 묶을 수 있습니다. 그러나 다른 도구도 사용합니다 (나는 꿀꺽 꿀꺽 사용). 그래서 ... 당신은 다음과 같은 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'
꿀꺽 꿀꺽 작업에 사용되는 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>
And that's it... I got from 600 requests, 4mb in about 5 seconds... to 20 requests, 1.4mb in 1.6 seconds (local development machine). But these 20 requests ~1.4mb in 1.6 seconds also include some other js and css that the admin theme came with plus a few html templates that get required on the first load, I prefer to use external templates - templateUrl: '', instead of inline ones, written in my component.ts file. Sure, for an app that would have millions of users, this still wouldn't be enough. Also server-side rendering for initial load and cache system should be implemented, I actually managed to do that with angular universal, but on Angular2 beta (took about 200-240 milliseconds to load the initial render of the same admin app that above takes 1.6 seconds - I know: WOW!). Now it's incompatible since Angular2 RC came out, but I'm sure the guys doing universal will get it up to speed soon, specially since ng-conf is coming up. Plus, they're also planing to make Angular Universal for PHP, ASP and a few other - right now it's only for Nodejs.
Edit: Actually, I've just found out that on NG-CONF they said Angular Universal already supports ASP (but it doesn't support Angular2 > beta.15 :)) ... but let's give them some time, RC just came out a few days ago
I think that your question is related to this one:
To have something ready for production (and speed it up), you need to package it.
I mean transpiling all files into JavaScript ones and concat them the same way Angular2 does for example. This way you will have several modules contained into a single JS file. This way you will reduce the number of HTTP calls to load your application code into the browser.
I found a simple solution, using browserify & uglifyjs on mgechev's angular2-seed repository
Here's my version:
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"
}
}
- Build your project.
- Run: npm run build_prod It'll create bundle.js & bundle.min.js under public\dist directory.
- Edit your
index.html
file: Instead of runningSystem.import('YourMainModule')... ,
add<script src="/dist/bundle.min.js"></script>
On the first load of my angular page, systemjs is making more than 500 hundred requests to retrieve every angular2 file in angular2/src directory. In total, the first load downloads more than 4mb and it takes more than 14s to start.
The SystemJs workflows are fairly new and don't have enough research in them for best deployment.
Suggest going back to commonjs
+ webpack
. More : https://basarat.gitbooks.io/typescript/content/docs/quick/browser.html
Here is an example : https://github.com/AngularClass/angular2-webpack-starter
@FreeBird72 Your answer is awesome.
If you want to use SystemJS for development and speed up the production server like I do. Check this out.
NOTE: Only import the components that you use, DO NOT import from the whole package.
Eg: If you want to use Modal from ng2-bootstrap.
import {MODAL_DIRECTIVES} from "ng2-bootstrap/components/modal";
Instead of:
import {MODAL_DIRECTIVES} from "ng2-bootstrap/ng2-bootstrap";
This will import the modal component instead of the whole ng2-bootstrap
Then follow the answer from @FreeBird72
Add this 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",
...
}
...
}
Then you can npm run tsc
on development and npm run prod
on production server Also remove System.import(....
from your index.html and change it to <script src="/dist/bundle.min.js"></script>
If you want to stick with SystemJS, you can bundle your app with JSPM. I've had good success with this so far, using JSPM's bundle-sfx
command to make single JS files for Angular 2 apps.
There's some useful information in this Gist, and there's a seed project.
I am using AG2 RC version While using MrCroft's solution with systemjs-builder, i was hitting a lot of issues like: error TS2304: Cannot find name 'Map' error TS2304: Cannot find name 'Promise'...
After many tries, i added: ///<reference path="../../typings/index.d.ts" />
into my boot.ts and now I got my bundle file compiled.
The Angular command line interface now supports bundling (with tree-shaking to strip out unused code from imports), minification, and ahead-of-time template compilation, which not only hugely minimises the number of requests made, but also makes the bundle very small. It uses WebPack underneath.
It's incredibly easy to make production builds with it:
ng build --prod --aot
https://github.com/angular/angular-cli
ReferenceURL : https://stackoverflow.com/questions/35280582/angular2-too-many-file-requests-on-load
'developer tip' 카테고리의 다른 글
package.json에 나열되지 않은 package-lock.json의 취약한 npm 패키지를 어떻게 수정합니까? (0) | 2020.12.26 |
---|---|
PHP를 사용하여 웹 사이트에서 OCR을 구현하려면 어떻게해야합니까? (0) | 2020.12.26 |
'위치 : 절대'가 flexbox와 충돌합니까? (0) | 2020.12.25 |
Django의 ModelForm unique_together 유효성 검사 (0) | 2020.12.25 |
Django의 계단식 삭제 동작을 재정의하는 옵션은 무엇입니까? (0) | 2020.12.25 |