Утечки памяти в 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 для дочерних компонентов, чтобы общаться с родительскими компонентами. Я специально придерживаюсь одного правила:
Родительские компоненты слушают только ПРЯМЫЕ дочерние компоненты.
Здесь родительские компоненты действуют как компоненты контейнера, а дочерние компоненты действуют как компоненты представления.
Таким образом, я могу убедиться, что всякий раз, когда я удаляю дочерний компонент, есть только одна точка, которая является прямым родителем, для удаления всех его слушателей. Пока что это правило работает довольно хорошо для меня.