调度上的Angular2 NGRX性能问题? [英] Angular2 NGRX Performance Issues On Dispatch?

查看:64
本文介绍了调度上的Angular2 NGRX性能问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在Angular2/CLI/NGRX中开发一个应用程序,直到最近为止一切都进行得很好.我注意到性能出现了相当大的峰值,特别是在同一容器内连续调度时.

I've been working on an application in Angular2/CLI/NGRX and things have been going well until recently. I'm noticing some pretty big spikes in performance especially with consecutive dispatches within the same container.

例如,可以说我定义了以下内容:

For example lets say I have the following defined:

public appEnvironment$: Observable<IEnvironment>;

public assessment$: Observable<IAssessment>;
public assessmentComments$: Observable<ICommentActivity[]>;
public assessmentEvidence$: Observable<IEvidenceActivity[]>;
public assessmentIssues$: Observable<IIssueActivity[]>;
public assessmentSurvey$: Observable<ISurvey>;
public assessmentUsers$: Observable<ISystemUser[]>;
public assessmentSelectedNode$: Observable<ISurveyChildNode>;

constructor(private _store: Store<fromDomain.State>, private _route: ActivatedRoute) {
  this.appEnvironment$ = _store.select(fromDomain.getEnvironment).share();

  this.assessment$ = _store.select(fromDomain.getAssessment).share();
  this.assessmentComments$ = _store.select(fromDomain.getAssessmentComments).share();
  this.assessmentIssues$ = _store.select(fromDomain.getAssessmentIssues).share();
  this.assessmentEvidence$ = _store.select(fromDomain.getAssessmentEvidence).share();
  this.assessmentSurvey$ = _store.select(fromDomain.getAssessmentSurvey).share();
  this.assessmentUsers$ = _store.select(fromDomain.getAssessmentUsers).share();
  this.assessmentSelectedNode$ = _store.select(fromDomain.getAssessmentSelectedNode).share();

  this.openAssessmentId = _route.snapshot.params['id'];

  this._store.dispatch(new LoadAssessmentAction(this.openAssessmentId));
}

还值得注意的是,以上是加载子组件及其在多个组件之间共享的数据所需的所有状态选择(因此,.share()如下):

It's also worth noting that the above is all the state selection required to load the child components and their data shared across multiple components (hence the .share()) something like:

<opt-drawer-index
  #drawerShow
  [leftHeading]="'Survey Info'"
  [leftIcon]="'fa-bars'"
  [rightHeading]="'Assessment Details'"
  [onForceChange]="assessmentSelectedNode$ | async">
  <section drawer-left-content>
    <opt-assessment-show-survey-info
      [appEnvironment]="appEnvironment$ | async"
      [assessment]="assessment$ | async"
      [assessmentUsers]="assessmentUsers$ | async"></opt-assessment-show-survey-info>
  </section>
  <section drawer-content>
    <opt-assessment-show-content
      [appEnvironment]="appEnvironment$ | async"
      [assessment]="assessment$ | async"
      [assessmentSurvey]="assessmentSurvey$ | async"
      (selectedNode)="changeSelectedNode($event)"></opt-assessment-show-content>
  </section>
  <section drawer-right-content>
    <opt-assessment-show-details
      [activeNode]="assessmentSelectedNode$ | async"
      [appEnvironment]="appEnvironment$ | async"
      [assessment]="assessment$ | async"
      [assessmentComments]="assessmentComments$ | async"
      [assessmentEvidence]="assessmentEvidence$ | async"
      [assessmentIssues]="assessmentIssues$ | async"
      [assessmentUsers]="assessmentUsers$ | async"></opt-assessment-show-details>
  </section>
</opt-drawer-index>

初始负载很大,效果很好.我的冻结状态处于活动状态,并且该状态内没有发生任何突变.所有组件也都在使用OnPush策略.

The initial load is great and works well. I have the freeze-state active and no mutations are occurring within the state. All components are utilizing the OnPush strategy as well.

问题出在中心内容组件内,我有一个与容器组件对话的事件发射器.它发送一个对象以选择",并通过分派器触发一个动作,以使用所选选项更新状态.最初的几次咔哒声运行得非常好,然后您继续注意到整个子组件的不同区域时,开始注意到一些严重的功耗.似乎调度员似乎陷入了困境.

The problem is within the center content component I have an event emitter that talks with the container component. It sends up an object to 'select' and that fires off an action through the dispatcher to update the state with the selected option. The first couple clicks run great and then you start to notice some serious power consumption as you continue to click on different areas throughout the child components. It's almost as if the dispatcher seems to be bogged down.

我已经尝试了一些方法,例如使用CombineLatest()和其他工具来减轻更新负担,但这似乎使情况变得更糟.当前,应用程序加载数据的方式如下:

I've tried a few things like using combineLatest() and other tools to lessen the burden on the updates, however that seemed to make matters worse. Currently the way the application loads data is as follows:

Load Assessment -> After Load Assessment Effect -> Select Assessment -> After Load Selected Assessment Effect

还有其他人遇到性能问题吗?这与NGRX和我的设置方式无关吗?我主要使用NGRX示例应用程序作为设置布局的参考点.

Anyone else run into performance issues? Is it something unrelated to NGRX and the way that I have things setup? I've mainly used the NGRX example app as a reference point for how to lay out my setup.

编辑

这是我遇到的问题的时间轴表示.好像点击事件越来越长了吗?

Here's a timeline representation of the problem I'm having. It's almost as though the click event is getting exponentially longer?

编辑2

我正在使用重新选择功能,这是后续单击后挂起的页面的效果:

I am using reselect and here's the effects for the page that is hanging after subsequent clicks:

import {Injectable} from "@angular/core";

// NGRX
import {Actions, Effect} from "@ngrx/effects";
import {Action} from "@ngrx/store";

// Services
import {AssessmentService} from "./assessment.service";
import {SurveyService} from "../survey/survey.service";
import {SystemUserService} from "../system-user/system-user.service";

// Observable and operators
import {Observable} from "rxjs/Observable";
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/concatMap';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/map';

// Misc
import * as assessment from './assessment.actions';
import * as assessmentNav from './navigation/assessments-navigation.actions';

@Injectable()
export class AssessmentEffects {
  constructor(private actions$: Actions, private assessmentsService: AssessmentService,
              private surveyService: SurveyService, private systemUserService: SystemUserService) { }

  @Effect()
  effLoadAssessment$: Observable<Action> = this.actions$
    .ofType(assessment.ActionTypes.LOAD_ASSESSMENT)
    .map((action: assessment.LoadAssessmentAction) => action.payload)
    .switchMap(guid => {
      return this.assessmentsService.getAssessment(guid)
        .map(v => new assessment.LoadAssessmentCompleteAction(v));
    });

  @Effect()
  effAfterLoadAssessment: Observable<Action> = this.actions$
    .ofType(assessment.ActionTypes.LOAD_ASSESSMENT_COMPLETE)
    .map((action: assessment.LoadAssessmentCompleteAction) => action.payload)
    .mergeMap(theAssessment => {
      return [
        new assessment.LoadAssessmentSurveyAction(theAssessment.surveyID),
        new assessmentNav.AssessmentNavAddAction(theAssessment),
        new assessment.LoadAssessmentUserAction(theAssessment.instanceOwner_SystemUserID)
      ];
    });

  @Effect()
  effLoadAssessmentComments$: Observable<Action> = this.actions$
    .ofType(assessment.ActionTypes.LOAD_ASSESSMENT_COMMENTS)
    .map((action: assessment.LoadAssessmentCommentsAction) => action.payload)
    .switchMap(multiRequest => {
      return this.assessmentsService
        .getAssessmentComments(multiRequest.assessmentId, multiRequest.type, multiRequest.nodeId)
        .map(v => new assessment.LoadAssessmentCommentsCompleteAction(v));
    });

  @Effect()
  effAfterSelectedNode$: Observable<Action> = this.actions$
    .ofType(assessment.ActionTypes.SELECT_ASSESSMENT_NODE)
    .map((action: assessment.SelectedNodeAction) => action.payload)
    .mergeMap(theNode => {
      return [
        new assessment.LoadAssessmentCommentsAction({
          type: 'Comments',
          nodeId: theNode.id,
          assessmentId: theNode.assessmentId
        }),
        new assessment.LoadAssessmentIssuesAction({
          type: 'Issues',
          nodeId: theNode.id,
          assessmentId: theNode.assessmentId
        }),
        new assessment.LoadAssessmentEvidenceAction({
          type: 'Attachments',
          nodeId: theNode.id,
          assessmentId: theNode.assessmentId
        })
      ];
    });

  @Effect()
  effLoadAssessmentIssues$: Observable<Action> = this.actions$
    .ofType(assessment.ActionTypes.LOAD_ASSESSMENT_ISSUES)
    .map((action: assessment.LoadAssessmentIssuesAction) => action.payload)
    .switchMap(multiRequest => {
      return this.assessmentsService
        .getAssessmentIssues(multiRequest.assessmentId, multiRequest.type, multiRequest.nodeId)
        .map(v => new assessment.LoadAssessmentIssuesCompleteAction(v));
    });

  @Effect()
  effLoadAssessmentEvidence$: Observable<Action> = this.actions$
    .ofType(assessment.ActionTypes.LOAD_ASSESSMENT_EVIDENCE)
    .map((action: assessment.LoadAssessmentEvidenceAction) => action.payload)
    .switchMap(multiRequest => {
      return this.assessmentsService
        .getAssessmentEvidence(multiRequest.assessmentId, multiRequest.type, multiRequest.nodeId)
        .map(v => new assessment.LoadAssessmentEvidenceCompleteAction(v));
    });

  @Effect()
  effLoadAssessmentUser$: Observable<Action> = this.actions$
    .ofType(assessment.ActionTypes.LOAD_ASSESSMENT_USER)
    .map((action: assessment.LoadAssessmentUserAction) => action.payload)
    .concatMap(guid => {
      return this.systemUserService.getSystemUser(guid)
        .map(v => new assessment.LoadAssessmentUserCompleteAction(v));
    });

  @Effect()
  effLoadAssessmentSurvey$: Observable<Action> = this.actions$
    .ofType(assessment.ActionTypes.LOAD_ASSESSMENT_SURVEY)
    .map((action: assessment.LoadAssessmentSurveyAction) => action.payload)
    .switchMap(guid => {
      return this.surveyService.getSurvey(guid)
        .map(v => new assessment.LoadAssessmentSurveyCompleteAction(v));
    });
}

推荐答案

减速实际上与@ngrx/store-devtools有关.从应用程序中删除模块后,速度非常快.我们希望使用该工具进行状态快照和重播,但是我不确定是否会因为性能下降而走这条路.

The slowdown was actually related to the @ngrx/store-devtools. After I removed the module from the application the speed was phenomenal. We were hoping to use the tooling for snapshotting and replaying state, but I'm not sure we can go down that route anymore with the performance hit.

这篇关于调度上的Angular2 NGRX性能问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