Nội dung bài viết không có gì mới, các hướng dẫn được tổng hợp từ nhiều nguồn (Xem cuối bài)

1) Bật chế độ Production

Các bước để bật chế độ production (đối với angular-cli) bao gồm:
1) Trong main.ts gọi hàm enableProdMode(). Nếu như bạn generate dự án bằng angular-cli thì việc này đã được tích hợp sẵn.
2) Trong terminal, bạn nhớ dùng --prod như sau: ng build --prod
3) kiểm tra file environment.prod.ts, và chắc rằng property production đã được đặt là true trong object environment.

Khi bật chế độ Production, các công việc như sau sẽ được thực hiện:

- Vô hiệu hóa các kiểm tra so sánh (assertion) và các thể loại kiểm tra khác bên trong framework của angular.
- Code sẽ được "làm xấu" (ugligy) và nén lại (minify), khó đọc hơn, khó debug hơn.
- Ứng dụng chạy nhanh hơn (chắc rồi).

2) Bật Ahead-of-Time Compilation

Angular có 2 chế độ compile, là AoT và JIT. AoT thì nhanh hơn (xem bảng so sánh bên dưới). Để bật AoT trong terminal, nhớ bật cờ --aot như sau: ng build --aot

JIT: trình tự làm việc

- Tất cả các typescript sẽ được biên dịch sang javascript.
- Trình duyệt tải tất cả các assets (js, css, images...).
- Angular khởi tạo ứng dụng (bootstrap).
- Mỗi component sẽ generate javascript và template trên trình duyệt.
- Render.

AoT: trình tự làm việc

- Tất cả các angular template được biên dịch sang typescript bằng angular compiler, sau đó tất cả typescript được compile sang javascript.
- Trình duyệt tải tất cả assets.
- Angular khởi tạo ứng dụng.
- Render.
Như vậy, quá trình build của AoT chắc chắn sẽ lâu hơn, nhưng render lại nhanh hơn vì tất cả đã được biên dịch sẵn và chỉ chờ để đưa lên.

3) Life Cycle Hooks

Angular có các Life Cycle Hooks sau đây:
ngOnChanges()
ngOnInit()
ngDoCheck()
ngAfterContentInit()
ngAfterContentCheck()
ngAfterViewInit()
ngAfterViewCheck()
ngOnDestroy()
(Bài viết sẽ tập trung ở một số hook quan trọng, các hook khác bạn có thể tham khảo tại link bên trên)

3.1) ngOnChanges()

Hook ngOnChanges chạy khi bạn đặt/thay đổi giá trị cho các property đầu vào (@Input property). Hàm ngOnChanges nhận một tham số duy nhất là object có kiểu SimpleChanges, trong đó, mỗi một property phản ánh 1 @Input với giá trị trước lúc thay đổi và giá trị hiện tại. Hook này được gọi đầu tiên, trước hook ngOnInit và mỗi khi @Input property có thay đổi giá trị.
Vì đôi lúc object SimpleChanges có rất nhiều property trong đó để phản ánh sự thay đổi của các @Input property, cho nên để kiểm tra riêng biệt một @Input nào đó có thay đổi hay không, tránh thực thi các tác vụ không liên quan, bạn nên kiểm tra như sau:
ngOnChanges(changes: SimpleChanges) {
    if (changes.student) {
        // your logic here…
    }
}
Hoặc bạn cũng có thể dùng setter cho @Input nếu bạn không muốn kiểm tra trong ngOnChanges như sau:
private _student: StudentModel;
@Input() set student(value) {
    // your code will run everytime
    // incoming value for this input
    // update from the parent component
}

3.2) ngOnInit()

Khởi tạo các directive/component sau khi hiển thị lần đầu các dữ liệu được bind vào component. hàm ngOnInit chỉ chạy một lần duy nhất, sau lần gọi đầu tiên của hook ngOnChange.

3.3) ngDoCheck()

Hook này chạy mỗi khi Change Detection của Angular đi kiểm tra các component. Chúng ta chỉ sử dụng hàm này để tự viết lấy các logic kiểm tra sự khác biệt của các property, khi Angular không thể tự làm lấy việc kiểm tra so sánh (vd như object có cấu trúc phức tạp nhưng thay đổi cực nhỏ và bạn phải tự kiểm tra lấy...). Hàm ngDoCheck được gọi ngay lập tức sau ngOnChanges và sau ngOnInit, và cứ mỗi lần Change Detection chạy thì hàm này được gọi.

4) Change Detection

Change Detection là cơ chế của Angular để kiểm tra sự thay đổi giá trị các property của các component.
Mỗi khi có một event nào đó xảy ra (vd khi user click một button nào đó), Change Detection được gọi lên chạy.
Change Detection sẽ chạy trên toàn bộ cây Component của ứng dụng. Mỗi khi chạy, Change Detection sẽ gọi 2 hook: ngOnChangesngDoCheck.
Change Detection là một cơ chế tương đối nặng nề trong toàn bộ ứng dụng, nên để giảm tải cho Change Detection có một vài cách thức như sau:
- Thay đổi chiến thuật: ChangeDetectionStrategy.OnPush
- Tắt ChangeDetection trên component.

4.1) ChangeDetectionStrategy.OnPush

@Component({
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponent {
}
Bằng cách này, component chỉ chạy Change Detection khi và chỉ khi các @Input property có sự thay đổi.
Chúng ta sử dụng cách này nếu:
- Các @Input property là immutable (không thể thay đổi từ bên trong component).
- Bạn muốn xây dựng một pure-component (chỉ để view mà không có thực thi tác vụ hay tính toán gì cả)

4.2) Tắt Change Detection

export class MyComponent {
    constructor(private cdr: ChangeDetectionRef) {
    }
    onAfterViewInit() {
        this.cdr.detach();
    }
}
Thực tế đây không phải là tắt, mà chính là "kéo" component ra khỏi cơ chế Change Detection. Khi thực hiện việc này, Change Detection sẽ bỏ qua component của bạn, cho đến khi bạn muốn thực hiện Change Detection ở thời điểm mà bạn muốn, hoặc cho tới khi bạn muốn đưa component trở lại cơ chế Change Detection bình thường.
- Đầu tiên chúng ta reference tới service ChangeDetectionRef của angular trong constructor của Component.
- Trong hook onAfterViewInit() chúng ta gọi hàm detach().
Ngoài ra service này còn cung cấp cho chúng ta các hàm khác:
- markForCheck(): Gọi Change Detection kiểm tra trên toàn bộ application.
- detectChanges(): Gọi Change Detection kiểm tra trên component.
- reattach(): Đưa component quay trở lại Change Detection của toàn ứng dụng.

5) Chạy ngoài Angular với ngZone

constructor(private zone: NgZone) {
    this.zone.runOutsideAngular(() => {
        // your code
    });
}
Những thay đổi giá trị property được viết trong scope của hàm runOutsideAngular() sẽ không gọi DetectionChange lên. Chỉ cần lưu ý là nếu bạn biết rõ bạn đang làm gì thì bạn có thể áp dụng cách này.

6) *ngFor và trackBy

Khi bạn KHÔNG sử dụng trackBy cho ngFor, thì tất cả các item bên trong ngFor sẽ render lại khi dữ liệu dùng cho ngFor có thay đổi. Nếu bạn có quá nhiều item để in ra màn hình dùng ngFor, bạn nên dùng trackBy để hạn chế việc render lại toàn bộ DOM.
Khi sử dụng trackBy, ngFor sẽ dùng định danh của mỗi item bên trong danh sách để kiểm tra, xem DOM nào cần render lại hay không, do đó, nếu toàn bộ danh sách có cập nhật lại nhưng chỉ có một số item trong đó thực sự thay đổi thì mới in lại DOM, nhưng chỉ những DOM nào cần thiết mà thôi.

7) Viết callback nhỏ gọn, thực thi nhanh

Giả sự bạn cần viết một callback cho sự kiện click. Bạn nên viết callback cho nó thật ngắn gọn, súc tính, và chỉ làm những việc cần làm. Những thứ không liên quan đến thì không nên viết vào trong callback.
Sự kiện click khi được gọi, sẽ block toàn bộ component để chạy Change Detection. (Change Detection sẽ chạy ngược từ component con lên đến root để kiểm tra sau đó thực hiện thay đổi trên màn hình từ root đến các component con). Do đó, callback quá phức tạp thì sẽ làm cho quá trình này diễn ra lâu hơn.
Ngoài ra, việc giảm số lần gọi callback cũng giúp tăng tốc độ. Bạn có thể tham khảo debouncing trong bài viết này (mục 5.0 Reducing the quantity of call back executions needed):

8) Data Binding

Đây là một ví dụ tốt về data binding:
Hello {{title}} {{fullName}}
Tuy nhiên trong trường hợp dưới đây lại không tốt lắm:
Hello {{getTitle()}} {{fullName}}
Lý do là hàm getTitle() sẽ được gọi 2 lần chỉ để in ra title của object student. (Do Change Detection chạy). Nếu hàm getTitle() này làm thêm một số tác vụ phụ nữa thì sẽ mất thêm thời gian mới in ra được title của object student.
Do vậy, cách tốt nhất, khi bind dữ liệu ra, chúng ta nên chuẩn bị dữ liệu đầy đủ, parse / transform dữ liệu hoàn chỉnh, và chỉ cần bind trực tiếp các property của object đó ra trực tiếp trên view, thay vì phải dùng các hàm như getTitle().

9) Các nguồn tham khảo cho bài viết