angular 性能_如何从Angular应用中获得最佳性能

angular 性能

by Mark Grichanik

马克·格里卡尼克(Mark Grichanik)

如何从Angular应用中获得最佳性能 (How to get the best performance out of your Angular apps)

Angular is a great framework and can be used for developing large scale applications, but can be tricky to fine tune and achieve good load time and run-time performance. In this post, I’ll detail some best practices I have learned along the way, so you will not make the same mistakes I made.

Angular是一个很好的框架,可用于开发大规模应用程序,但要进行微调并获得良好的加载时间和运行时性能可能会很棘手。 在本文中,我将详细介绍我在此过程中学到的一些最佳实践,因此您不会犯同样的错误。

变更检测 (Change detection)

Change detection is Angular’s mechanism to see if there are any values that have been changed and require the view to be updated. By default, Angular runs change detection with nearly every user interaction. In order to know if the view should be rendered again, Angular accesses the new updated value, compares it with the old one and makes the decision. As your application grows, it will include a lot of expressions, and having a change detection cycle on each one of them will cause a performance problem.

更改检测是Angular的机制,用于查看是否存在任何已更改的值并需要更新视图。 默认情况下,Angular几乎与每个用户交互都运行更改检测。 为了知道是否应该再次渲染视图,Angular访问了新的更新值,将其与旧值进行比较并做出决定。 随着您的应用程序的增长,它将包含许多表达式,并且每个表达式都有一个更改检测周期将导致性能问题。

We can optimize things if we create a ‘dumb’ component with a certain attribute to handle the change detection cycles. This component relies only on non specific input data and in that way, we can tell Angular only to run change detection when an input changes or when we manually trigger it. When a reference type is immutable, every time the object is being updated, the reference on the stack memory will have to change. Now we can have a simple reference check on the object between the memory address and the stack. If the memory address has changed, then we check all the values. This will skip change detection in that component.

如果我们创建具有特定属性的“哑巴”组件来处理变更检测周期,那么我们可以优化事物。 该组件仅依赖于非特定的输入数据,这样,我们可以告诉Angular仅在输入发生更改或手动触发时才运行更改检测。 当引用类型是不可变的时,每次更新对象时,堆栈存储器上的引用就必须更改。 现在,我们可以对内存地址和堆栈之间的对象进行简单的引用检查。 如果内存地址已更改,则我们检查所有值。 这将跳过该组件中的更改检测。

We need to keep in mind that primitive types such as numbers, booleans, strings, etc are passed by value. Objects, arrays and functions are also passed by value, but the value is a copy of a reference.

我们需要记住,原始类型(例如数字,布尔值,字符串等)是通过值传递的。 对象,数组和函数也按值传递,但该值是引用的副本。

You can look for more details on that here.

您可以在此处查找更多详细信息。

And now we will see two examples of how this is implemented.

现在,我们将看到两个有关如何实现此示例的示例。

示例: ChangeDetectionStrategy.Default (Example: ChangeDetectionStrategy.Default)

You don’t have to specify changeDetection type, it will be ‘ChangeDetectionStrategy.Default’ by default.

您不必指定changeDetection类型,默认情况下它将为'ChangeDetectionStrategy.Default'。

ChangeDetectionStrategy.OnPush (ChangeDetectionStrategy.OnPush)

In order to use the OnPush change detection, we need to modify the child component from the first example.

为了使用OnPush更改检测,我们需要从第一个示例中修改子组件。

最小化DOM操作 (Minimize DOM manipulations)

If you have some list of data that was retrieved from some server and you need to show it, you are probably using the Angular directive, ngFor. Angular will create a new template for you for each item in that list.

如果您有一些从某个服务器检索到的数据列表,并且需要显示它,则可能使用的是Angular指令ngFor Angular将为该列表中的每个项目创建一个新模板。

If at some point some of the data has been changed, Angular can’t really know that and will replace the whole list, instead of just the items that were changed. In order to improve that, Angular provide us with the trackBy function.trackBy takes a function which has two arguments: index and item. If trackBy is given, Angular tracks changes by the return value of the function.

如果某些数据已经更改,Angular可能真的不知道,它将替换整个列表,而不仅仅是已更改的项目。 为了改善这一点,Angular为我们提供了trackBy函数。 trackBy采用具有两个参数的函数: indexitem 。 如果trackBy ,则Angular轨迹会根据函数的返回值而变化。

Syntax:

句法:

Most common use is just to return the index itself or item.id as a unique identifier for the item: trackByFn(index, item){ return item.id; }.

最常见的用途是返回索引本身或item.id作为项目的唯一标识符: trackByFn(index, item){ return item.id; } trackByFn(index, item){ return item.id; }

With that, Angular can track which items have been added or removed according to the unique identifier and create or destroy only the things that were changed.

