Angular 服务器端渲染应用常见的内存泄漏问题小结

 更新时间:2022年06月23日 10:33:46   作者:JerryWang_sap  
这篇文章主要介绍了Angular 服务器端渲染应用一个常见的内存泄漏问题,主要包括屏幕闪烁问题,出现闪烁的原因,在于 Angular 不知道如何重用它在服务器上成功渲染的内容,本文给大家介绍的非常详细,需要的朋友一起学习下吧

考虑如下的 Angular 代码:

import { Injectable, NgZone } from "@angular/core";
import { interval } from "rxjs";
@Injectable()
export class LocationService {
  constructor(ngZone: NgZone) {
    ngZone.runOutsideAngular(() => interval(1000).subscribe(() => {
      ...
    }));
  }
}

这段代码不会影响应用程序的稳定性,但是如果应用程序在服务器上被销毁,传递给订阅的回调将继续被调用。 服务器上应用程序的每次启动都会以 interval 的形式留下一个 artifact.

这是一个潜在的内存泄漏点。

这个内存泄漏风险可以通过使用 ngOnDestoroy 钩子解决。这个钩子适用于 Component 和 service. 我们需要保存 interval 返回的订阅(subscription),并在服务被销毁时终止它。

退订 subscription 的技巧有很多,下面是一个例子:

import { Injectable, NgZone, OnDestroy } from "@angular/core";
import { interval, Subscription } from "rxjs";
@Injectable()
export class LocationService implements OnDestroy {
  private subscription: Subscription;

  constructor(ngZone: NgZone) {
    this.subscription = ngZone.runOutsideAngular(() =>
      interval(1000).subscribe(() => {})
    );
  }
  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }
}

屏幕闪烁问题

用户的浏览器显示从服务器渲染并返回的页面,一瞬间出现白屏,闪烁片刻,然后应用程序开始运行,看起来一切正常。出现闪烁的原因,在于 Angular 不知道如何重用它在服务器上成功渲染的内容。在客户端环境中,它从根元素中 strip 所有 HTML 并重新开始绘制。

闪烁问题可以抽象成如下步骤:

关于正在发生的事情的一个非常简化的解释:

(1) 用户访问应用程序(或刷新)

(2) 服务器在服务器中构建html

(3) 它被发送到用户的浏览器端

(4) Angular 重新创建 应用程序(就好像它是一个常规的非 Angular Universal 程序)

(5) 当上述四个步骤发生时,用户会看到一个 blink 即闪烁的屏幕。

代码如下:

// You can see this by adding:
// You should see a console log in the server
// `Running on the server with appId=my-app-id`
// and then you'll see in the browser console something like
// `Running on the browser with appId=my-app-id`
export class AppModule {
  constructor(
    @Inject(PLATFORM_ID) private platformId: Object,
    @Inject(APP_ID) private appId: string) {
    const platform = isPlatformBrowser(this.platformId) ?
      'in the browser' : 'on the server';
    console.log(`Running ${platform} with appId=${this.appId}`);
  }
}

无法通过 API 的方式终止渲染

什么时候需要人为干预的方式终止一个服务器端渲染?

始终明确一点,渲染应用程序的时间点发生在应用程序 applicationRef.isStable 返回 true 时,参考下列代码:

github.com/angular/ang…

function _render<T>(
    platform: PlatformRef, moduleRefPromise: Promise<NgModuleRef<T>>): Promise<string> {
  return moduleRefPromise.then((moduleRef) => {
    const transitionId = moduleRef.injector.get(ɵTRANSITION_ID, null);
    if (!transitionId) {
      throw new Error(
          `renderModule[Factory]() requires the use of BrowserModule.withServerTransition() to ensure
the server-rendered app can be properly bootstrapped into a client app.`);
    }
    const applicationRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
    return applicationRef.isStable.pipe((first((isStable: boolean) => isStable)))
        .toPromise()
        .then(() => {
          const platformState = platform.injector.get(PlatformState);
         ...

到此这篇关于Angular 服务器端渲染应用一个常见的内存泄漏问题的文章就介绍到这了,更多相关Angular内存泄漏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • angularjs的一些优化小技巧

    angularjs的一些优化小技巧

    这篇文章主要介绍了angularjs的一些优化小技巧,本文总结了5种优化技巧,如一次绑定、尽可能少调用 ng-repeat、尽量在指令里写原生语法、页面内尽量少用filters等,需要的朋友可以参考下
    2014-12-12
  • 详解如何使用webpack+es6开发angular1.x

    详解如何使用webpack+es6开发angular1.x

    本篇文章主要介绍了详解如何使用webpack+es6开发angular1.x,具有一定的参考价值,有兴趣的可以了解一下
    2017-08-08
  • AngularJS语法详解(续)

    AngularJS语法详解(续)

    本文续上文,接着介绍AngularJS语法,和上文一样,都是通过示例来向大家分析说明,非常不错的一篇文章,推荐给大家。
    2015-01-01
  • AngularJS基于ngInfiniteScroll实现下拉滚动加载的方法

    AngularJS基于ngInfiniteScroll实现下拉滚动加载的方法

    这篇文章主要介绍了AngularJS基于ngInfiniteScroll实现下拉滚动加载的方法,结合实例形式分析AngularJS下拉滚动插件ngInfiniteScroll的下载、功能、属性及相关使用方法,需要的朋友可以参考下
    2016-12-12
  • 关于使用axios的一些心得技巧分享

    关于使用axios的一些心得技巧分享

    vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios,所以下面这篇文章主要给大家分享了关于使用axios的一些心得技巧,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-07-07
  • angularjs实现的前端分页控件示例

    angularjs实现的前端分页控件示例

    本篇文章主要介绍了angularjs实现的前端分页控件示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • Angular应用懒加载模块配置管理详解

    Angular应用懒加载模块配置管理详解

    这篇文章主要为大家介绍了Angular应用懒加载模块配置管理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • AngularJS中控制器函数的定义与使用方法示例

    AngularJS中控制器函数的定义与使用方法示例

    这篇文章主要介绍了AngularJS中控制器函数的定义与使用方法,结合具体实例形式分析了AngularJS控制器函数的定义、绑定及相关使用技巧,需要的朋友可以参考下
    2017-10-10
  • 深入解析AngularJS框架中$scope的作用与生命周期

    深入解析AngularJS框架中$scope的作用与生命周期

    这篇文章主要介绍了AngularJS中$scope的作用与生命周期,包括在DOM中添加controller对象的相关用法,需要的朋友可以参考下
    2016-03-03
  • Angular2搜索和重置按钮过场动画

    Angular2搜索和重置按钮过场动画

    这篇文章主要介绍了Angular2搜索和重置按钮过场动画,需要的朋友可以参考下
    2017-05-05

最新评论