Pengalaman terbaik dalam membuat aplikasi Sudut yang bersih dan cepat

Untuk menulis artikel ini, mereka didorong oleh pencarian untuk pengembang front-end JavaScript di perusahaan mereka di Stavropol. Karena Untuk waktu yang lama tidak mungkin menemukan programmer yang cerdas, dan kemudian kami memutuskan untuk meluncurkan program magang dengan banyak materi pelatihan tentang Angular & JS.

Ini adalah terjemahan dari artikel Vamsi Vempati tentang pengalamannya dengan aplikasi berskala besar untuk Trade Me yang ditulis dalam Angular.



Sampai saat ini, saya sudah bekerja beberapa tahun pada aplikasi Angular skala besar di Trade Me. Selama beberapa tahun terakhir, tim kami telah menyempurnakan aplikasi kami dalam hal standar penulisan kode dan kinerja untuk membawanya ke keadaan terbaik.

Artikel ini menguraikan metode yang kami gunakan dalam proyek kami. Teks sebagian besar dikaitkan dengan Angular, TypeScript, RxJs dan @ ngrx / store.

Selain itu, beberapa pedoman umum untuk menulis kode yang akan membantu membuat aplikasi lebih "bersih" dan dapat dibaca akan dipertimbangkan.

1) trackBy


Saat menggunakan ngFor untuk mengulang array di templat, lihat fungsi trackBy , yang akan mengembalikan pengidentifikasi unik untuk setiap elemen.

Mengapa


Ketika array berubah, Angular menggambar ulang pohon DOM sepenuhnya. Tetapi jika Anda menggunakan fungsi trackBy , Angular akan memahami elemen mana yang telah berubah, dan kemudian akan membuat perubahan pada DOM hanya untuk elemen tertentu itu.

Catatan: deskripsi yang lebih rinci dapat ditemukan dalam artikel oleh Nathanel Bazal. [eng]

Untuk


 <li *ngFor="let item of items;">{{ item }}</li> 


Setelah


 //   <li *ngFor="let item of items; trackBy: trackByFn">{{ item }}</li> //   trackByFn(index, item) { return item.id; // unique id corresponding to the item } 

2) const atau biarkan?


Saat mendeklarasikan variabel, gunakan const jika mereka tidak akan dipindahkan.

Mengapa


Penggunaan let dan const jika perlu membuat alasan untuk mendeklarasikan variabel lebih dapat dimengerti. Ini juga dapat membantu mengidentifikasi masalah di mana nilai dipindahkan secara acak ke konstanta karena kesalahan waktu kompilasi. Ini juga meningkatkan keterbacaan kode.

Untuk


 let car = 'ludicrous car'; let myCar = `My ${car}`; let yourCar = `Your ${car}`; if (iHaveMoreThanOneCar) { myCar = `${myCar}s`; } if (youHaveMoreThanOneCar) { yourCar = `${youCar}s`; } 

Setelah


 //  car  ,      (const) const car = 'ludicrous car'; let myCar = `My ${car}`; let yourCar = `Your ${car}`; if (iHaveMoreThanOneCar) { myCar = `${myCar}s`; } if (youHaveMoreThanOneCar) { yourCar = `${youCar}s`; } 

3) Operator seperti pipa


Gunakan pernyataan seperti pipa saat bekerja dengan RxJs .
Operator mirip pipa hanya menyertakan kode yang perlu dijalankan saat mengimpor.

Ini juga membuatnya lebih mudah untuk menemukan pernyataan yang tidak digunakan dalam file.

Catatan: Diperlukan sudut 5,5 ke atas.

Untuk


 import 'rxjs/add/operator/map'; import 'rxjs/add/operator/take'; iAmAnObservable .map(value => value.item) .take(1); 

Setelah


 import { map, take } from 'rxjs/operators'; iAmAnObservable .pipe( map(value => value.item), take(1) ); 

4) Masuk ke template


