📜  大量页面的分页 (1)

📅  最后修改于: 2023-12-03 15:23:44.656000             🧑  作者: Mango

大量页面的分页

在Web开发中,经常会遇到需要分页展示大量数据的情况。如何高效地实现这种分页,是一个值得探讨的问题。

传统的分页方式

传统的分页方式是在后端进行数据查询和分页处理,然后将某一页的数据返回给前端。前端的分页逻辑是简单的根据总数据量、每页展示数量和当前页数计算出需要展示的数据在总数据中的位置,然后展示出来。

public interface UserService {
    /**
    * 查询用户列表。参数page、pageSize为分页参数,pageNum为要查询的页码。返回值为用户列表预计的总数及实际返回的用户列表。
    */
    UserListVO listUser(int page, int pageSize, int pageNum);
}

这种方式看似简单,但不足之处也很明显:

  • 由于总数据量很大,可能导致查询和分页处理的时间很长,从而导致整个请求的响应时间变长;
  • 如果需要展示的数据实时性比较高,必须要及时更新缓存,否则可能导致展示的数据和实际的数据不一致;
  • 由于分页的数据本身是有序的,因此这种方式对用户直接随机访问某一页的需求支持不友好,需要对每一页的数据进行缓存或预处理。
前端分页

因此,有一种“前端分页”的方式很受欢迎。它的原理是直接将后端查询的所有数据一次性返回,并在前端进行分页处理。

public interface UserService {
    /**
     * 查询用户列表。参数pageNum、pageSize为分页参数。返回值为用户列表预计的总数及实际返回的用户列表。
     */
    UserListVO listUser(int pageNum, int pageSize);
}
function getPageData(pageNum, pageSize, data) {
    const startIndex = (pageNum - 1) * pageSize;
    const endIndex = startIndex + pageSize;
    const pageData = data.slice(startIndex, endIndex);
    return pageData;
}

这种方式的好处是:

  • 后端都只需要执行一次查询和分页处理,在前端进行分页会极大地减少后端查询和处理的时间;
  • 前端只需要返回需要展示的数据,不需要返回其他信息,因此网络传输量更小;
  • 前端可以直接根据展示需求对数据进行排序、过滤等处理,不需要再额外查询处理;

但也有缺点:

  • 前端需要一次性加载所有数据,太多数据的话可能会导致前端性能下降;
  • 前端需要对所有数据进行处理,因此可能会导致前端的运行时间变长。
高性能前端分页

通过上面的比较,我们可以发现前后端分别做分页都有各自的优缺点。那么有没有一种既能减少后端查询和处理时间,又能在前端实现高性能分页的方式呢?

答案是有的。一个优秀的前端分页方式应该是:

  1. 前端只加载需要展示的数据。
  2. 前端可以根据当前数据量和用户的查询条件等综合因素,决定是否使用前后端分页。
  3. 如果用户需要直接访问某一页,可以在前端直接对数据进行缓存或者进行预处理。

实现这种前端分页方式,需要考虑以下几个方面:

数据的处理

在前端进行分页时,需要把所有数据从后端请求到前端。但是由于数据过多,前端无法一次性展示。在这种情况下,我们需要将数据划分成若干个小块(一般为每一页的数据量),并在前端分别展示。比如:

const data = [
    {id:1, name:'Alice', age:18},
    {id:2, name:'Bob', age:25},
    {id:3, name:'Cathy', age:32},
    //...
];

const pageSize = 10;
const pageNum = 1;
const startIndex = (pageNum - 1) * pageSize;
const endIndex = startIndex + pageSize;
const pageData = data.slice(startIndex, endIndex);

我们要展示的数据就是pageData

分页逻辑的实现

在前端处理分页时,需要根据总数据量、每页展示数据量和当前页数,计算出需要从展示数据中哪里开始截取。我们可以通过下面这段代码实现:

function getPageData(pageNum, pageSize, data) {
    const startIndex = (pageNum - 1) * pageSize;
    const endIndex = startIndex + pageSize;
    const pageData = data.slice(startIndex, endIndex);
    return pageData;
}

这个函数的参数包括:

  • pageNum:当前页码。
  • pageSize:每页展示数据量。
  • data:需要分页的数据。

它的返回值是从所有数据中截取的用于展示的页数据。

缓存和预处理

如果用户需要直接访问某一页,并且数据量很大,那么此时在前端对数据进行分页和计算是非常耗时的。因此,我们可以考虑在前端缓存一些数据,或者实现一些预处理逻辑。比如,我们可以在数据加载时,将每一页的数据展示出来,并将其他页面的数据进行缓存。如果用户直接访问某一页,直接从缓存中获取该页数据即可。这样可以大大减少在前端进行数据处理的时间。

分页的位置控制

在大量数据的分页的应用中,用户能直观地看到数据展示的位置非常重要。因此要考虑到让用户在直观上找到自己想看的数据时不需要过多的点击更多。如果你采用 ajax 方式实现分页,那么分页导航条是不再以超链接的形式出现了,翻页变得更加友好,而一般是以一个视觉组件,如按钮或下拉框等形式提示用户所处的页码。

结论

前端分页和后端分页各自有优缺点。如果数据量较小,可以使用前端分页;如果是大量数据,可以考虑使用前后端结合的方式。但是需要注意,大量数据的展示需要注意以下事项:

  • 减少后端查询和处理的时间;
  • 减少前端发送的请求;
  • 数据的处理和分页逻辑的实现需要注意性能问题;
  • 对于用户直接访问某一页的需求,需要实现缓存或者预处理。

在实现前端分页时,我们需要掌握一些基本的技术能力,比如slice函数、分页算法的实现等。同时,编写良好的代码风格、采用合适的缓存机制也是非常重要的。