Are impure pipes in Angular 2 (pure = false) bad for my performance?
Asked Answered
F

2

15

I have a translate pipe, which accepts a string as key, and returns the translated string from a dictionary. The pipe looks like this:

import {Pipe, PipeTransform} from 'angular2/core';
import {TranslateService} from './translate.service';

@Pipe({
    name: 'translate',
    pure: false
})
export class TranslatePipe implements PipeTransform {

    constructor(private _translateService : TranslateService) {
    }
    transform(key: string): any {
        var translatedText = this._translateService.resources[key];
        if (translatedText)
            return translatedText;
        return key;
    }
}

I use the pipe in my templates like this:

<div>{{'login_EnterNewPassword'|translate}}</div>

Which will be rendered in my HTML like this:

<div>Please enter a new password</div>

So far so good!

The TranslatePipe depends on the TranslateService, which holds a dictionary called resources with translations of the current language. The TranslateService's resource gets loaded with an ajax http call to a server, and it can get reloaded behind the scenes, if a user selects a different language.

Because i need my UI to update all texts when this happens, i have set the pure property of the pipe to false.

Everything works perfect, but the thing is, the pipe gets executed very often, since it's impure. If the user enters a 10 character password, change tracking starts on every key-down and key-up, and the pipe gets executed hundres of times for all different translated texts on the page.

The main question is: Is this a bad thing, and does it have much negative impact on the overall performance???

Or is there another way to force angular to reevaluate everything on demand, for example only when the language changes???

Fluker answered 31/3, 2016 at 14:45 Comment(0)
D
8

Impure pipes have quite an impact on performance, especially when they do non-trivial work like copying, filtering and sorting arrays.

Impure pipes are called on every change detection cycle, no matter what. It's wise to cache results if possible to avoid doing the same work over and over if possible.

Pure pipes are only called when the input value or parameters have changed.

If possible you can keep the pipe pure and instead add an additional parameter. Updating that parameter causes the pipe to be run again.

Dane answered 12/6, 2016 at 10:3 Comment(4)
"If possible you can keep the pipe pure and instead add an additional parameter" Is it possible to do the same with pipe class property not with the pipe parameter? (if the pipe property changes, do the same as if the parameter dies) My pipe uses a translation service that returns current language and i wouldn't want to add this service to every component, just to be able to pass the language as a parameter to the pipe.Barling
@GregorSrdic I understand that but I don't know of other options.Jereme
@GünterZöchbauer You can use i18n alt.Participle
@Participle right. That wan't around yet when I posted this answer :DJereme
V
0

It is not recommended to use impure pipe. I will impact your performance. It will be called even source has not been changed.

To see this.

  name: 'empFilter',
  pure: false
})
export class EmpFilterPipe implements PipeTransform {
  private count = 0;
  transform(employees: Employee[], searchValue?: string): Employee[] {
    console.log(this.count++);
   }
}

onMouseOver(): void{

}

<div *ngFor="let emp of employees | empFilter : searchValue" 
     (mouseover)="onMouseOver()">
        {{emp.name}}
</div> 
Valve answered 10/2, 2019 at 10:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.