【问题标题】:What is the performance impact for a class / interface with a lot of fields?具有很多字段的类/接口对性能有什么影响?
【发布时间】:2017-07-17 13:23:20
【问题描述】:

我的 Angular 4 应用程序中有一个类(接口),它有很多字段。 请注意,此类/接口的实例是 immutable(即成员永远不会被更改)。

例如

public interface IHaveALotOfFields {
    field1: string;
    //...
    field500: string;
}

此接口是通过(提供单例/应用程序级别)服务提供的,该服务将类公开为成员。例如

@Injectable()
public class MyService {
    public translations: ITranslationsProvider;
}

服务被注入到很多组件(几乎所有组件)中,并且经常在它们对应的模板中使用,也经常在组件的ts-部分中使用。例如。

@Component({
               template: `Value: {{service.field500}}`
           })
export class MyComponent {
    public constructor(public service: MyService) {
    }

    private doSomething(): string {
        return this.service.field1;
    }
}

现在我的问题:

  • 一个大类(有很多字段)会因为变化检测而使角度变慢吗?
  • 有没有办法将一个类标记为“在更改检测时忽略我”? (类似于ChangeDetectionStrategy.OnPush,但不是为每个组件指定这个,而是可以在类本身或服务成员上声明)

请注意,我不想将所有组件的更改检测策略更改为OnPush

【问题讨论】:

  • 接口只是类型检查的一种方式。它不会被注入......只有被 new 为类实例化的对象才会被注入。接口是类将遵守的契约。在界面中,您为合同分配属性和方法签名...服务具有 @Injectable 并且 Angular 负责这些实例化,以便您自动将事物连接在一起。
  • 我知道。我有实现这个接口的具体类。 MyService 基本上得到了一个实现注入接口的类的实例。
  • 接口不只注入对象。这就是我希望能帮助你的。即你不能在界面上做新的......

标签: angular angular2-changedetection


【解决方案1】:

一个大类(有很多领域)会因为以下原因而使角度变慢吗 变化检测?

没有。角度变化检测执行两个读取类属性的操作:

  • 当前组件上的 DOM 更新
  • 子组件/指令的输入绑定更新

对于这些操作,Angular 编译器创建了两个函数:

  • updateRenderer - 读取模板中使用的字段
  • updateDirectives - 读取输入绑定表达式中指定的字段

这些函数只读取服务的特定属性。以你为例

Value: {{service.field500}}

updateRenderer 函数看起来大致如下:

function(_ck,_v) {
    var _co = _v.component;
    var currVal_0 = _co.service.field500;
    _ck(_v,1,0,currVal_0);

每个摘要循环都会调用这些函数。但正如您所见,只会从服务中读取相关属性。因此,服务上有多少属性并不重要。

有什么方法可以将类标记为“更改检测时忽略我”?

我假设您是在询问我们在 AngularJS 中的一次性绑定。也许它也会被添加到 Angular 中。如果出现问题,我将对此进行监控并更新答案。但您可能知道,您可以使用cd.detach/cd.attach 禁用/启用组件的更改检测。您可以监听来自服务的一些信号,并在需要时手动运行 cd。

以下是您可以阅读的文章列表,以更好地了解变更检测的机制:

【讨论】:

  • 感谢您的出色回答。我的意思是将一个类标记为“在更改检测时忽略我”的意思是,如果有一种方法可以告诉 Angular 这个特定类的属性/字段是“常量”(具有常量值)并且永远不会改变。不管这个类是从服务中注入的,还是作为输入注入的。
  • @OschtärEi,啊,我明白了。不,不幸的是,还没有办法做到这一点。在 AngularJS 中,我们有一次性绑定。也许它也会被添加到 Angular 中。如果出现问题,我将对此进行监控并更新答案。但是您可能知道您可以使用cd.detach/cd.attach 禁用/启用组件的更改检测。您可以监听来自服务的一些信号,并在需要时手动运行 cd。
  • 再次感谢。但是如果我使用detach/attach,组件的所有更改检测都将被分离(我不想要),而且我需要在我的所有组件中执行此操作(因为几乎所有组件都使用这个“大类”(它是用于翻译)。
  • @OschtärEi,我明白了。正如我所说,您目前无能为力。
猜你喜欢
  • 2015-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 2020-03-22
相关资源
最近更新 更多