semi-design icon indicating copy to clipboard operation
semi-design copied to clipboard

[BUG] semi Table 在虚拟化时,面对渲染成本较高的组件会出现白色的空行,请教有无好的解法能给用户相对好一些的体验

Open coding-ax opened this issue 1 year ago • 2 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Which Component

Table

Semi Version

latest

Current Behavior

20231221201801_rec_

Expected Behavior

能够有一个占位的图片?总之是希望能让用户体验好一点

Steps To Reproduce

  1. Table with virtualized
  2. expensive column render components
  3. scrolling your table

ReproducibleCode

import React, { useRef } from 'react';
import { Table, Avatar, Button } from '@douyinfe/semi-ui';
import * as dateFns from 'date-fns';

const DAY = 24 * 60 * 60 * 1000;

const columns = [
    {
        title: '标题',
        dataIndex: 'name',
        width: 200,
        fixed: true,
        render: (text, record, index) => {
            return <div>{text}</div>;
        },
        filters: [
            {
                text: 'Semi Design 设计稿',
                value: 'Semi Design 设计稿',
            },
            {
                text: 'Semi D2C 设计稿',
                value: 'Semi D2C 设计稿',
            },
        ],
        onFilter: (value, record) => record.name.includes(value),
    },
    {
        title: '大小',
        dataIndex: 'size',
        width: 150,
        sorter: (a, b) => (a.size - b.size > 0 ? 1 : -1),
        render: text => `${text} KB`,
    },
    {
        title: '所有者',
        dataIndex: 'owner',
        render: (text, record, index) => {
            for(let i = 0; i < 100000000; i ++ ) {}
            return (
                <div>
                    <Avatar size="small" color={record.avatarBg} style={{ marginRight: 4 }}>
                        {typeof text === 'string' && text.slice(0, 1)}
                    </Avatar>
                    {text}
                </div>
            );
        },
    },
    {
        title: '更新日期',
        dataIndex: 'updateTime',
        fixed: 'right',
        width: 150,
        sorter: (a, b) => (a.updateTime - b.updateTime > 0 ? 1 : -1),
        render: value => {
            return dateFns.format(new Date(value), 'yyyy-MM-dd');
        },
    },
];

const getData = () => {
    const data = [];
    for (let i = 0; i < 1000; i++) {
        const isSemiDesign = i % 2 === 0;
        const randomNumber = (i * 1000) % 199;
        data.push({
            key: '' + i,
            name: isSemiDesign ? `Semi Design 设计稿${i}.fig` : `Semi D2C 设计稿${i}.fig`,
            owner: isSemiDesign ? '姜鹏志' : '郝宣',
            size: randomNumber,
            updateTime: new Date().valueOf() + randomNumber * DAY,
            avatarBg: isSemiDesign ? 'grey' : 'red',
        });
    }
    return data;
};

const data = getData();

function VirtualizedFixedDemo() {
    let virtualizedListRef = useRef();
    const scroll = { y: 400, x: 900 };
    const style = { width: 750, margin: '0 auto' };

    return (
        <>
            <Button onClick={() => virtualizedListRef.current.scrollToItem(100)}>Scroll to 100</Button>
            <Table
                pagination={false}
                columns={columns}
                dataSource={data}
                scroll={scroll}
                style={style}
                virtualized
                getVirtualizedListRef={ref => (virtualizedListRef = ref)}
            />
        </>
    );
}

render(VirtualizedFixedDemo);

Environment

- OS:OSX
- browser:Chrome

Anything else?

No response

coding-ax avatar Dec 21 '23 12:12 coding-ax

这个问题出现的原因是单元格的渲染比较复杂,解决这个问题的方式是,根据渲染情况,给行渲染做个占位,比如0.5s展示占位,0.5s后渲染真实数据。这个自己实现就好了。

shijiatongxue avatar Dec 22 '23 09:12 shijiatongxue

这个问题出现的原因是单元格的渲染比较复杂,解决这个问题的方式是,根据渲染情况,给行渲染做个占位,比如0.5s展示占位,0.5s后渲染真实数据。这个自己实现就好了。

react-window 底层支持一个 isScrolling 参数,看起来是你想要的。https://react-window.vercel.app/#/examples/list/scrolling-indicators

不过目前这个参数 Semi Table 里面没有消费。

image

shijiatongxue avatar Dec 22 '23 09:12 shijiatongxue