zoukankan      html  css  js  c++  java
  • AngularJs ng-repeat 必须注意的性能问题

    AngularJs 的 ng-repeat 让我们非常方便的遍历数组生成 Dom 元素,但是使用不当也会有性能问题。

    在项目中我们使用 ng-repeat 加载完一个列表后,如果再次请求数据,然后过滤列表,代码可能会这么写:

    <div ng-controller="Test">
        <button ng-click="request()">请求新数据</button>
        <div ng-repeat="user in users">
            {{user.name}}
        </div>
    </div>
    

    Controller 的代码:

    app.controller('Test', function($scope) {
        var users = [];
        for (var i = 0; i < 100; i++) {
            users[i] = {
                id: i,
                name: "User: " + i
            };
        }
        $scope.users = users;
    
        $scope.request = function () {
            // 从服务器加载新数据
            var result = [];
    
            // 直接重新赋值给 users
            $scope.users = result;
        };
    });
    

    查看 ng-repeat 的源码可以发现,当 ng-repeat 的数组被替换时, 它默认并不会重新利用已有的 Dom 元素,而是直接将其全部删除并重新生成新的数组 Dom 元素:

    // 将上次生成的所有 dom 移除
    for (key in lastBlockMap) {
        if (lastBlockMap.hasOwnProperty(key)) {
            block = lastBlockMap[key];
            elementsToRemove = getBlockElements(block.clone);
            $animate.leave(elementsToRemove);
            forEach(elementsToRemove, function(element) { element[NG_REMOVED] = true; });
            block.scope.$destroy();
        }
    }
    

    Dom 的频繁操作是非常不友好的,为什么 ng-repeat 不能利用已有的 dom 元素去更新数据呢?因为你没有把数组元素的标识属性告诉它,那么两次替换的时候它就没办法追踪了,我们可以看到 ng-repeat 往数组里每个元素加了一个 $$hashKey 的属性:

    key

    这个 key 是由 Angular 内部的 nextUid() 方法生成,类似数据库自增,但是是使用字符串。

    现在我们明白了,因为每次替换数组都会导致 ng-repeat 为每个元素生成一个新 key, 所以根本没办法重用已有的 Dom 元素,那么我们可以使用下边的语法来避免这个问题:

    <div ng-controller="Test">
        <button ng-click="request()">请求新数据</button>
    	// 使用 track by 标识
        <div ng-repeat="user in users track by user.id">
            {{user.name}}
        </div>
    </div>
    

    这样 ng-repeat 就用将其缓存起来啦,当然可能你的数组元素没有一个标识属性,如果元素数量不多那么可以接受,不然还是建议你手动为其生成一个标识属性。

  • 相关阅读:
    stenciljs 学习四 组件装饰器
    stenciljs 学习三 组件生命周期
    stenciljs 学习二 pwa 简单应用开发
    stenciljs ionic 团队开发的方便web 组件框架
    stenciljs 学习一 web 组件开发
    使用npm init快速创建web 应用
    adnanh webhook 框架 hook rule
    adnanh webhook 框架 hook 定义
    adnanh webhook 框架request values 说明
    adnanh webhook 框架execute-command 以及参数传递处理
  • 原文地址:https://www.cnblogs.com/MigCoder/p/3930264.html
Copyright © 2011-2022 走看看