Hindari berlangganan objek yang dipantau dari komponen - alih-alih, berlangganan objek tersebut dari templat.

Mengapa


async feeds secara otomatis berhenti berlangganan, menyederhanakan kode dan menghilangkan kebutuhan untuk manajemen berlangganan manual. Risiko berhenti berlangganan yang tidak disengaja dalam suatu komponen juga berkurang, yang akan menyebabkan kebocoran memori. Ini dapat diperbaiki dengan menggunakan aturan serat untuk mendeteksi objek yang diamati tanpa tanda tangan.

Selain itu, tidak memungkinkan komponen tetap statis dan menambah kesalahan saat data berubah di luar langganan.

Untuk


 //  <p>{{ textToDisplay }}</p> //  iAmAnObservable .pipe( map(value => value.item), takeUntil(this._destroyed$) ) .subscribe(item => this.textToDisplay = item); 

Setelah


 //  <p>{{ textToDisplay$ | async }}</p> //  this.textToDisplay$ = iAmAnObservable .pipe( map(value => value.item) ); 

5) Hapus Berlangganan


Saat berlangganan objek yang dipantau, selalu pastikan bahwa Anda kemudian berhenti berlangganan dari mereka dengan menggunakan operator seperti take , takeUntil , dll.

Mengapa


Kesalahan dari berhenti berlangganan dari objek yang diamati akan menyebabkan kebocoran memori yang tidak diinginkan, karena aliran yang diamati tetap terbuka, mungkin bahkan setelah komponen dihapus atau ketika pengguna pindah ke halaman lain.

Selain itu, buat aturan lint untuk mendeteksi objek yang dapat diobservasi dari mana tidak ada berhenti berlangganan.

Untuk


 iAmAnObservable .pipe( map(value => value.item) ) .subscribe(item => this.textToDisplay = item); 


Setelah


 private _destroyed$ = new Subject(); public ngOnInit (): void { iAmAnObservable .pipe( map(value => value.item) //     iAmAnObservable   ,     / takeUntil(this._destroyed$) ) .subscribe(item => this.textToDisplay = item); } public ngOnDestroy (): void { this._destroyed$.next(); this._destroyed$.complete(); } 

Menggunakan takeUntil untuk mendengarkan perubahan sampai objek lain yang diamati mengembalikan nilai:

 iAmAnObservable .pipe( map(value => value.item), take(1), takeUntil(this._destroyed$) ) .subscribe(item => this.textToDisplay = item); 

Perhatikan penggunaan takeUntil dan take dalam contoh di atas. Ini menghindari kebocoran memori yang disebabkan oleh fakta bahwa tidak ada nilai yang ditetapkan untuk berlangganan sebelum komponen dihapus.

Tanpa takeUntil langganan akan tetap dalam status ditangguhkan, sampai ia menerima nilai pertama, tetapi karena komponen telah dihapus, ia tidak akan pernah menerima nilainya, dan ini akan menyebabkan kebocoran memori.

6) Memuat malas


Jika memungkinkan, coba muat modul dalam aplikasi Angular hanya saat sedang digunakan.

Mengapa


Ini akan mengurangi ukuran aplikasi yang diunduh dan mempersingkat waktu pemuatannya.

Untuk


 // app.routing.ts { path: 'not-lazy-loaded', component: NotLazyLoadedComponent } 

Setelah


 // app.routing.ts { path: 'lazy-load', loadChildren: 'lazy-load.module#LazyLoadModule' } // lazy-load.module.ts import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router'; import { LazyLoadComponent } from './lazy-load.component'; @NgModule({ imports: [ CommonModule, RouterModule.forChild([ { path: '', component: LazyLoadComponent } ]) ], declarations: [ LazyLoadComponent ] }) export class LazyModule {} 

Terjemahan lanjutan di artikel selanjutnya. Jika ada yang tidak mau menunggu, maka di sini ada tautan ke artikel aslinya.

Source: https://habr.com/ru/post/id447042/


All Articles