改进性能ng-repeat列表750个元素

时间:2015-05-07 21:50:28

标签: angularjs performance ng-repeat

想知道在我的场景中提高性能的最佳方法是实时过滤的750个元素的列表,并且要求不分页或限制列表,750个元素应该在屏幕上,需要尽可能快地过滤用输入文本实时提供,显然使用

表现
# transform for good measure
states <- spTransform(states,CRS("+datum=WGS84 +proj=longlat") )

# combine ggmap with shapefile
states_df <- fortify(states)

# get your map
map <-get_map("new york city", zoom = 10, source = "stamen")

a <- ggmap(map, # this is where we get our raster
       base_layer=ggplot(aes(x=long, y=lat), data=states_df), # this defines the region where things are plotted
       extent = "normal",  # this won't work with device, you need normal (see examples in ggmap documentation)
       maprange=FALSE
       ) +
coord_map( # use map's bounding box to setup the 'viewport' we want to see
  projection="mercator",
  xlim= c(attr(map, "bb")$ll.lon, attr(map, "bb")$ur.lon),
  ylim=c(attr(map, "bb")$ll.lat, attr(map, "bb")$ur.lat)
) +
geom_polygon( # plot the polygon
  aes(x=long, y=lat,group=group), data =states_df, color = "red", fill=NA, size = 1)

print(a)

在这里不是很好,有什么想法吗?

编辑:当前场景

ng-repeat="x in collection | filter: x" 

现在所有过滤都在控制器中以获得更好的性能,在此功能中

 <section ng-repeat="(key, value) in content">
    <md-subheader class="md-primary">{{ key == '1' ? '#' : key }}</md-subheader>
    <md-list layout-padding>
        <md-list-item class="md-3-line" ng-repeat="person in value" layout="row">
            <div flex="15" flex-md="10" layout="column" layout-align="center center">
                <span>{{ ::person.id_lista_nominal }}</span>
            </div>
            <div class="md-list-item-text" flex>
                <h3>{{ ::person.nombre_completo }}</h3>
                <h4>{{ ::person.ine }}</h4>
            </div>
            <div flex="15" flex-md="10" layout="column" layout-align="center center">
                <md-button aria-label="Votó" class="md-primary md-raised text-white" ng-click="confirm_voting(person, $event)"><md-icon md-font-icon="mdi-navigation-check icon-md"></md-icon> </md-button>
            </div>
        </md-list-item>
    </md-list>
</section>

因为它是正确的,所以我的目标并不是很明确,所以这里是:

我正在开发一个使用cordova的移动应用程序,所有这些在电脑上运行良好且流畅但在移动设备上感觉很迟钝

在这里我有一个像联系人列表的列表,第一个ng-repeat重新排序列表并将列表拆分成组(子标题是组名)

嵌套的ng-repeat用于显示每个组内的人员列表

这个屏幕的过程非常简单,因为这是一个滞后的界面是不可接受的

用户只能通过滚动或按人名过滤来搜索列表,每个人的按钮都会询问用户是否愿意将联系人“标记”为进程,如果用户同意该过程将执行一个简单的过程websql命令通过其id将mark = 1设置为选定的人,它将从列表中删除该人。

但是列表中屏幕上750人的过滤感觉有问题,每次用户标记一个人时,更新列表需要3到4秒钟,并显示删除标记

所需的体验是流畅的滚动,快速搜索和标记后的中间删除,我知道如果我限制屏幕上的人数(假设为50)我在过程中获得了很多表现,但遗憾的是对我来说这不是一个选择,除非可能管理一种模拟方法,他们可以向上和向下滚动,但限制显示的数据量:S

5 个答案:

答案 0 :(得分:1)

您不必限制元素本身的数量,但如果您检测到它,则可以在滚动事件中加载它们。