这样,Angular可以根据唯一标识符跟踪已添加或删除的项目,并仅创建或销毁已更改的项目。

避免在模板中使用方法 (Avoid using methods in your template)

While it is very convenient to use methods in Angular templates, Angular will recalculate them on each change detection. For larger lists it will affect rendering time and the application may even get stuck due to huge memory consumption. In the following example, Angular will run getNumberOfCars on each change detection cycle (ie upon adding a new row).

虽然在Angular模板中使用方法非常方便,但是Angular会在每次更改检测时重新计算它们。 对于较大的列表,它将影响渲染时间,并且由于巨大的内存消耗,应用程序甚至可能卡住。 在以下示例中,Angular将在每个更改检测周期(即,添加新行时)运行getNumberOfCars

How can we handle this situation? We can pre-compute the results and then just access the data we have computed. In our example, we can add a new attribute to the person object, vehiclesNumber, which holds in advance the amount of vehicles each person has. The other way to do this is by implementing the method getNumberOfCars as a pure pipe.

我们如何处理这种情况? 我们可以预先计算结果,然后访问已计算的数据。 在我们的示例中,我们可以向人员对象VehicleNumber添加一个新属性,该属性预先保存每个人拥有的车辆数量。 另一种方法是将getNumberOfCars方法实现为纯管道。

According to Angular pipe documentation:

根据Angular管道文档

Angular executes a pure pipe only when it detects a pure change to the input value. A pure change is either a change to a primitive input value (String, Number, Boolean, Symbol) or a changed object reference (Date, Array, Function, Object).

Angular仅在检测到输入值的纯变化时才执行纯管道 。 纯粹的更改是对原始输入值的更改( StringNumberBooleanSymbol )或更改的对象引用( DateArrayFunctionObject )。

Angular ignores changes within (composite) objects.
Angular忽略(复合)对象内的更改。
This may seem restrictive but it’s also fast. An object reference check is fast — much faster than a deep check for differences — so Angular can quickly determine if it can skip both the pipe execution and a view update.
这似乎很严格,但速度很快。 对象引用检查很快-比进行深度检查要快得多-因此Angular可以快速确定它是否可以跳过管道执行和视图更新。

The pipe will still be executed on each change detection cycle. However, if a pipe is executed more than once with the same parameters, the results of the first execution are returned. Meaning, Angular will cache the results for better performance.

该管道仍将在每个更改检测周期执行。 但是,如果使用相同的参数多次执行管道,则返回第一次执行的结果。 这意味着,Angular将缓存结果以获得更好的性能。

Let’s see an example.

让我们来看一个例子。

Without a pipe:

没有管道:

While with a pipe we will get:

使用管道时,我们将获得:

We can see it will recalculate only on the new data, instead of the whole list.

我们可以看到它将仅对新数据而不是整个列表进行重新计算。

在生产中使用Prod标志 (Use Prod flag in production)

It will disable Angular’s development mode, which turns off assertions and other checks within the framework. This will also increase your performance. You can find more details here.

它将禁用Angular的开发模式,该模式将关闭框架中的断言和其他检查。 这也将提高您的性能。 您可以在此处找到更多详细信息。

不要在生产代码中使用console.log (Don’t use console.log in production code)

console.log prints can really slow down your application, as it takes some time to compute what you want to print. Also, for long information it will also consume some more time for the printing process.

console.log打印确实会减慢您的应用程序的速度,因为它需要一些时间来计算要打印的内容。 同样,对于较长的信息,打印过程也将花费更多时间。

别忘了取消订阅您的观测值 (Don’t forget to unsubscribe from your observables)

Your subscription holds a reference to your component instance. If you will not unsubscribe from it, the instance will not be cleared by the garbage collector which will cause a memory leak. You can unsubscribe easily by using ngOnDestory(){this.subscription.unsubscribe();}. You can read more about it here.

您的订阅包含对组件实例的引用。 如果您不取消订阅该实例,那么垃圾回收器将不会清除该实例,这将导致内存泄漏。 您可以使用ngOnDestory(){this.subscription.unsubscribe();}轻松地取消订阅。 您可以在此处了解更多信息。

最后的话 (Final Words)

If you run into any issues, feel free to drop me a line at : markgrichanik[at]gmail[dot]com.

如果您遇到任何问题,请随时给我留言markgrichanik [at] gmail [dot] com

I would also love to hear any feedback/tips you have while working on large scale applications with Angular.

我也很想听听您使用Angular进行大规模应用程序时遇到的任何反馈/提示。

If you liked this article, ? away so that others can read it as well
如果您喜欢这篇文章,? 离开,以便其他人也可以阅读

翻译自: https://www.freecodecamp.org/news/how-to-get-the-best-performance-out-of-your-angular-apps-d5132a6c3335/

angular 性能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值