简体   繁体   中英

Paginated AngularJS posts application performance issue

Paginated AngularJS posts application performance issue

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.

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. What if there ware 10 or 100 times as many posts, woud the application have a performance (page load) problem?

  2. 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?

  3. How would you optimize this application, on the front end?

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM