你的反对对我意义重大!
🔥 Hi,我是小彭。本文已收录到 GitHub · Android-NoteBook 中。这里有 Android 进阶成长路线笔记 & 博客,有气味相投的敌人,欢送跟着我一起成长。(联系方式在 GitHub)
前言
- 列表是 App 中很常见的一种内容排列模式,常见的列表款式有卡片流、瀑布流、信息流等,那么这些列表有什么区别呢?在这篇文章里,我将总结常见的列表款式以及接口分页设计相干问题。如果能帮上忙,请务必点赞加关注,这真的对我十分重要。
1. 常见列表款式
1.1 传统 PC 列表
咱们先说一种咱们很相熟的 PC 列表款式,列表底部会带有 上一页 / 下一页 / 页码
的页码切换性能,比方淘宝、百度、京东等列表。这类款式最大的特点是浏览的节奏感,在用户浏览一页数据后会有进展,因而列表底部经常会设置相干举荐、猜你喜爱等性能。
传统 PC 列表对屏幕尺寸有肯定要求,因而在手机端很少见。那么手机端有哪些常见的列表款式呢?从数据是否有止境,能够分为一般列表和瀑布流列表。
1.2 一般列表
一般列表是绝对于瀑布流列表的,一般列表的内容是无限的,只有始终滑总能滑到止境。从单个数据项的设计款式辨别,能够分为纯文字、图文混排、卡片三种:
- 纯文字: 以文字信息为主导的布局模式,例如手机短信列表;
- 图文混排: 以文字 + 图文的信息布局模式,可能疾速突出重点。除了规范的单列布局形式外,多种布局模式混合应用可能让布局内容更加多化;
- 卡片: 将卡片色彩与列表背景色彩能够辨别,使得视觉上可能轻易感知到卡片矩形的存在。同时,借助了卡片后景深(也就是卡片暗影)将页面 XY 轴扩大到 XYZ 三轴,从而增强了视觉层级丰富性。目前,卡片式设计曾经成为 App 中应用十分广告的设计款式。除了规范的单列布局外,双列卡片流也很常见。
1.3 瀑布流列表
绝对于简略列表,瀑布流列表指内容像瀑布一样源源不断,始终滑不到止境的列表。最常见的一种瀑布流是信息流(或 Feed 流),简直每个产品都存在信息流。信息流在散发内容时,会依据用户的爱好对内容进行干涉,更精准地向用户举荐内容。咱们相熟的产品中有哪些是信息流呢?
- 微信朋友圈:不算信息流,朋友圈是依照最近公布工夫排序,且存在止境;
- 知乎答复列表:不算信息流,答复列表是依照热度等指标综合排序,且存在止境;
- 抖音首页 / 小红书首页:算信息流,依据用户举荐,且滑不到止境。
即便列表的数据量很小,列表接口也应该在一开始就反对分页增量申请,防止未来再反对时的兼容问题。那么,列表分页有哪些设计方案呢?
2. 基于偏移分页
基于偏移是最常见的分页接口设计,其原理是通过数据库查问语句的 offset + limit 指定某一分页的数据。例如:
# 获取第 curPage 页数据,每页数据量为 pageSize
select * from ... where ... order by ... limit (curPage - 1) * pageSize, pageSize
因而,前端参数须要指定申请的页码 page 和可选的每页数据量 size:
第一页申请:page : 1 // 以后页码,必选
size : 10 // 每页数据量,可选
响应:list:[{1},{2},{3}...,{10}] // 列表数据
total:100 // 数据总量
-----------------------------------
第二页申请:page : 2 // 以后页码,必选
size : 10 // 每页数据量,可选
响应:list:[{11},{12},{13}...,{20}] // 列表数据
total:100 // 数据总量
基于偏移的分页计划劣势在于简略易了解,而且可能反对点击 上一页 / 下一页 / 页码
按钮切换分页,实现传统 PC 列表的款式。但劣势也是很显著的,次要分为两个方面:
- 慢查问:SQL 查问语句在配合 offset、limit 查问时,如果 offset 偏移过大,会造成慢查问;
- 动态数据: 从前端展现一页数据到增量申请下一页数据之间会有一个时间差,如果这段时间内数据存在更新,则在申请下一页数据时可能会存在反复或缺失。我画了个示意图帮忙你了解为什么数据更新会引起反复或缺失:
数据反复的状况尽管能够通过前端去重的形式防止,但也会导致新一页展示的数据量参差不齐。那么,对于动态数据的场景,应该如何设计分页接口呢?
3. 基于游标分页
基于游标的分页设计实用于动态数据场景,其原理是依据已获取的最初一条数据的 ID 作为参数来申请下一页数据。例如:
# 获取第 curCursor 后的一页数据,每页数据量为 pageSize
select * from ... where ... and id > $curCursor order by id limit ($curPage - 1) * $pageSize, $pageSize
因而,前端在请求分页接口时,不再指定下一个页码 page,而是依据已接管的最初一条数据的 ID 来申请下一页数据:
第一页申请:cursor : 0 // 以后游标,必选
size : 10 // 每页数据量,可选
响应:list:[{1},{2},{3}...,{10}] // 列表数据
total:100 // 数据总量
-----------------------------------
第二页申请:cursor : 10 // 以后游标,必选
size : 10 // 每页数据量,可选
响应:list:[{11},{12},{13}...,{20}] // 列表数据
total:100 // 数据总量
为什么游标的计划能够防止数据反复或缺失呢?这是因为无论数据产生新增还是缩小时,基于游标的分页申请都获取该游标后续的一页数据,而基于偏移的分页申请是获取变更后数据排序后指定偏移地位的数据,这些数据在之前的申请中是否反复或缺失是无从得悉的。
当然了,基于游标的分页计划也存在局限性:
- 不能够反对点击
上一页 / 下一页 / 页码
按钮切换分页,App 根本不存在传统 PC 列表的操作,简直没有影响; - 只适宜简略排序场景,例如依照工夫排序或主键 ID 排序(主键 ID 通常是依照插入工夫递增的)
参考资料:
- 浅谈 APP 流式分页服务端设计
- 4 种 MySQL 分页查问优化的办法,你晓得几个?—— 程序员追风 著
- APP 后端分页设计 —— ScienJus 著
- 列表流、卡片流、瀑布流、Feed 流,你能分清它们的设计特点吗?—— Clippp 著
- mysql 查问时 offset 过大影响性能的起因和优化详解 —— 傲雪星枫 著
你的点赞对我意义重大!心愿大家能够一起探讨技术,找到气味相投的敌人,咱们下次见!