iOS---分页加载实现方案

转自:https://www.jianshu.com/p/59a28a0a88aa


一、基于偏移的分页

例如: http://XXXXXXXlist?page=1&count=20

缺点:

1、数据重复


数据重复

2、数据缺失


数据缺失

3、效率低
使用limit在数据量小的时候并不会有效率问题,但是当数据偏移量很大时性能会开始急剧下降,查询性能比对会在接下来提到。

综上所述,流式分页不需要也不适合使用传统分页,而是使用一种更合适的方法:游标分页。

所以这种分页方法 适用于 数据部经常变化的情况。或者拿到数据后做去重处理。

二、基于游标分页方案

基于游标的分页是最有效的分页方法,应尽量使用这种方法。游标是指标记数据列表中特定项目的一个随机字符串。该项目未被删除时,游标将始终指向列表的同一部分,项目被删除时游标即失效。因此,您的应用不应存储任何旧的游标,也不能假定它们仍然有效。

游标分页的连线支持以下参数:

  • before:这是指向已返回的数据页面开头的游标。

  • after:这是指向已返回的数据页面末尾的游标。

  • limit:这是每个页面返回的单独对象的数量。请注意:这是上限。如果数据列表中没有足够的剩余对象,那么返回的数量将小于这个数。为提升性能,将为某些连线的 limit 值设置上限。在调用案例中,API 将返回正确的分页链接。

  • next:将返回下一页数据的图谱 API 端点。如果未包含,则显示的是最后一页数据。根据分页的可见性和隐私,页面可能为空,但包含“next”分页链接。“next”链接不再出现时,应停止分页。

  • previous:将返回上一页数据的图谱 API 端点。如果未包含,则显示的是第一页数据。

Facebook 示例

{
 "data":[     ...端点数据在此 ], 
"paging":{   
  "cursors":{     
      "after":"MTAxNTExOTQ1MjAwNzI5NDE=",                
      "before":"NDMyNzQyODI3OTQw"   
    },   
      "previous":"https://graph.facebook.com/me/albums?limit=25&before=NDMyNzQyODI3OTQw",         
      "next":"https://graph.facebook.com/me/albums?limit=25&after=MTAxNTExOTQ1MjAwNzI5NDE=" 
    }
}

Twitter 示例

Twitter

请求参数:

|参数| 是否可选| 描述 |
|:----|:-----||
|since_id|optional|Returns results with an ID greater than (that is, more recent than) the specified ID. There are limits to the number of Tweets which can be accessed through the API. If the limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID available. ** Example Values: 12345|
|count|optional|Specifies the number of tweets to try and retrieve, up to a maximum of 200 per distinct request. The value of count is best thought of as a limit to the number of tweets to return because suspended or deleted content is removed after the count has been applied. We include retweets in the count, even if include_rts is not supplied. It is recommended you always send include_rts=1 when using this API method.|
|max_id|optional|Returns results with an ID less than (that is, older than) or equal to the specified ID.
Example Values: 54321**|

返回结果:

"search_metadata": {
  "max_id": 250126199840518145,
  "since_id": 24012619984051000,
  "refresh_url": "?since_id=250126199840518145&q=php&result_type=recent&include_entities=1",

  "next_results": "?max_id=249279667666817023&q=php&count=10&include_entities=1&result_type=recent",

  "count": 10,
  "completed_in": 0.035,
  "since_id_str": "24012619984051000",
  "query": "php",
  "max_id_str": "250126199840518145"
}

问题: 如果 某一条 id 被删除了,怎么处理?

三、基于时间的分页

时间分页使用指向数据列表中的特定时间的 Unix 时间戳在结果数据中导航。

基于时间的连线支持以下参数:

  • until:指向基于时间的数据范围末尾的 Unix 时间戳或 strtotime
    数据值。
  • since:指向基于时间的数据范围开头的 Unix 时间戳或 strtotime
    数据值。
  • limit:这是每个页面返回的单独对象的数量。限值 0 将不返回结果。为提升性能,将为某些连线的 limit 值设置上限。在调用案例中,API 将返回正确的分页链接。
  • next:将返回下一页数据的图谱 API 端点。
  • previous:将返回上一页数据的图谱 API 端点。

抓包发现 新浪微博 使用的就是 基于时间的分页

  必选 类型 描述
since_id false int64 若指定此参数,则返回ID比since_id大的微博(即比since_id时间晚的微博),默认为0。
max_id false int64 若指定此参数,则返回ID小于或等于max_id的微博,默认为0。

加载更多1:
max_id  1474446495309988
返回1:
since_id    String  1474446349209988
max_id  String  1474446349209988
need_insert Integer 0
num Integer 17

加载更多2:
max_id  1474446349209988
返回2:
since_id    String  1474444074709993
max_id  String  1474444074709993
need_insert Integer 0
num Integer 11


加载更多3:
max_id  1474444074709993
返回3:
since_id    String  1474443946709988
max_id  String  1474443946709988
need_insert Integer 0
num Integer 12

下拉刷新
since_id    1474446662409995
refresh pulldown
isgzip  1
preAdInterval   7
返回:
since_id    String  1474447981509999
max_id  String  1474447981509999
interval    Integer 0
need_insert Integer 0
num Integer 0

四、延伸——数据的缓存

1、基于偏移的分页方案 会有数据重复加载到,需要做好去重工作。

2、基于游标的分页方案 有数据连续性的问题。
例如 第一次 缓存 10-0 条,第二次 缓存了 30-20 条记录。 第三次 打开 如果请求的数据 能 接上 第30条,则没问题。但是 缓存的 10-0 条记录 就断掉了。

所以:
A)如果 80% 的访问量 都是第一页的数据,例如最新的 20条 或者 40条 记录,则可以 只缓存 第一页的数据。
例如 新浪微博
B)把每次断掉的 id 都缓存起来。等加载到的时候再连上。

C)自己想到的方案:客户端只缓存最新的连续数据。

  • 每次请求服务器的时候,都带上最新的id(since_id)和最老的 id(max_id)。加载更多 或者 下拉刷新时,如果可以和缓存连接上,则同时返回 since_id 和 max_id 之间 变化的数据(例如删除了某一条),客户端做处理。
  • 下拉刷新时,假如本来一页是返回10条数据,但是实际上只有11or12条数据,

五、 对比

一、传统分页:

总结

传统分页的特点:

  • 可以直接根据页码跳转到特定页
  • 可能会出现重复、丢失数据的情况
  • 页数较大时性能会降低
  • 排序条件与分页无关

游标分页的特点:

  • 不可以直接跳转到特定页(知道页数),但是可以直接跳转到最后一页,能加载下一页,上一页。
  • 不会出现重复、丢失数据的情况
  • 查询效率与页数无关,并且优于传统分页
  • 不适合排序条件比较复杂的分页

参考文档:



猜你喜欢

转载自blog.csdn.net/iotjin/article/details/80393014
今日推荐