React 的 Swiper 替代方案:按你真正想摆脱的东西来选
没有人是因为 Swiper 不好才离开它的——它是目前功能最完整的滑块库。人们离开的原因是体积(未加模块前就有 ≈40 kB)、要继承它的 DOM 和 CSS,或者是因为自己的“滑块”其实从来就不是幻灯片。每一种诉求都有各自最合适的答案。
| Swiper | Embla | keen-slider | react-horizontal-scrolling-menu | |
|---|---|---|---|---|
| 包体积(核心,min+gzip) | ≈40 kB | ≈8 kB | ≈7 kB | ≈5.7 kB |
| 模型 | 幻灯片,内置一切 | 幻灯片,无头 | 幻灯片,精简引擎 | 原生滚动行中的项目 |
| 特效与模块 | 现有方案中最丰富 | 插件 / 自行实现 | 部分内置 | 没有——提供方案而非特效 |
| 接管手势层 | 是(transform) | 是(transform) | 是(transform) | 否——由浏览器滚动 |
| 逐项可见性 | 幻灯片索引事件 | 幻灯片索引事件 | 幻灯片索引事件 | 内置(useIsVisible) |
| 适合替换的情况 | — | 反正你会自己写所有样式 | 需要精简滑块,且不想被锁定在 React | “幻灯片”其实是可点击的项目 |
体积均为核心部分的近似值——Swiper 的体积会随导入的模块增长,这也意味着精简后的 Swiper 构建其实比它的“名声”要小。
摆脱体积负担:Embla 或 keen-slider
如果你的产品确实是一个真正的轮播图——带吸附对齐、一次展示一页幻灯片——这些轻量引擎几乎可以直接替换:
- Embla(≈8 kB):无头架构,物理效果出色,拥有一等公民级别的 React hook,也是 shadcn/ui 轮播组件底层使用的引擎。所有标记和 CSS 都由你自己提供——这正是它的意义所在。
- keen-slider(≈7 kB):一个精简的、与框架无关的引擎,适合同一个滑块既要用在 React 又要用在非 React 场景的情况。
两者都保留了基于 transform 的幻灯片模型,因此渐隐或 coverflow 之类的特效仍需自行实现——如果你依赖这些特效,坦白说精简后的 Swiper 构建比重新实现它们更划算。
摆脱幻灯片模型:菜单形态的情况
另一条退路适用于那些 Swiper 的幻灯片语义从一开始就不承重的场景:分类行、logo 墙、标签栏、筛选标签栏、商品栏。破绽就在于像 slidesPerView: 'auto' 加上 freeMode: true 这样的配置组合——这正是在让 Swiper 假扮原生滚动。
react-horizontal-scrolling-menu(≈5.7 kB)就是那种原生滚动,外加浏览器本身不提供的部分:逐项可见性、滚动到指定项、边缘感知箭头,以及不会破坏点击的拖拽。没有特效,没有吸附对齐,没有手势模拟——可查看 Netflix 行、标签栏 和 筛选标签栏 页面,或 完整对比表。
双向的一句公道提醒
为了省体积而放弃 Swiper,结果却要自己手工实现自动播放、分页、无障碍播报和各种特效,这正是一个 40 kB 的问题演变成一个人月级问题的过程。只有当你的用法真的只是 Swiper 的一个子集时,才该换成更轻量的引擎;只有当幻灯片语义从一开始就是伪装出来的时,才该换成滚动菜单。如果你确实用到了 Swiper 的深度功能,那就继续用 Swiper。