1.0.0 • Published 6 years ago

better-scroller v1.0.0

Weekly downloads
3
License
MIT
Repository
github
Last release
6 years ago

移动端高性能滚动组件

基于infinite-scroller改进、封装

当页面元素过多时,内存占用会持续增加,页面重绘的时候占用的CPU资源也会随之增大,页面频繁滚动或者重排的时候就会出现明显的卡顿。 此组件可以有效解决海量数据列表动态加载时的性能问题,可以在性能较差的设备上流畅地滚动,帧率能接近理想化的60FPS(同等条件下iScroll的无限加载版本只能达到30FPS左右)。 可以动态加载任何形式的UI节点,不要求节点具有相同的结构或者尺寸,可以随意定制每个节点的UI。demo

实用场景

  • 需要大规模动态加载数据的
  • 想要通过墓碑元素改善加载视图
  • 不需要兼容IE9-的应用

实现原理

  • 通过will-change: transform;开启元素3D加速(目前chrome、safari、firefox支持)
  • 通过contain: layout;开启元素的(目前仅chrome支持)
  • 通过节点的复用,维持页面的节点数量在一个设定的范围,降低内存占用,减少页面重绘、重排的性能开销
  • 通过墓碑节点实现更友好的数据加载站位显示
  • 数据更新导致滚动位置变化的时候通过记录锚点元素实现滚动定位

改进

  • 去除第三方依赖(摘除es6-promise.js依赖,减少代码量,降低接入成本,也有利于后期兼容更低版本浏览器)
  • 解决原生Promise性能问题(提升2~3倍,详情
  • resize事件做防抖操作,对scroll事件做节流操作
  • 多种接入方式的支持(支持全局、ES6模块、AMD、CMD方式接入)

使用

  • npm包引用
  # 安装模块
  # @sea https://www.npmjs.com/package/better-scroller
  npm i -S better-scroller
  // ES6 使用方式
  import BetterScroller from 'better-scroller';
  
  // cmd 使用方式
  // let BetterScroller = require('better-scroller');
  • 全局引用
  <script src="//j1.58cdn.com.cn/git/scroller/index.min.js"></script>
  • 模块加载器引用
  // cmd 使用方式(如seajs)
  let BetterScroller = require('dist/index.min.js');

  // amd 使用方式(如requirejs)
  requirejs(['dist/index.min.js'], function(BetterScroller) {
    // TODO
  });
  • 调用
<div id="templates">
  <li class="item" data-id="{{id}}">
    <img class="avatar" width="48" height="48">
    <div class="bubble">
      <p></p>
      <img width="300" height="300">
      <div class="meta">
        <time class="posted-date"></time>
      </div>
    </div>
  </li>
  
  <li class="item tombstone" data-id="{{id}}">
    <img class="avatar" width="48" height="48" src="images/unknown.jpg">
    <div class="bubble">
      <p></p>
      <p></p>
      <p></p>
      <div class="meta">
        <time class="posted-date"></time>
      </div>
    </div>
  </li>
</div>
<ul id="scroll-container"></ul>
  #templates {display: none}
  
  #scroll-container {
    position: absolute;
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
    overflow-x: hidden;
    overflow-y: scroll;
    box-sizing: border-box;
    
    /*safari上开启原生滚动*/
    -webkit-overflow-scrolling: touch;
    /*chrome重隔离优化*/
    contain: layout;
    /*开启3D加速*/
    will-change: transform;
  }
  
  .item {
    display: flex;
    padding: 10px 0;
    width: 100%;
    contain: layout;
    will-change: transform;
  }
  let scroller = new BetterScroller(
    document.querySelector('#scroll-container'),
    new ContentSource())

TODO

  • 源码中TODO的问题
  • issue中一些问题
  • 上拉加载数据
  • IE8-兼容性问题
1.0.0

6 years ago

0.3.0

6 years ago

0.2.0

6 years ago

0.1.0

6 years ago