Kaedah diff React boleh digunakan untuk mencari perbezaan antara dua objek, dengan matlamat untuk menggunakan semula nod seberapa banyak yang mungkin; ke dalam Proses manipulasi minimum pokok DOM Sebenar.
Persekitaran pengendalian tutorial ini: Sistem Windows 10, bertindak balas versi 18.0.0, komputer Dell G3.
Apakah kaedah tindak balas diff?
1. Peranan algoritma Diff
Menghasilkan DOM sebenar adalah sangat mahal Kadangkala kami mengubah suai data tertentu dan menjadikannya terus kepada DOM sebenar . Akan menyebabkan keseluruhan pokok DOM dilukis semula dan disusun semula. Kami berharap untuk mengemas kini bahagian kecil DOM yang kami ubah suai, bukan keseluruhan DOM Algoritma diff membantu kami mencapai ini.
Intipati algoritma perbezaan adalah untuk mencari perbezaan antara dua objek, dengan tujuan menggunakan semula nod sebanyak mungkin.
Nota: Objek yang disebut di sini sebenarnya merujuk kepada dom maya (pokok dom maya) dalam vue, iaitu, menggunakan objek js untuk mewakili struktur dom dalam halaman.
minimum Proses operasi dipanggil perdamaian. 2.
penyelarasan . 3 strategi berbeza
3) kerumitan menjadi O(n) kerumitan >Strategi 1 (
perbezaan pokok): Terdapat sangat sedikit operasi pergerakan merentas peringkat nod DOM dalam UI Web dan boleh diabaikan. (2) Strategi 2 (perbezaan komponen): Dua komponen dengan kelas yang sama menjana struktur pokok yang serupa, Dua komponen dengan kelas yang berbeza Menghasilkan struktur pokok yang berbeza . (3) Strategi tiga (perbezaan elemen): Untuk sekumpulan nod anak pada tahap yang sama, dibezakan oleh id unik. (1) React menggunakan updateDepth untuk melaksanakan kawalan tahap . (2) Membandingkan pokok secara hierarki, kedua-dua pokok hanya membandingkan Nod pada tahap yang sama dibandingkan. Jika nod tidak wujud, nod dan nod anaknya akan dipadamkan sepenuhnya dan tidak akan dibandingkan lagi. (3) Hanya satu lintasan diperlukan untuk melengkapkan perbandingan keseluruhan pokok DOM. Apakah yang akan dilakukan Diff jika terdapat operasi merentas peringkat pada nod DOM? Jawapan: Tree DIFF merentasi setiap lapisan pokok Jika komponen tidak lagi wujud, ia akan dimusnahkan secara langsung. Seperti yang ditunjukkan dalam rajah, bahagian kiri ialah atribut lama dan bahagian kanan ialah atribut baru Lapisan pertama ialah komponen R, yang betul-betul sama dan tidak akan berubah Lapisan kedua memasuki Component DIFF dan jenis yang sama daripada komponen terus dibandingkan. Didapati bahawa komponen A tidak wujud, jadi secara langsung Padam komponen A, B, dan C teruskan ke lapisan ketiga dan buat semula komponen A, B, dan C. Seperti yang ditunjukkan dalam gambar di atas, keseluruhan pokok dengan A sebagai nod akar akan dicipta semula dan bukannya dipindahkan, jadi secara rasmi disyorkan tidak untuk melaksanakan Nod DOM beroperasi merentas peringkat, dan nod boleh disembunyikan dan dipaparkan melalui CSS dan bukannya mengalih keluar atau menambah nod DOM. React mempunyai tiga strategi untuk membandingkan komponen yang berbeza (1) Jenis yang sama Untuk kedua-dua komponen , teruskan sahaja membandingkan pokok DOM Maya mengikut strategi asal (perbandingan hierarki). (2) Untuk dua komponen daripada jenis yang sama, apabila komponen A bertukar kepada komponen B, DOM Maya mungkin tidak berubah sama sekali Jika anda tahu perkara ini (DOM Maya tidak berubah semasa proses transformasi), Ia boleh menjimatkan banyak masa pengiraan, jadi pengguna boleh menggunakan shouldComponentUpdate() untuk menilai sama ada pengiraan penghakiman diperlukan. (3) Jenis komponen yang berbeza, menilai komponen (yang akan ditukar) sebagai komponen yang kotor, dengan itu menggantikan semua nod keseluruhan komponen . Nota: Seperti yang ditunjukkan dalam rajah di atas, Apabila komponen D menjadi komponen G, walaupun kedua-dua komponen mempunyai struktur yang serupa, Apabila nod berada pada tahap yang sama, diff menyediakan tiga operasi nod: Padam, selitkan, gerakkan . Sisipkan: Komponen C tiada dalam set (A, B) dan perlu dimasukkan Padam: (1) Komponen D ialah dalam set (A, B, D), tetapi nod D telah berubah dan tidak boleh digunakan semula dan dikemas kini, jadi D lama perlu dipadamkan dan yang baharu perlu dibuat. (2) Komponen D sebelum ini berada dalam set (A, B, D), tetapi set itu menjadi set baharu (A, B), D Ia perlu dipadamkan. Alih: Komponen D sudah ada dalam koleksi ( A, B, C, D), dan apabila set dikemas kini, D tidak dikemas kini, tetapi kedudukannya berubah Contohnya, dalam set baru (A, D, B, C), D berada dalam set kedua . Tidak perlu menjadi seperti perbezaan tradisional Mari Bandingkan B kedua set lama dengan D kedua set baru, padamkan B pada kedudukan kedua, masukkan D pada kedudukan kedua, dan tambah kunci unik. (untuk kumpulan nod anak yang sama pada tahap yang sama) Untuk membezakan, cuma gerakkan. Gerak situasi 1: Cara mengalihkan nod (1) B tidak bergerak, tiada butiran lanjut, kemas kini l astIndex=1 (2) Koleksi baharu memperoleh E dan mendapati koleksi lama tidak wujud, jadi ia mencipta E pada kedudukan lastIndex=1 dan mengemas kini lastIndex=1 (3) Set baru mendapat C, C tidak bergerak, kemas kini lastIndex=2 (4) Set baharu mendapat pergerakan A, A, sama seperti di atas, kemas kini lastIndex=2 (5) Selepas membandingkan set baharu, lalui set lama. Ia dinilai bahawa set baru tidak mempunyai elemen, tetapi set lama mempunyai elemen (seperti D, set baru tidak mempunyainya, tetapi set lama mempunyainya), D ditemui, D dipadam, dan perbezaan operasi tamat. Kod untuk pelaksanaan algoritma Diff dalam React: berdasarkan perbezaan pokok: Berdasarkan perbezaan komponen: Berdasarkan perbezaan elemen: Pembelajaran yang disyorkan: "tutorial video bertindak balas"
4 perbezaan pokok:
5. Perbezaan komponen:
一旦React判断D和G是不用类型的组件,就不会比较两者的结构,而是直接删除组件D,重新创建组件G及其子节点。
Walaupun apabila kedua-dua komponen itu berbeza jenis tetapi mempunyai struktur yang serupa, algoritma diff dilakukan Analisis akan menjejaskan prestasi, tetapi lagipun, jarang sekali jenis komponen yang berbeza mempunyai pokok DOM yang serupa dalam proses pembangunan sebenar, jadi sukar bagi faktor ekstrem ini untuk memberi kesan besar dalam proses pembangunan sebenar .
6 perbezaan elemen
_updateChildren: function(nextNestedChildrenElements, transaction, context) {
var prevChildren = this._renderedChildren;
var removedNodes = {};
var mountImages = [];
// 获取新的子元素数组
var nextChildren = this._reconcilerUpdateChildren(
prevChildren,
nextNestedChildrenElements,
mountImages,
removedNodes,
transaction,
context
);
if (!nextChildren && !prevChildren) {
return;
}
var updates = null;
var name;
var nextIndex = 0;
var lastIndex = 0;
var nextMountIndex = 0;
var lastPlacedNode = null;
for (name in nextChildren) {
if (!nextChildren.hasOwnProperty(name)) {
continue;
}
var prevChild = prevChildren && prevChildren[name];
var nextChild = nextChildren[name];
if (prevChild === nextChild) {
// 同一个引用,说明是使用的同一个component,所以我们需要做移动的操作
// 移动已有的子节点
// NOTICE:这里根据nextIndex, lastIndex决定是否移动
updates = enqueue(
updates,
this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex)
);
// 更新lastIndex
lastIndex = Math.max(prevChild._mountIndex, lastIndex);
// 更新component的.mountIndex属性
prevChild._mountIndex = nextIndex;
} else {
if (prevChild) {
// 更新lastIndex
lastIndex = Math.max(prevChild._mountIndex, lastIndex);
}
// 添加新的子节点在指定的位置上
updates = enqueue(
updates,
this._mountChildAtIndex(
nextChild,
mountImages[nextMountIndex],
lastPlacedNode,
nextIndex,
transaction,
context
)
);
nextMountIndex++;
}
// 更新nextIndex
nextIndex++;
lastPlacedNode = ReactReconciler.getHostNode(nextChild);
}
// 移除掉不存在的旧子节点,和旧子节点和新子节点不同的旧子节点
for (name in removedNodes) {
if (removedNodes.hasOwnProperty(name)) {
updates = enqueue(
updates,
this._unmountChild(prevChildren[name], removedNodes[name])
);
}
}
}
3. Pembangunan berdasarkan Diff Adalah disyorkan bahawa
Atas ialah kandungan terperinci Apakah kaedah diff tindak balas?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!