Angular/AngularJS升级应用在浏览器标签页处于后台时无响应

23
我有一个 Angular/AngularJS 升级应用程序,目前正在将所有内容从 AngularJS 迁移到 Angular。这是一个相当大的项目,因此我肯定需要采用升级的方式。
我使用 @uirouter/angular-hybrid,有一个仍然是 AngularJS(导航和其他相关事项)的根状态以及一个子视图。在这个子视图中,我现在慢慢将所有组件升级为 Angular。出于性能原因,我不得不使用 downgradeModule() (https://angular.io/guide/upgrade-performance) 而不是 UpgradeModule。
对于 UI 组件,我使用 Angular Material 2。
至于设置,现在到了问题/问题所在:
当带有页面的选项卡在后台时,您稍后回到页面(至少 5 到 10 分钟),整个页面都会出现滞后并且无响应。离开时间越长,选项卡在后台的时间就越长,滞后就越长。
我已经尝试/查找到的是:
  • 似乎已注册事件,但由于该选项卡在后台,它们没有被执行,但一旦返回选项卡,它们都会同时执行。以下是性能分析截图 profiling screenshot
  • 删除 Angular 变更检测并使用 ngZone: 'noop' 没有效果
  • 禁用所有动画没有效果
  • 启用Angular的生产模式稍微改善了一点(可能也是一种错觉),但问题仍然存在
  • 我在Chrome中开发,这个问题在其他浏览器(如Firefox、Safari)中也存在
  • 只有当路由视图组件是Angular组件时才会发生,AngularJS视图组件似乎不受影响

我目前正在开发一个干净的示例应用程序来重现这个问题,并为进一步的测试提供更多上下文。我很快就会添加它。

库版本

Angular: 6.1.0

AngularJS: 1.7.2

zone.js: 0.8.26

@uirouter/angular-hybrid: 6.0.0

更新(2019年8月)

当前库版本为Angular 8、AngularJS 1.7.8和uirouter/hybrid 8,仍然存在该问题。


背景事件是否重要?它们是什么类型的事件? - bryan60
我不是很确定。这些事件似乎是从Angular触发的。 - Nicolas Gehlert
3个回答

1

尝试在所有ng2组件上使用这种实现模式。

https://angular.io/api/core/ChangeDetectorRef#detach-change-detector-to-limit-how-often-check-occurs

这个概念是将组件的更新或渲染从angularjs中移除。
来自文档:
class DataListProvider {
  // in a real application the returned data will be different every time
  get data() { return [1, 2, 3, 4, 5]; }
}

@Component({
  selector: 'giant-list',
  template: `
      <li *ngFor="let d of dataProvider.data">Data {{d}}</li>
    `,
})
class GiantList {
  constructor(private ref: ChangeDetectorRef, private dataProvider: DataListProvider) {
    ref.detach();
    setInterval(() => { this.ref.detectChanges(); }, 5000);
  }
}

@Component({
  selector: 'app',
  providers: [DataListProvider],
  template: `
      <giant-list><giant-list>
    `,
})
class App {
}

您将会从组件中分离(),然后手动检测更改。

谢谢你的回答。我会尝试这个方法。但还不太确定如何在没有间隔的情况下检测更改。 - Nicolas Gehlert
你想让我分离父页面组件还是这个页面上使用的所有组件?我刚试了一下只分离了页面组件,但没有任何区别。@captwebdesign - Nicolas Gehlert
仍在努力使更精细的根级别答案可行。 - captwebdesign

0

尝试在每个选项卡加载时处理服务,然后创建新的事件以侦听新更改。

此外,这可能有效,但考虑到自述文件@ https://github.com/ui-router/angular-hybrid#limitations,这是一种解决方法。

自述文件的此部分可能表明降级不是无缝选项:

限制:

我们目前支持将Angular(2+)或AngularJS(1.x)组件路由到AngularJS(1.x)ui-view中。 但是,我们不支持将AngularJS(1.x)组件路由到Angular(2+)ui-view中。

如果您创建了一个Angular(2+)ui-view,则任何嵌套的ui-view也必须是Angular(2+)。

因此,应用程序应从叶状态/视图开始迁移,并向根状态/视图工作。


“在每个选项卡加载时处理服务”是什么意思?是哪个服务?至于第二部分,在我们的情况下并不重要。我们严格遵循他们的指南。Angular JS父视图和Angular 2+子视图。如果您尝试反过来使用路由器,它会抛出一个严重的异常。 - Nicolas Gehlert
尝试根据您的应用程序处理其中一个: https://ui-router.github.io/ng1/docs/latest/classes/state.stateservice.html#dispose https://ui-router.github.io/ng2/docs/latest/classes/state.stateservice.html#dispose - captwebdesign
@NicolasGehlert 我目前正在编写一个基本测试。您说“当包含页面的选项卡在后台时……”。这是一个正常的网页浏览器选项卡,不是具有内容选项卡的某种UI组件? - captwebdesign
@NicolasGehlert 如果它是一个浏览器“选项卡”,如果您让页面(即在浏览器中活动查看的选项卡)静置一段时间,它是否会恢复响应并正常工作? - captwebdesign
是的,普通浏览器标签。如果您让它静置一段时间,它最终会重新变得响应。我猜测是一旦所有累积的事件都被处理完毕了。在非常罕见的情况下,标签会崩溃,只能通过重新启动浏览器来修复。稍后会回来与测试结果。感谢您的工作。 - Nicolas Gehlert
显示剩余3条评论

0

你有尝试过查看UrlHandlingStrategy吗? 我们成功地在AngularJS堆栈上使用了Angular,并在必要时进行了缓慢的重写。

我们所做的是同时使用Angular和AngularJS路由器,使用UrlHandlingStrategy来确定哪个路由由Angular处理,如果该路由不由Angular处理,则会转到AngularJS路由。

我无法查看您的设置,只能猜测。也许是因为路由一直来回跳转,


实际上我已经尝试过了,但问题在于我的设置非常复杂,涉及到抽象状态,而且我需要为两个Angular版本都进行复制。所以我被迫使用UI Router Hybrid。状态转换很好,没有状态乒乓现象。至少从外部来看是这样的,不知道它们在幕后做了什么,但我严格遵循他们的设置建议。感谢您的回答。 - Nicolas Gehlert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接