antd Select 数据量过大时卡顿问题解决

4,038 阅读2分钟

前几天在用antd Select的时候遇到的一个问题,觉得可以记录一下。

首先说一下问题吧,一开始写的时候也没考虑那么多,就是一个普普通通的select,开发时数据也没那么多,感觉很完美。后来发现居然被提单了,上验收环境一看,原来测试小姐姐创建了几千条用户,下拉展开的时候会感觉到有一点点卡顿,而且测试小姐姐用的是虚拟桌面,卡顿就比较明显。

既然是问题,那就得解决了,废话不多说,直接上代码

const [state, dispatchState] = useReducer(reducer, initialState);

const handleSearch = useCallback(
    debounce(value => searchValue(value), 300),
    [],
  );

const searchValue = value => {
    const allList = userList.filter(item => {
      return item.name.toLowerCase().indexOf(value.toLowerCase()) > -1;
    });
    dispatchState({
      type: 'search',
      payload: {
        scrollPage: 1,
        allUserList: allList,
        currentUserList: [...allList.slice(0, perPage)],
      },
    });
};

const handleScroll = e => {
    e.persist();
    const { target } = e;
    // scrollHeight:代表包括当前不可见部分的元素的高度
    // scrollTop:代表当有滚动条时滚动条向下滚动的距离,也就是元素顶部被遮住的高度
    // clientHeight:包括padding但不包括border、水平滚动条、margin的元素的高度
    const rmHeight = target.scrollHeight - target.scrollTop;
    const clHeight = target.clientHeight;
    // 当下拉框失焦的时候,也就是不下拉的时候
    if (rmHeight === 0 && clHeight === 0) {
      dispatchState({ type: 'stopScroll' });
    } else {
      // 滚动到底部
      if (rmHeight < clHeight + 5) {
        dispatchState({ type: 'scroll' });
      }
    }
};

const handleBlur = () => {
    dispatchState({
      type: 'clear',
      payload: initialState,
    });
};

总体的思路就是通过前端分页来分批渲染,当然如果后端接口支持分页也可以,默认渲染前100条,onPopupScroll下拉滚动到底部时再渲染第二个100条,搜索时也一样,默认展示搜索结果的前100条,滚动加载更多,另外搜索时用debounce做了防抖处理。

啊~写的都是啥啊,大概就这个意思,先就这样吧,代码只贴了相关的部分,部分变量定义未贴出来~