私は1000個以上のデータ要素を読み込む非常に大きなコンポーネントを持っています。これらのデータ要素は、一度だけ呼び出されるサービス経由で生成されます。最初の実装では、コンポーネントが初期化されるたびにサービスが呼び出されました。これは問題があると思った場所です。そこで、私は祖父母コンポーネントで一度しか呼び出されない共有サービスを作成しました。次のように角の大きいコンポーネントローディング時間の改善
成分階層構造は以下の通りである:
- AddComponent(祖父母)
- Type1AddComponent
- BlockComponent(1000+データ要素を有する成分)
- Type2AddComponent
- BlockComponent
- Type3AddComponent
- 分かるようBlockComponent
- Type1AddComponent
、BlockComponent
は、すべての3つのTypeComponents
で使用されています。 3つの異なるTypeComponents
に示されているBlockComponent
のデータは同じです(ただしタイトル @Input)。 TypeComponent
の最初の初期化はうまくロードされますが、それらの切り替え時には読み込み時間が3秒を超えるため、私は不合理だと思います。ロード時間を短縮する方法はありますか?
私は下に共有されているコードがたくさんあることを知っています。 webpackプロジェクトのために私がそうする方法を知っていれば私はPlunkerを作成します。
共有data.service.ts
import { Injectable } from '@angular/core';
import { DataResolver } from '../../blocking/data/data.resolver';
import { Data } from 'si-data-model';
import { Observable } from 'rxjs/Observable';
import { Logger } from 'ngx-data-utils';
@Injectable()
export class DataService {
data: Data[] = []; // shared data
dataObs$: Observable<Data[]>;
logger: Logger;
completed = false; // used to signal whether the service has completed to components
constructor(private resolver: DataResolver,
logger: Logger) {
this.logger = logger;
}
ngOnInit() {
this.logger.debug('Data Service initialized.');
}
ngOnDestroy() {
this.logger.debug('Data Service destroyed.');
}
load() {
return this.resolver.resolve(); // retrieves the data elements from a web service
}
initData() {
this.dataObs$ = this.load();
this.dataObs$.subscribe((res: Data[]) => {
this.data = res;
this.completed = true;
});
}
}
add.component.ts
import { Component, OnDestroy, OnInit } from '@angular/core';
import { DataService } from '../../shared/data/data.service';
@Component({
selector: 'add',
templateUrl: './add.component.html',
styleUrls: ['./add.component.scss']
})
export class AddComponent implements OnInit, OnDestroy {
radioUrl: string;
constructor(private service: DataService) {
console.log('Add component built');
}
ngOnInit() {
this.service.initData();
console.log('Add component initialized');
}
ngOnDestroy() {
console.log('Add component destroyed');
}
}
type1.component.ts
import { Component, OnDestroy, OnInit } from '@angular/core';
@Component({
selector: 'type1',
templateUrl: './type1.component.html',
styleUrls: ['./type1.component.scss']
})
export class Type1Component implements OnInit, OnDestroy {
title = 'Add Block Stuff';
constructor() {
console.log('Type1 component built');
}
ngOnInit() {
console.log('Type1 component initialized');
}
ngOnDestroy() {
console.log('Type1 component destroyed');
}
onType1Change($event: any) {
console.log($event);
}
}
block.component.ts
import { Component, OnDestroy, OnInit, Output, EventEmitter, Input } from '@angular/core';
import { Logger } from 'ngx-data-utils';
import { Observable } from 'rxjs/Observable';
import { Data } from 'si-data-model';
import { DataService } from '../../shared/data/data.service';
@Component({
selector: 'block',
templateUrl: './block.component.html',
styleUrls: ['./block.component.scss']
})
export class BlockComponent implements OnInit, OnDestroy {
dataLoaded = false;
labels = ['Label1', 'Label2', 'Label3', 'Label4',
'Label5'];
selected: any[] = [];
data1: string;
data2: string;
data3: string;
data4: string;
data5: string;
data6: string;
datas: Data[] = [];
@Output() change: EventEmitter<any> = new EventEmitter();
@Input() title: string;
@Input() data: Data[];
// private criteriaCodes = [6, 2, 3, 11, 29, 25];
constructor(private logger: Logger,
private dataService: DataService) {
// TODO
}
ngOnInit() {
this.display();
this.logger.debug('BlockComponent initialized.');
}
ngOnDestroy() {
this.logger.debug('BlockComponent destroyed.');
}
initData() {
this.dataService.data.forEach((dt: Data) => {
this.datas.push(dt);
this.dataLoaded = true;
});
}
display() {
if (this.dataService.completed)
this.initData();
}
propagateChange() {
this.change.emit(this.selected); // doesn't do anything yet
}
}
block.component.htmlあなたadd.component.ts
データが再度初期化されるたびにregettingされるように見えます
<div class="row" *ngIf="dataLoaded">
<div class="row">
<div class="col-md-4">
<label>{{'DATA.BLOCK.LABEL1' | translate}}</label>
<select class="custom-select form-control" [(ngModel)]="data1" (change)="propagateChange()">
<option *ngFor="let c of data[0].value">{{c.code}} - {{c.description}}</option>
</select>
</div>
<div class="col-md-4">
<label>{{'DATA.BLOCK.LABEL2' | translate}}</label>
<select class="custom-select form-control" [(ngModel)]="data2" (change)="propagateChange()">
<option *ngFor="let mt of data[1].value">{{mt.code}} - {{mt.description}}</option>
</select>
</div>
<div class="col-md-4">
<label>{{'DATA.BLOCK.LABEL3' | translate}}</label>
<select class="custom-select form-control" [(ngModel)]="data3" (change)="propagateChange()">
<option *ngFor="let pem of data[2].value">{{pem.code}} - {{pem.description}}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-4">
<label>{{'DATA.BLOCK.LABEL4' | translate}}</label>
<select class="custom-select form-control" [(ngModel)]="data4" (change)="propagateChange()">
<option *ngFor="let tt of data[3].value">{{tt.code}} - {{tt.description}}</option>
</select>
</div>
<div class="col-md-4">
<label>{{'DATA.BLOCK.LABEL5' | translate}}</label>
<select class="custom-select form-control" [(ngModel)]="data5" (change)="propagateChange()">
<option *ngFor="let cl of data[4].value">{{cl.code}} - {{cl.description}}</option>
</select>
</div>
<div class="col-md-4">
<label>{{'DATA.BLOCK.LABEL6' | translate}}</label>
<input type="text">
</div>
</div>
</div>
plunkerを使用してについては、あなただけ(ちょうど '新しい選択し、Plunkerで| Angular')を生成アンギュラスニペットにコードを追加することができます。そしてあなたのコードを追加してください。それはSystemjsですが、それでもあなたの問題をデモする必要があります。 (Webpackの問題だと思わない限り) – DeborahK
私はそれがウェブパックの問題だとは思わない。翻訳のようなものを取り除き、Plunkrを動作させるにはちょっと時間がかかりますが、それは1000行のコードを投稿するよりも優れています。 –