-
-
Notifications
You must be signed in to change notification settings - Fork 47.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
关于Transfer组件的性能问题的建议 #2860
Comments
如果合适的话,可以直接引入 Lazyload 。 |
感觉 这个组件有两个主要属性,分别是
然后现在 @codering 的写法,渲染出来应该是 现阶段可以推荐用户使用 LazyLoad 优化性能,但不集成进 antd。 |
还是有两个方案可以实现惰性渲染:
|
源码发现 import React, {Component} from 'react'
import Animate from 'rc-animate'
import {Transfer, Checkbox} from 'antd'
import Search from 'antd/lib/transfer/search'
import LazyLoad from 'react-lazy-load'
function isRenderResultPlainObject(result) {
return result && !React.isValidElement(result) &&
Object.prototype.toString.call(result) === '[object Object]';
}
export default class LazyTransfer extends Component {
constructor(props) {
super(props);
this.state = {
mounted: false,
};
}
componentDidMount() {
this.timer = setTimeout(() => {
this.setState({
mounted: true,
});
}, 0);
}
componentWillUnmount() {
clearTimeout(this.timer);
}
render() {
const renderBody = (props) => {
const {dataSource, render, showSearch, prefixCls, filter, filterOption,
handleFilter,handleClear, handleSelect, checkedKeys, searchPlaceholder, notFoundContent } = props
const matchFilter = (filterText, item, text) => {
if (filterOption) {
return filterOption(filterText, item);
}
return text.indexOf(filterText) >= 0;
}
const _handleSelect = (selectedItem) => {
const result = checkedKeys.some((key) => key === selectedItem.key);
handleSelect(selectedItem, !result);
}
const showItems = dataSource.map(item => {
const renderResult = render(item);
let renderedText;
let renderedEl;
if (isRenderResultPlainObject(renderResult)) {
renderedText = renderResult.value;
renderedEl = renderResult.label;
} else {
renderedText = renderResult;
renderedEl = renderResult;
}
if (filter && filter.trim() && !matchFilter(filter, item, renderedText)) {
return null;
}
return (
<LazyLoad height={30} key={item.key} >
<li onClick={() => _handleSelect(item)} key={item.key} title={renderedText}>
<Checkbox checked={checkedKeys.some(key => key === item.key)} />
<span>{renderedEl}</span>
</li>
</LazyLoad>
);
}).filter(item => !!item);
return (
<div className={showSearch ? `${prefixCls}-body ${prefixCls}-body-with-search` : `${prefixCls}-body`}>
{showSearch ? <div className={`${prefixCls}-body-search-wrapper`}>
<Search prefixCls={`${prefixCls}-search`}
onChange={handleFilter}
handleClear={handleClear}
placeholder={searchPlaceholder || '请输入搜索内容'}
value={filter}
/>
</div> : null}
<Animate component="ul"
transitionName={this.state.mounted ? `${prefixCls}-highlight` : ''}
transitionLeave={false}
>
{showItems.length > 0
? showItems
: <div className={`${prefixCls}-body-not-found`}>{notFoundContent || '列表为空'}</div>}
</Animate>
</div>
)
}
return <Transfer {...this.props} body={renderBody} />
}
} |
要是把checkbox换掉,比如我现在就把它简单处理成 |
对一个 UI 库而言,这样太坑了吧,交互和样式都被改了。。 |
加一个 |
已经有这个 API 了。 |
感觉楼主的建议还是可行的,默认集成 react-lazy-load ,并加一个 itemHeight (默认 32px)用于配合自定义内容。我来搞搞试试。 |
其实与 @yesmeck #3715 (comment) 提到的 |
This thread has been automatically locked because it has not had recent activity. Please open a new issue for related bugs and link to relevant comments in this thread. |
当Transer组件内维护的数据达到1000左右,初次渲染及checkbox的操作会感觉到明显的卡顿, 尽管曾经优化过(#2112) 。
然后今天我试着用react-lazy-load,看下能否提升性能
把 transfer/list.jsx#L165 简单改成
在chrome 51.0.2704.79 Ubuntu 16.04 (64-bit) 测试2000条数据, 发现性能可以提升1倍(无具体性能数据,只是从体验上)
所以我在想antd或rc可否内部实现一个lazyload组件,对可能会有大数据量展示的组件提供lazy属性?
The text was updated successfully, but these errors were encountered: