Deteksi Perubahan Sudut dan Strategi OnPush
Diterbitkan: 2022-03-11Anda telah mulai menggunakan Angular untuk semua proyek favorit Anda. Anda tahu apa yang ditawarkan Angular, dan bagaimana Anda dapat memanfaatkannya untuk membangun aplikasi web yang luar biasa. Namun, ada hal-hal tertentu tentang Angular, dan mengetahuinya dapat membuat Anda lebih baik dalam menggunakan Angular untuk proyek Anda.
Aliran data menjadi pusat dari hampir semua hal Angular, deteksi perubahan adalah sesuatu yang perlu diketahui, karena ini akan membantu Anda melacak bug dengan lebih mudah dan memberi Anda kesempatan untuk lebih mengoptimalkan aplikasi saat bekerja dengan kumpulan data yang kompleks.
Dalam artikel ini, Anda akan mempelajari bagaimana Angular mendeteksi perubahan dalam struktur datanya dan bagaimana Anda dapat membuatnya tidak berubah untuk memanfaatkan strategi deteksi perubahan Angular secara maksimal.
Ubah Deteksi di Angular
Saat Anda mengubah salah satu model Anda, Angular mendeteksi perubahan dan segera memperbarui tampilan. Ini adalah deteksi perubahan di Angular. Tujuan dari mekanisme ini adalah untuk memastikan tampilan yang mendasari selalu sinkron dengan model yang sesuai. Fitur inti Angular inilah yang membuat kerangka kerja dan sebagian alasan mengapa Angular adalah pilihan yang tepat untuk mengembangkan aplikasi web modern.
Model di Angular dapat berubah sebagai akibat dari salah satu skenario berikut:
Peristiwa DOM (klik, arahkan kursor, dll.)
permintaan AJAX
Timer (setTimer(), setInterval())
Ubah Detektor
Semua aplikasi Angular terdiri dari pohon hierarki komponen. Saat runtime, Angular membuat kelas pendeteksi perubahan terpisah untuk setiap komponen di pohon, yang kemudian membentuk hierarki pendeteksi perubahan yang serupa dengan hierarki pohon komponen.
Setiap kali deteksi perubahan dipicu, Angular menelusuri pohon detektor perubahan ini untuk menentukan apakah ada di antara mereka yang melaporkan perubahan.
Siklus deteksi perubahan selalu dilakukan satu kali untuk setiap perubahan yang terdeteksi dan dimulai dari detektor perubahan akar dan terus turun secara berurutan. Pilihan desain sekuensial ini bagus karena memperbarui model dengan cara yang dapat diprediksi karena kita tahu bahwa data komponen hanya dapat berasal dari induknya.
Detektor perubahan menyediakan cara untuk melacak status komponen sebelumnya dan saat ini serta strukturnya untuk melaporkan perubahan ke Angular.
Jika Angular mendapatkan laporan dari pendeteksi perubahan, Angular menginstruksikan komponen terkait untuk merender ulang dan memperbarui DOM yang sesuai.
Ubah Strategi Deteksi
Nilai vs. Jenis Referensi
Untuk memahami apa itu strategi deteksi perubahan dan mengapa itu berhasil, pertama-tama kita harus memahami perbedaan antara tipe nilai dan tipe referensi dalam JavaScript. Jika Anda sudah terbiasa dengan cara kerjanya, Anda dapat melewati bagian ini.
Untuk memulai, mari kita tinjau tipe nilai dan tipe referensi serta klasifikasinya.
Jenis Nilai
Boolean
Batal
Tidak terdefinisi
Nomor
Rangkaian
Untuk kesederhanaan, orang dapat membayangkan bahwa tipe ini hanya menyimpan nilainya di memori tumpukan (yang secara teknis tidak benar tetapi cukup untuk artikel ini). Lihat memori tumpukan dan nilainya pada gambar di bawah ini misalnya.
Jenis Referensi
Array
Objek
Fungsi
Jenis ini sedikit lebih rumit karena mereka menyimpan referensi pada memori tumpukan, yang menunjuk ke nilai sebenarnya pada memori tumpukan. Anda dapat melihat bagaimana memori tumpukan dan memori tumpukan bekerja bersama dalam contoh gambar di bawah ini. Kami melihat memori tumpukan mereferensikan nilai sebenarnya dari tipe referensi di memori tumpukan.
Perbedaan penting yang harus dibuat antara tipe nilai dan tipe referensi adalah, untuk membaca nilai tipe nilai, kita hanya perlu menanyakan memori tumpukan, tetapi untuk membaca nilai tipe referensi, kita harus terlebih dahulu kueri memori tumpukan untuk mendapatkan referensi dan kemudian gunakan referensi itu untuk kueri memori tumpukan untuk menemukan nilai tipe referensi.
Strategi Default
Seperti yang kami nyatakan sebelumnya, Angular memonitor perubahan pada model untuk memastikan model menangkap semua perubahan. Ini akan memeriksa perbedaan antara keadaan sebelumnya dan keadaan saat ini dari model aplikasi secara keseluruhan.
Pertanyaan yang diajukan Angular dalam strategi deteksi perubahan default adalah: Apakah ada nilai dalam model yang berubah? Tetapi untuk tipe referensi, kami dapat menerapkan strategi sehingga kami dapat mengajukan pertanyaan yang lebih baik. Di sinilah strategi deteksi perubahan OnPush masuk.

Strategi OnPush
Ide utama di balik strategi OnPush terwujud dari kesadaran bahwa jika kita memperlakukan tipe referensi sebagai objek yang tidak dapat diubah, kita dapat mendeteksi jika suatu nilai telah berubah lebih cepat. Ketika jenis referensi tidak dapat diubah, ini berarti setiap kali diperbarui, referensi pada memori tumpukan harus berubah. Sekarang kita cukup memeriksa: Apakah referensi (dalam tumpukan) dari tipe referensi berubah? Jika ya, baru kemudian periksa semua nilai (di heap). Lihat kembali diagram tumpukan tumpukan sebelumnya jika ini membingungkan.
Strategi OnPush pada dasarnya menanyakan dua pertanyaan, bukan satu. Apakah referensi dari tipe referensi berubah? Jika ya, apakah nilai di memori heap berubah?
Misalnya, asumsikan kita memiliki array yang tidak dapat diubah dengan 30 elemen dan kita ingin tahu apakah ada perubahan. Kita tahu bahwa, agar ada pembaruan pada array yang tidak dapat diubah, referensi (pada tumpukan) itu harus diubah. Ini berarti kita pada awalnya dapat memeriksa untuk melihat apakah referensi ke array berbeda, yang berpotensi menyelamatkan kita dari melakukan 30 pemeriksaan lagi (di heap) untuk menentukan elemen mana yang berbeda. Ini disebut strategi OnPush.
Jadi, Anda mungkin bertanya, apa artinya memperlakukan tipe referensi sebagai tidak dapat diubah? Itu berarti kita tidak pernah menyetel properti dari tipe referensi, melainkan menetapkan kembali nilainya secara bersamaan. Lihat di bawah:
Memperlakukan objek sebagai bisa berubah:
static mutable() { var before = {foo: "bar"}; var current = before; current.foo = "hello"; console.log(before === current); // => true }
Memperlakukan objek sebagai tidak berubah:
static mutable() { var before = {foo: "bar"}; var current = before; current = {foo "hello"}; console.log(before === current); // => false }
Perhatikan bahwa, dalam contoh di atas, kami "memperlakukan" tipe referensi sebagai tidak dapat diubah menurut konvensi, jadi pada akhirnya kami masih bekerja dengan objek yang dapat berubah, tetapi hanya "berpura-pura" bahwa mereka tidak dapat diubah.
Jadi bagaimana Anda menerapkan strategi OnPush untuk sebuah komponen? Yang perlu Anda lakukan adalah menambahkan parameter changeDetection
di anotasi @Component mereka.
import {ChangeDetectionStrategy, Component} from '@angular/core'; @Component({ // ... changeDetection: ChangeDetectionStrategy.OnPush }) export class OnPushComponent { // ... }
tidak berubah.js
Ini adalah ide yang baik untuk menegakkan kekekalan jika seseorang memutuskan untuk menggunakan strategi OnPush pada komponen Angular. Di situlah Immutable.js masuk.
Immutable.js adalah perpustakaan yang dibuat oleh Facebook untuk kekekalan dalam JavaScript. Mereka memiliki banyak struktur data yang tidak dapat diubah, seperti Daftar, Peta, dan Tumpukan. Untuk keperluan artikel ini, Daftar dan Peta akan diilustrasikan. Untuk referensi lebih lanjut, silakan lihat dokumentasi resmi di sini.
Untuk menambahkan Immutable.js ke proyek Anda, pastikan untuk masuk ke terminal Anda dan jalankan:
$ npm install immutable --save
Pastikan juga untuk mengimpor struktur data yang Anda gunakan dari Immutable.js di komponen tempat Anda menggunakannya.
import {Map, List} from 'immutable';
Ini adalah bagaimana Peta Immutable.js dapat digunakan:
var foobar = {foo: "bar"}; var immutableFoobar = Map(foobar); console.log(immutableFooter.get("foo")); // => bar
Dan, Array dapat digunakan:
var helloWorld = ["Hello", "World!"]; var immutableHelloWorld = List(helloWorld); console.log(immutableHelloWorld.first()); // => Hello console.log(immutableHelloWorld.last()); // => World! helloWorld.push("Hello Mars!"); console.log(immutableHelloWorld.last()); // => Hello Mars!
Kekurangan Menggunakan Immutable.js
Ada beberapa kelemahan utama yang dapat diperdebatkan menggunakan Immutable.js.
Seperti yang mungkin Anda perhatikan, menggunakan API-nya agak rumit, dan pengembang JavaScript tradisional mungkin tidak menyukai ini. Masalah yang lebih serius berkaitan dengan tidak dapat mengimplementasikan antarmuka untuk model data Anda karena Immutable.js tidak mendukung antarmuka.
Bungkus
Anda mungkin bertanya mengapa strategi OnPush bukan strategi default untuk Angular. Saya kira itu karena Angular tidak ingin memaksa pengembang JavaScript untuk bekerja dengan objek yang tidak dapat diubah. Tapi, bukan berarti Anda dilarang menggunakannya.
Jika itu adalah sesuatu yang ingin Anda manfaatkan dalam proyek web Anda berikutnya, Anda sekarang tahu betapa mudahnya Angular membuatnya beralih ke strategi deteksi perubahan yang berbeda.