例如,我将承认你使用一个普通的mysql数据库存储你的所有数据,我使用两个变量来做这个并得到我所有的用户评论,看起来就像那样(阅读评论):

    //Function to get all comments progressively
    $scope.getAllCommentsByUserId = function(){

        //action name, here actionVar's value will be my php case, if 
        //$_POST['action'] equal this value then i will send my sql request

        var actionVar = "getAllCommentsByUserId";

        //Define callback function
        var callback = function(resp){

            if(resp.success == 1){

                // $scope.userComments will be my array were the sql results
                // from resp will be stored, also it's the main varaible of 
                // my ng-repeat loop, i push them because i don't want 
                // to erase the comments i already requested, so the new ones  
                // will be at the end of the array

                angular.forEach(resp.comments, function(comment, key) {
                    $scope.userComments.push(comment);

                });

            // In case i got an error istead of a good result

            }else{
                $scope.$emit('showAlert', ["Une erreur est survenue","error"]);

            }

        };

        // In case you want to know, userId is not needed, i use it just to 
        // request all the comments on the current user's page. that's just logic.

        var params = {
            'action' : actionVar,
            'idUser' : $scope.bigouder.idUser,
            'begin' : $scope.beginComments,
            'length' : $scope.lengthComments
        };

        //HTTP REQUEST
        $http.post(url, params)
        .success(callback)
        .error(function(){
            $scope.$emit('showAlert', ["ERROR","error"]);

        });
    };

   // I update the begining element index by adding the length to it
   // YOU HAVE TO SET "beginComments" AND "lengthComments" AT THE BEGINING OF 
   // YOUR JS FILE, to give them a default value, otherwise that will never work.

   $scope.changeMaxComments = function(){
        $scope.beginComments += $scope.lengthComments;
        $scope.lengthComments = 20;
        $scope.getAllCommentsByUserId();
    };

基本上我在这里做的是设置2个值:

  • beginComments和lengthComments

beginComments将是我的sql请求将开始保存结果结果的元素,lengthComments将是我将保存的结果数。

sql请求将是这样的:$query = "select ... from ... where ... order by ... limit". $_POST['begin'] . "," $_POST['length'];

所以我在我的sql请求中使用带有limit参数的两个变量,我将从&#34; beginComments&#34;中获取所有结果。元素到&#34; beginComments + lengthComments&#34;元件。

当您检测到滚动事件时,您只需要调用类似的东西,angular会完成工作并刷新ng-repeat。 :)

答案 1 :(得分:0)

限制最初显示的元素数量,然后在用户滚动时显示更多元素。就像高音无限滚动一样(当用户到达页面底部时,它会加载更多推文)

答案 2 :(得分:0)

  1. 以某种方式简化您的过滤器,以便您的控制器或服务生成应列出的项目,而不是在视图中执行此操作。 (key, value) in filteredContent()
  2. 另一个想法是使用https://github.com/Pasvaz/bindonce并在可能的情况下更新事件数据。
  3. 只需将手表数量保持在1,200以下(当我经历缓慢时),你就可以了。 http://www.bennadel.com/blog/2698-counting-the-number-of-watchers-in-angularjs.htm
  4. 否则我会谷歌降低监视计数并为AngularJS编写有效的过滤器。

答案 3 :(得分:0)

您无法解释您的要求......对于大量数据,AngularJS可能非常繁重,但750个简单项目不应成为问题。你有几种选择:

  • 使用ReactJShere指南)加快渲染速度,只需将该视图委派给reactJS。

  • 将过滤器输入更改为延迟,以便在按下的每个键上都不会更改model。首先,不要在过滤器上收听param.search,而是听取其他变量searchText

例如:

 $scope.$watch('param.search', function (newValue) {
      if (searchTextTimeout) {
        $timeout.cancel(searchTextTimeout);
      }
      searchTextTimeout= $timeout(function() {
        $scope.searchText= newValue;
      }, 300); // between 200-300 ms should be a good user experience
  });

您也可以应用React并延迟过滤器。如果您的表现仍然很差,可能问题出在您的风格中,单个样式可能会导致大量重新绘制,例如,如果您在过滤时动画position更改,那么动画会很慢。< / p>

我希望这适合你。

<强>更新

另外我注意到你正在使用这个指令md-subheader,它似乎只是添加#1或键需要显示的内容?如果是数字,你可以使用$ index代替

答案 4 :(得分:0)

我想我找到了解决我自己的问题的解决方案谷歌搜索我找到的各种类型的解决方法

Angular Virtual Scroll

一个非常棒的指令,直接在角度的ng-repeat循环上管理虚拟滚动的概念,这样,视图只会渲染一些项目,而滚动它会加载其余项目,但与延迟加载不同,用户看不到滚动条正在增加向下滚动导致alreade计算出空间,它会移除你在视口外滚动的元素,因此,你总是会有“错觉”,只需要渲染一些完整的项目