Detailed Explanation of lisf-diff for children Comparison in virtual-dom

Keywords: Javascript github Vue React Mobile

Visit this article if you are not clear about virtual-dom

Source code of list-diff

Preface:

Within a vue or react, each VNode has a unique key to identify, which is usually handled automatically by the framework, but must be specified by the developer within the loop. So the following interpretation is that I use this key to represent the object in the list.

We do not really need to achieve the minimum operation, we only need to optimize some of the more common mobile situations, sacrificing a certain DOM operation, so that the time complexity of the algorithm is linear (O(max(M, N)).

Method entry

let diff = (oldList, newList) => {
    let moves = [];
    // Logic processing
    return moves;
}

As you can see from the above, the diff function returns the steps of converting an old array into a new one.
Next, I will elaborate on the intermediate logical processing steps.

We pass in two arrays

oldList = [ A, B, C, D];
newList = [ E ,C, D, B];

In the first step, the two arrays intersect to find item s that need to be deleted.

var simulateList = [];
oldList.forEach((item, index) => {
    // This item exists in the newList
    if (newList.indexOf(item) !== -1) {
        simulateList.push(item)
    } else {
        moves.push({
            type: 'remove',
            index: index
        })
    }
});

// When the program runs out, simulateList is the intersection of oldList and newList, sorted in the order of oldList.
// At this point, the value of simulateList is [B, C, D]
// At this point, the value of moves is [{type:'remove',index:0}], and the identifier deletes the item marked 0 from the oldList, i.e., deletes A.

The second step is to synchronously traverse the newList and simulateList

newList = [E,C,D,B];
simulateList= [B,C,D];

// i and j are subscripts to newList and simulateList, respectively

// Comparing newList E with simulateList B, if E is not equal to B and E does not exist in simulateList, insert E 
// i=0;j=0;
moves = [
    {type:'remove',index:0},
    {type:'insert',index:0,item:E}
];
i++;

// Comparing newList C with simulateList B, C is not equal to B and the next one of simulateList B is C, then remove B
// i=1;j=0;

moves = [
    {type:'remove',index:0},
    {type:'insert',index:0,item:E},
    {type:'remove',index:1}
]
i++;
j++;


// 4. newList D is compared with simulateList D, and equality goes to the next step.
i++;
j++;

// 5. newList B, when simulateList is finished, insert B
// i=3;j=2;

moves = [
    {type:'remove',index:0},
    {type:'insert',index:0,item:E},
    {type:'remove',index:1},
    {type:'inser', item: B, index: 3}
]

The final returned data is as shown above. According to this step, the oldList can be transformed into newList. Usually, the changes of lists are mainly concentrated on deleting or adding new data. There are very few cases where the list data are totally disrupted, so the above algorithm basically meets our needs.

From the above, we can see the importance of the only key. When writing a list with vue or react, we must use the only fixed value as possible, and avoid using array subscripts as keys.

For the first time, Haihan was invited to write an article.

Posted by jkm4201 on Thu, 24 Jan 2019 15:24:14 -0800