Утечки памяти в Angular2

Что может вызвать утечки памяти в приложении Angular2 (rc5)? Как их предотвратить?

Неправильные / правильные примеры кода будут высоко оценены.

2 ответа

Решение

В браузере Angular - это просто JavaScript, поэтому применяются типичные предостережения.

Одна из вещей, против которой Angular специально предупреждает, - это Observables. После того, как вы подпишетесь на один, он будет работать до тех пор, пока вы не отмените подписку, даже если вы перейдете в другое представление. Угловой неписывает для вас, где это возможно (например, если вы используете async труба в шаблоне:

модель

//listenToServer returns an observable that keeps emitting updates
serverMsgs = httpService.listenToServer();

шаблон

<div>{{serverMsgs | async}}</div>

Angular покажет серверные сообщения в div, но завершит подписку, когда вы уйдете.

Однако, если вы подписываетесь самостоятельно, вы также должны отписаться:

модель

msgs$ = httpService.listenToServer().subscribe(
    msg => {this.serverMsgs.push(msg); console.log(msg)}
);

шаблон

<div *ngFor="let msg of serverMsgs">{{msg}}</div>

Когда вы уходите, даже если вы не видите, что новые сообщения появляются в представлении, вы увидите их напечатанными на консоли по мере их поступления. Чтобы отменить подписку при утилизации компонента, вы должны сделать:

ngOnDestroy(){ this.msgs$.unsubscribe(); }

Из документов:

мы должны отписаться, прежде чем Angular уничтожит компонент. Невыполнение этого требования может привести к утечке памяти.

Аспект подписки и отписки, который упомянутый выше BeetleJuice, безусловно, является предосторожностью №1, которую мы должны помнить, чтобы предотвратить утечку памяти.

Чтобы лучше понять некоторые методы управления памятью, вы можете взглянуть на Управление памятью в приложениях Angular. (Заметим, что вы можете найти одну и ту же статью на нескольких сайтах. Вопрос авторского права здесь и там?)

Есть одна вещь, которую я хотел бы сказать о "слушателях событий", в частности. В недавнем проекте, который я сделал, я использую Event emitter и listeners для дочерних компонентов, чтобы общаться с родительскими компонентами. Я специально придерживаюсь одного правила:

Родительские компоненты слушают только ПРЯМЫЕ дочерние компоненты.

Здесь родительские компоненты действуют как компоненты контейнера, а дочерние компоненты действуют как компоненты представления.

Таким образом, я могу убедиться, что всякий раз, когда я удаляю дочерний компонент, есть только одна точка, которая является прямым родителем, для удаления всех его слушателей. Пока что это правило работает довольно хорошо для меня.

Другие вопросы по тегам