分页类型
传统分页
通过页码进行分页
通过点击上/下页按钮可实现页面切换
通过点击页码可实现页面切换
可直接跳转至指定页面
多用于 PC 端
流式分页
通过滚动/上拉/点击等方式加载新一页
无页码
无上/下页按钮
不可跳转至指定页面
pc端和移动端均有使用
流式分页的实现方案
前端分页的实现
diviner.jd.com/diviner?p=610009&callback=jsonpCallbackMoreGood&lid=1&lim=100&ec=utf-8
参数 | 含义 | 备注 |
---|---|---|
lim / limit | 返回数据个数 | 由前端根据需要传参,或由后端设置默认值 |
Model.find().limit(lim)
后端分页的实现
https://ai.jd.com/index_new.php?app=Discovergoods&action=getDiscZdmGoodsList&callback=listCallback&page=1
参数 | 含义 | 备注 |
---|---|---|
page | 当前页数 | 由前端传参 |
pageSize / limit | 每页数据个数 | 由前端根据需要传参,或由后端设置默认值 |
const offset = (page-1) * pageSize // 跳过的个数
Model.find().skip(offset).limit(pageSize)
后端分页的问题与优化
存在的问题
1. 数据缺失
2. 数据重复
优化方案
1. 使用缓存
请求第 1 页数据时,timestamp 传 0,服务端检查将当前系统时间赋值给 timestamp 返回
请求第 2,3,…n 页数据时,将第 1 步系统返回的 timestamp 传入
参数 | 含义 | 备注 |
---|---|---|
page | 当前页数 | 由前端传参 |
pageSize | 每页数据个数 | 由前端根据需要传参,或由后端设置默认值 |
timestamp | 时间戳 | 由前端传参 |
若
timestamp
为 0,生成当前时间对应的缓存,如“data_1498705088000”,并返回前端所需数据若
timestamp
不为 0 且对应的缓存不存在,返回“刷新数据”的提示若
timestamp
不为 0 且有对应的缓存,则返回前端所需数据
2. 游标式分页
客户端记录当前分页的最后一条数据的 ID
请求下一页的时候,从这个 ID 开始获取一页大小的内容
参数 | 含义 | 备注 |
---|---|---|
curcor | 最后一个 ID | 由前端传参 |
pageSize | 每页数据个数 | 由前端根据需要传参,或由后端设置默认值 |
Model.find({id: {$gt: cursor}}).limit(pageSize)
能够避免数据重复/遗漏
无需计算offset,性能更稳定
只适用于按照时间追加的方式的简单排序
3. 一次性下发 ID
请求第 1 页数据之前/时先缓存所有 ID 列表
请求第 2,3,…n 页数据时,只需传入相关的 ID 列表参数
http://xw.qq.com/service/api/proxy?key=Xw@2017Mmd&charset=GBK&url=http://openapi.inews.qq.com/getQQNewsIndexAndItems?chlid=news_news_top&refer=mobilewwwqqcom&otype=jsonp&t=1498706343475
http://xw.qq.com/service/api/proxy?key=Xw@2017Mmd&charset=GBK&url=http://openapi.inews.qq.com/getQQNewsNormalContent?ids=20170604A063AG00,20170604A05SKQ00,20170604A05PBT00,NEW2017060403772906,NEW2017060403765707,NEW2017060403278705,20170604A06CMP00,20170604A03ZEU00,20170604A04P5900,NEW2017060402106202,20170603A07E0700,20170604A04WBM00,NEW2017060403031208,20170604A02X9900,20170604A03U6600,20170604A040JX00,20170604A04TE200,NEW2017060403727300,NEW2017060403727800,20170604A03I8200&refer=mobilewwwqqcom&otype=jsonp&t=1496603487427
4. 客户端排除
在客户端中保存已加载记录的 ID
每次请求完数据时,先进行数据去重
若去重数据较多,则考虑再请求下一页的数据
确保不会出现重复的数据
不改动服务器端的原有逻辑
只适用于列表数据添加不是很频繁的情况
参考文档
《浅谈APP流式分页服务端设计》
《浅谈单页应用中前端分页的实现方案》
《APP后端分页设计》
《Infinite Scrolling vs. Pagination》
《瀑布流下拉加载更多导致数据重复怎么办》
本文分享自微信公众号 - 凹凸实验室(AOTULabs)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。