Maaf jika ini sudah dijawab di sini, tetapi saya tidak dapat menemukan kecocokan untuk skenario khusus kami, jadi begini!
Kami telah berdiskusi di tim pengembangan kami, tentang pemanggilan fungsi dalam templat sudut. Sekarang sebagai aturan umum, kami setuju bahwa Anda tidak boleh melakukan ini. Namun, kami sudah mencoba mendiskusikan kapan itu boleh saja. Biarkan saya memberi Anda sebuah skenario.
Katakanlah kita memiliki blok template yang dibungkus dengan ngIf, yang memeriksa beberapa parameter, seperti di sini:
<ng-template *ngIf="user && user.name && isAuthorized">
...
</ng-template>
Apakah akan ada perbedaan kinerja yang signifikan dibandingkan dengan yang seperti ini:
Templat:
<ng-template *ngIf="userCheck()">
...
</ng-template>
Naskah:
userCheck(): boolean {
return this.user && this.user.name && this.isAuthorized;
}
Jadi, untuk meringkas pertanyaan, apakah opsi terakhir memiliki biaya kinerja yang signifikan?
Kami lebih suka menggunakan pendekatan ke-2, dalam situasi di mana kami perlu memeriksa lebih dari 2 kondisi, tetapi banyak artikel online mengatakan panggilan fungsi SELALU buruk dalam templat, tetapi apakah ini benar-benar masalah dalam kasus ini?
sumber
Jawaban:
Saya juga mencoba untuk menghindari panggilan fungsi dalam template sebanyak mungkin, tetapi pertanyaan Anda menginspirasi saya untuk melakukan riset cepat:
Saya menambahkan kasus lain dengan
userCheck()
hasil cachingMempersiapkan demo di sini: https://stackblitz.com/edit/angular-9qgsm9
Anehnya sepertinya tidak ada perbedaan di antara keduanya
Dan
Dan
Sepertinya ini valid untuk pemeriksaan properti sederhana, tetapi pasti akan ada perbedaan jika menyangkut
async
tindakan apa pun , getter yang sedang menunggu api misalnya.sumber
Ini adalah jawaban yang cukup keras.
Penggunaan fungsi seperti ini, sangat bisa diterima. Ini akan membuat templat lebih jelas, dan tidak menyebabkan overhead yang signifikan. Seperti JB katakan sebelumnya, itu akan menetapkan basis yang jauh lebih baik untuk pengujian unit juga.
Saya juga berpikir bahwa ekspresi apa pun yang Anda miliki di template Anda, akan dievaluasi sebagai fungsi oleh mekanisme deteksi perubahan, jadi tidak masalah jika Anda memilikinya di template Anda atau di komponen logika Anda.
Biarkan logika di dalam fungsi tetap minimum. Jika Anda namun waspada tentang dampak kinerja fungsi tersebut mungkin memiliki, saya sangat menyarankan Anda untuk menempatkan Anda
ChangeDetectionStrategy
keOnPush
, yang dianggap praktek terbaik lagian. Dengan ini, fungsi tidak akan dipanggil setiap siklus, hanya ketika adaInput
perubahan, beberapa peristiwa terjadi di dalam template, dll.(menggunakan dll, karena saya tidak tahu alasan lain lagi) .
Secara pribadi, sekali lagi, saya pikir itu lebih baik untuk menggunakan pola yang dapat diobservasi, Anda kemudian dapat menggunakan
async
pipa, dan hanya ketika nilai baru dipancarkan, template akan dievaluasi kembali:Anda kemudian dapat menggunakan dalam template seperti ini:
Namun pilihan lain adalah menggunakan
ngOnChanges
, jika semua variabel dependen ke komponen adalah Input, dan Anda memiliki banyak logika yang terjadi untuk menghitung variabel templat tertentu (yang bukan kasus yang Anda tunjukkan):Yang dapat Anda gunakan dalam template Anda seperti ini:
sumber
Observable
aliran, yang akan membuatnya menjadi kandidat yang sempurna untuk opsi ke-2 yang saya tunjukkan. Either way, senang saya bisa memberi Anda beberapa wawasanTidak direkomendasikan karena berbagai alasan kepala sekolah:
Untuk menentukan apakah userCheck () perlu dirender ulang, Angular perlu mengeksekusi ekspresi userCheck () untuk memeriksa apakah nilai pengembaliannya telah berubah.
Karena Angular tidak dapat memprediksi apakah nilai pengembalian userCheck () telah berubah, ia perlu menjalankan fungsi setiap kali deteksi perubahan berjalan.
Jadi jika deteksi perubahan berjalan 300 kali, fungsinya disebut 300 kali, bahkan jika nilai baliknya tidak pernah berubah.
Penjelasan lebih lanjut dan lebih banyak masalah https://medium.com/showpad-engineering/why-you-should-never-use-function-calls-in-angular-template-expressions-e1a50f9c0496
Masalahnya muncul ketika jika komponen Anda besar dan menghadiri banyak acara perubahan, jika komponen Anda akan menyala dan hanya menghadiri beberapa acara seharusnya tidak menjadi masalah.
Contoh dengan diamati
Kemudian Anda dapat menggunakannya dengan pipa async yang dapat diamati dalam kode Anda.
sumber
Saya pikir JavaScript dibuat dengan tujuan agar pengembang tidak melihat perbedaan antara ekspresi dan panggilan fungsi terkait kinerja.
Di C ++ ada kata kunci
inline
untuk menandai suatu fungsi. Sebagai contoh:Ini dilakukan untuk menghilangkan panggilan fungsi. Akibatnya, kompiler menggantikan semua panggilan
userCheck
dengan isi fungsi. Alasan untuk berinovasiinline
? Peningkatan kinerja.Oleh karena itu, saya berpikir bahwa waktu eksekusi pemanggilan fungsi dengan satu ekspresi, mungkin, lebih lambat daripada eksekusi dari ekspresi saja. Tapi, saya juga berpikir Anda tidak akan melihat perbedaan dalam kinerja jika Anda hanya memiliki satu ekspresi dalam fungsinya.
sumber