You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS中map遍历大量数据加载慢导致页面无响应如何解决?

问题根因

你遇到的页面无响应不是map函数执行慢,是一次性向DOM树插入14万+option节点,完全阻塞了浏览器主线程的渲染、交互逻辑,才会触发无响应提示。

实现加载状态+性能优化方案

首先要避免一次性渲染全量节点,同时增加加载状态标识,具体改造如下:

1. 状态调整

在state中新增loading状态标识加载进度,同时不要在constructor初始化时就加载全量城市数据到state,避免阻塞组件初始化。

2. 渲染逻辑优化(二选一即可)

  • 分片渲染:将全量数据拆分为多段,每段渲染1000-2000条,利用浏览器空闲时间分段插入DOM,不会阻塞主线程,过程中显示加载提示
  • 虚拟滚动:仅渲染当前可视区域内的节点(一般几十条),滚动时动态替换节点内容,是大数据量列表渲染的最优方案

3. 附加优化建议

14万+的下拉选项用户无法直接使用,建议增加输入搜索筛选功能,仅渲染匹配搜索关键词的少量节点,性能和体验都会大幅提升。

改造后参考代码
export default class addGy extends Component {
    constructor(props){
        super(props);
        // 全量城市数据存在实例上,不进state避免不必要的渲染
        this.allCities = City.getAllCities();
        this.state = {
          countries: Country.getAllCountries(),
          states: State.getAllStates(),
          cities: [], // 初始为空,逐步加载
          loading: true // 加载状态标识
        }
        // 分片渲染配置:每次渲染2000条,可根据实际情况调整大小
        this.chunkSize = 2000;
        this.renderIndex = 0;
    }
    
    componentDidMount() {
      navigator.geolocation.getCurrentPosition(function(position) {
        console.log(position)
        console.log("Latitude is :", position.coords.latitude);
        console.log("Longitude is :", position.coords.longitude);
      });
      console.log(this.allCities)
      // 启动分片渲染
      this.chunkRender();
    }
    
    // 分片渲染逻辑
    chunkRender = () => {
      const nextIndex = Math.min(this.renderIndex + this.chunkSize, this.allCities.length);
      // 取当前批次的城市数据
      const chunkCities = this.allCities.slice(this.renderIndex, nextIndex);
      this.setState(prev => ({
        cities: [...prev.cities, ...chunkCities]
      }), () => {
        this.renderIndex = nextIndex;
        if (nextIndex < this.allCities.length) {
          // 还有未渲染数据,下一帧继续渲染
          requestAnimationFrame(this.chunkRender);
        } else {
          // 全部渲染完成,关闭加载状态
          this.setState({ loading: false })
        }
      })
    }
      
    render() {
        return (
          <Form>
            <Row className="mb-3">
              <Form.Group as={Col} controlId="formGridCity">
                <Form.Label>City {this.state.loading && '(加载中...)'}</Form.Label>
                <Form.Control as="select" multiple>
                  {
                    this.state.cities.map(ele=>{
                      return (
                        <option 
                          value={`${ele.name}`} 
                          className="d-inline mx-2 col-sm-5" 
                          onClick={({target}) => target.classList.toggle('bg-primary')}
                          key={ele.name} // 必须加唯一key,避免React重复渲染损耗性能
                        >
                            {ele.name}
                       </option>
                      )
                    })
                  }
                </Form.Control>
              </Form.Group>
            </Row>
            <Button variant="primary" type="submit" disabled={this.state.loading}>
              {this.state.loading ? '城市数据加载中' : 'Submit'}
            </Button>
          </Form>
        );
    }
}

内容的提问来源于stack exchange,提问作者streak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:57:02