美文网首页
无标题文章

无标题文章

作者: 追逐時光的旅行 | 来源:发表于2016-05-21 15:52 被阅读0次

    废话不多说,为了记录大前端的发展,研读React的内在,写下记录:
    传统 diff 算法
    计算一棵树形结构转换成另一棵树形结构的最少操作,是一个复杂且值得研究的问题。传统 diff 算法通过循环递归对节点进行依次对比,效率低下,算法复杂度达到 O(n^3),其中 n 是树中节点的总数。O(n^3) 到底有多可怕,这意味着如果要展示1000个节点,就要依次执行上十亿次的比较。这种指数型的性能消耗对于前端渲染场景来说代价太高了!现今的 CPU 每秒钟能执行大约30亿条指令,即便是最高效的实现,也不可能在一秒内计算出差异情况。
    因此,如果 React 只是单纯的引入 diff 算法而没有任何的优化改进,那么其效率是远远无法满足前端渲染所要求的性能。
    通过下面的 demo 可以清晰的描述传统 diff 算法的实现过程。

    var result = [];

    var diff = function (beforeDom, afterDom) {
    // 获取较大节点树的长度
    var count = Math.max(beforeDom.children.length, afterDom.children.length);
    //循环遍历
    for (var i=0; i<count; i++) {
    var beforeTag = beforeDom.children[i];
    var afterTag = afterDom.children[i];
    // 添加 afterTag 节点
    if (beforeTag === undefined) {
    //beforeTag 不存在
    //{type: type, elment: elment}
    result.push({type: 'add', element: afterTag});
    //删除 beforeTag 节点
    } else if (afterTag === undefined) {
    result.push({type: 'remove', element: beforeTag});
    //节点名改变时,删除 beforeTag 节点,添加 afterTag 节点
    } else if (beforeTag.tagName !== afterTag.tagName) {
    result.push({type: 'remove', element: beforeTag});
    result.push({type: 'add', element: afterTag});
    // 节点不变而内容改变时,改变节点
    } else if (beforeTag.innerHTML !== afterTag.innerHTML) {
    //如果之前DomTag的子元素个数为0
    if (beforeTag.children.length === 0) {
    result.push({type: 'changed', beforeElement: beforeTag, afterElement: afterTag, html: afterTag.innerHTML});
    } else {
    // 递归比较
    diff(beforeTag, afterTag)
    }
    }
    }
    return result;
    }

    相关文章

      网友评论

          本文标题:无标题文章

          本文链接:https://www.haomeiwen.com/subject/wkcorttx.html