分页AngularJS发布应用程序性能问题

分页AngularJS发布应用程序性能问题

问题描述:

分页AngularJS发布应用程序性能问题

Paginated AngularJS posts application performance issue

我已经制作了一个小应用程序,它借助AngularJS和Twitter Bootstrap 4以卡的形式显示 posts JSON.

I have made a small application that displays an posts JSON in the form of cards, with the help of AngularJS and Twitter Bootstrap 4.

该应用程序具有分页,并且每个页面上显示大约100个帖子.

The application has a pagination and there are about 100 posts displayed on each page.

var root = 'https://jsonplaceholder.typicode.com';

// Create an Angular module named "postsApp"
var app = angular.module("postsApp", []);

// Create controller for the "postsApp" module
app.controller("postsCtrl", ["$scope", "$http", "$filter", function($scope, $http, $filter) {
  var url = root + "/posts";
  $scope.postList = [];
  $scope.search = "";
  $scope.filterList = function() {
    var oldList = $scope.postList || [];
    $scope.postList = $filter('filter')($scope.posts, $scope.search);
    if (oldList.length != $scope.postList.length) {
      $scope.pageNum = 1;
      $scope.startAt = 0;
    };
    $scope.itemsCount = $scope.postList.length;
    $scope.pageMax = Math.ceil($scope.itemsCount / $scope.perPage);
  };
  $http.get(url)
    .then(function(data) {
      // posts arary
      $scope.posts = data.data;
      $scope.filterList();

      // Paginate
      $scope.pageNum = 1;
      $scope.perPage = 24;
      $scope.startAt = 0;
      $scope.filterList();

      $scope.currentPage = function(index) {
        $scope.pageNum = index + 1;
        $scope.startAt = index * $scope.perPage;
      };

      $scope.prevPage = function() {
        if ($scope.pageNum > 1) {
          $scope.pageNum = $scope.pageNum - 1;
          $scope.startAt = ($scope.pageNum - 1) * $scope.perPage;
        }
      };

      $scope.nextPage = function() {
        if ($scope.pageNum < $scope.pageMax) {
          $scope.pageNum = $scope.pageNum + 1;
          $scope.startAt = ($scope.pageNum - 1) * $scope.perPage;
        }
      };
    });
}]);

.posts-grid {
  margin-top: 25px;
  display: flex;
  flex-wrap: wrap;
}

.posts-grid>[class*='col-'] {
  display: flex;
  flex-direction: column;
  margin-bottom: 25px;
}

.posts-grid .post {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-top: 1px solid #d5d5d5;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.11);
}

.posts-grid .text {
  padding: 8px;
}

.posts-grid .card-title {
  font-size: 1.25rem;
  margin-bottom: 8px;
  text-transform: capitalize;
}

.posts-grid .read-more {
  padding: 0 8px 8px 8px;
  margin-top: auto;
}

.posts-grid .text-muted {
  margin-bottom: 8px;
}

.posts-grid .thumbnail img {
  display: block;
  width: 100%;
  height: auto;
}

.posts-grid p {
  text-align: justify;
}

.pagination>li>a,
.pagination>li>a:hover,
.pagination>li>span {
  color: #585858;
  line-height: 1;
  padding: 6px 12px;
  text-decoration: none;
}

.pagination>.active>a,
.pagination>.active>span,
.pagination>.active>a:hover,
.pagination>.active>span:hover,
.pagination>.active>a:focus,
.pagination>.active>span:focus {
  background-color: #007bff;
  border-color: #2b7c2b;
  color: #fff;
}

@media (max-width: 767px) {
  .container {
    max-width: 100%;
  }
}

@media (max-width: 575px) {
  .container {
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
  }
  .posts-grid>[class*='col-'] {
    padding-left: 5px;
    padding-right: 5px;
  }
}

<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>

<nav class="navbar navbar-expand-md bg-dark navbar-dark sticky-top">
  <!-- Brand -->
  <a class="navbar-brand" href="#">My Blog</a>
  <!-- Toggler/collapsibe Button -->
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
	 <span class="navbar-toggler-icon"></span>
  </button>

  <!-- Navbar links -->
  <div class="collapse navbar-collapse" id="collapsibleNavbar">
    <ul class="navbar-nav ml-auto">
      <li class="nav-item">
        <a class="nav-link active" href="#">Contacts</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">About us</a>
      </li>
      <li class="nav-item">
        <a class="nav-link btn btn-outline-primary" href="#">Login</a>
      </li>
    </ul>
  </div>
</nav>

<div data-ng-app="postsApp">
  <div class="container" data-ng-controller="postsCtrl">
    <div class="row">
      <div class="col-sm-9 mx-auto">
        <div class="form-group search-box mt-3 px-3">
          <input type="text" class="form-control" id="search" placeholder="Search post" data-ng-model="search" ng-change="filterList()">
        </div>
      </div>
    </div>
    <div class="posts-grid" ng-if="postList.length > 0">
      <div class="col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-ng-repeat="post in postList | limitTo : perPage : startAt">
        <div class="post">
          <div class="thumbnail">
            <img src="//lorempixel.com/450/300" />
          </div>
          <div class="text">
            <h3 class="card-title">{{post.title}}</h3>
            <p class="text-muted">{{post.body}}</p>
          </div>
          <div class="read-more">
            <a class="btn btn-block btn-sm btn-primary" href="#">Read more</a>
          </div>
        </div>
      </div>
    </div>
    <p ng-if="postList.length <= 0" class="text-center">There are no posts</p>
    <div ng-if="pageMax > 1">
      <ul class="pagination pagination-sm justify-content-center">
        <li class="page-item"><a href="#" ng-click="prevPage()"><i class="fa fa-chevron-left"></i></a></li>
        <li ng-repeat="n in [].constructor(pageMax) track by $index" ng-class="{true: 'active'}[$index == pageNum - 1]">
          <a href="#" ng-click="currentPage($index)">{{$index+1}}</a>
        </li>
        <li><a href="#" ng-click="nextPage()"><i class="fa fa-chevron-right"></i></a></li>
      </ul>
    </div>
  </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<script>
  $(document).ready(function($) {
    $('.pagination > li > a').click(function() {
      $("html, body").animate({
        scrollTop: 0
      }, 500);
      return false;
    });
  });
</script>

最近在我脑海中浮现出几个问题,我没有找到答案,因此这里是我的话题:

A few questions ware born in my mind recently and I did not find the answer, hence my topic here:

  1. 如果发布的帖子数量是原来的10或100倍,应用程序会出现性能(页面加载)问题怎么办?

  1. What if there ware 10 or 100 times as many posts, woud the application have a performance (page load) problem?

是否有更好的分页应用程序的方法;一个会从 posts.json 中加载与在一页上显示的项目一样多的项目(24个项目),而不是整个JSON文件?

Is there a better way to paginate the application; one that would load as many items from posts.json as there are displayed on one page (24 items), instead of the entire JSON file?

如果发布的商品数量是其数量的10或100倍,应用程序会出现性能(页面加载)问题怎么办?

What if there ware 10 or 100 times as many posts, woud the application have a performance (page load) problem?

是的,如果您在前端加载,很多数据浏览器可能会崩溃.您可以简化它,只需要创建一系列压力测试即可.尝试从后端(不是jsonplaceholder)返回数百个数据,浏览器将冻结

Yes, if you load on front-end a lot of data browser could be go down. You can dimostrate it, need only create a series of stress test. Try to return hundred of hundred of data from your back-end (not jsonplaceholder), the browser will freeze

是否有更好的分页应用程序的方法;

Is there a better way to paginate the application; one that would load as many items from posts.json as there are displayed on one page (24 items), instead of the entire JSON file?

根据我的经验,我使用前端和后端之间的协作进行分页.

In my experience I did pagination using a collaboration between front-end and back-end side.

前端:您可以在功能的基础上选择不同类型的分页(无穷大滚动,标准分页等).

front-end: you can choose different kind of pagination (infinity scroll, standard pagination etc.) in base of your features.

后端:您可以创建休息服务,以每页输入项目和偏移量(您的页面)的方式输入

back-end: you can create rest service that take in input the items per page and an offset (your page).

在浏览器上更改页面时,您将要求后端珩磨器调用可分页查询.

When on browser you change page you will demande the back-end the honer to call a pageable query.

根据我的经验,我通过大量数据获得了不错的表现.

In base of my experience I gained a good performance with a lot of data.