Lo siento si esto ya se ha respondido aquí, pero no pude encontrar ninguna coincidencia para nuestro escenario específico, ¡así que aquí va!
Hemos tenido una discusión en nuestro equipo de desarrollo, con respecto a las llamadas a funciones en plantillas angulares. Ahora, como regla general, estamos de acuerdo en que no debe hacer esto. Sin embargo, hemos tratado de discutir cuándo podría estar bien. Déjame darte un escenario.
Digamos que tenemos un bloque de plantilla que está envuelto en un ngIf, que verifica múltiples parámetros, como aquí:
<ng-template *ngIf="user && user.name && isAuthorized">
...
</ng-template>
¿Habría una diferencia significativa en el rendimiento en comparación con algo como esto:
Modelo:
<ng-template *ngIf="userCheck()">
...
</ng-template>
Mecanografiado:
userCheck(): boolean {
return this.user && this.user.name && this.isAuthorized;
}
Entonces, para resumir la pregunta, ¿la última opción tendría algún costo de rendimiento significativo?
Preferiríamos usar el segundo enfoque, en situaciones donde necesitamos verificar más de 2 condiciones, pero muchos artículos en línea dicen que las llamadas a funciones SIEMPRE son malas en las plantillas, pero ¿es realmente un problema en este caso?
fuente
Respuestas:
También intenté evitar las llamadas a funciones en las plantillas tanto como sea posible, pero su pregunta me inspiró a hacer una investigación rápida:
Agregué otro caso con
userCheck()
resultados de almacenamiento en cachéPreparó una demostración aquí: https://stackblitz.com/edit/angular-9qgsm9
Sorprendentemente parece que no hay diferencia entre
Y
Y
Parece que es válido para una simple comprobación de propiedades, pero definitivamente habrá una diferencia si se trata de alguna
async
acciones, por ejemplo, captadores que esperan alguna API.fuente
Esta es una respuesta bastante obstinada.
El uso de funciones como esta es perfectamente aceptable. Hará que las plantillas sean mucho más claras y no causará una sobrecarga significativa. Como JB dijo antes, también establecerá una base mucho mejor para las pruebas unitarias.
También creo que cualquier expresión que tenga en su plantilla será evaluada como una función por el mecanismo de detección de cambios, por lo que no importa si la tiene en su plantilla o en la lógica de sus componentes.
Simplemente mantenga la lógica dentro de la función al mínimo. Si no está sin embargo cautelosos acerca de cualquier función de un tal impacto en el rendimiento podría tener, yo recomiendo que usted ponga su
ChangeDetectionStrategy
aOnPush
, que se considera la mejor práctica de todos modos. Con esto, la función no se llamará en cada ciclo, solo cuando unInput
cambio, algún evento ocurra dentro de la plantilla, etc.(usando etc, porque ya no sé la otra razón) .
Personalmente, nuevamente, creo que es aún mejor usar el patrón Observables, luego puedes usar la
async
tubería, y solo cuando se emite un nuevo valor, la plantilla se vuelve a evaluar:Luego puede usar en la plantilla de esta manera:
Otra opción sería usar
ngOnChanges
, si todas las variables dependientes del componente son entradas, y tiene mucha lógica para calcular una determinada variable de plantilla (que no es el caso que mostró):Que puedes usar en tu plantilla de esta manera:
fuente
Observable
secuencia, lo que lo convertirá en un candidato perfecto para la segunda opción que mostré. De cualquier manera, me alegro de poder darte algunas ideasNo se recomienda por muchas razones el principal:
Para determinar si userCheck () necesita ser re-renderizado, Angular necesita ejecutar la expresión userCheck () para verificar si su valor de retorno ha cambiado.
Debido a que Angular no puede predecir si el valor de retorno de userCheck () ha cambiado, necesita ejecutar la función cada vez que se ejecuta la detección de cambio.
Entonces, si la detección de cambios se ejecuta 300 veces, la función se llama 300 veces, incluso si su valor de retorno nunca cambia.
Explicación extendida y más problemas https://medium.com/showpad-engineering/why-you-should-never-use-function-calls-in-angular-template-expressions-e1a50f9c0496
El problema viene cuando si su componente es grande y asiste a muchos eventos de cambio, si su componente será pequeño y solo asiste a algunos eventos, no debería ser un problema.
Ejemplo con observables
Luego puede usarlo observable con una tubería asíncrona en su código.
fuente
Creo que JavaScript se creó con un objetivo para que un desarrollador no note la diferencia entre una expresión y una llamada de función con respecto al rendimiento.
En C ++ hay una palabra clave
inline
para marcar una función. Por ejemplo:Esto se hizo para eliminar una llamada de función. Como resultado, el compilador reemplaza todas las llamadas de
userCheck
con el cuerpo de la función. ¿Motivo para innovarinline
? Un aumento de rendimiento.Por lo tanto, creo que el tiempo de ejecución de una llamada de función con una expresión, probablemente, es más lento que la ejecución de la expresión solamente. Pero, también creo que no notarás una diferencia en el rendimiento si solo tienes una expresión en la función.
fuente