首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从socket.io高效地用动态数据实时渲染反应元件

如何从socket.io高效地用动态数据实时渲染反应元件
EN

Stack Overflow用户
提问于 2015-11-25 03:56:55
回答 1查看 2.6K关注 0票数 0

我的首页是由React + Flux制作的,它将script data发送到后端nodejs服务器。

script data是一个Array,它包含linux参数(超过100000)。当接收到后端时,它将执行linux命令.

举个例子:

代码语言:javascript
复制
cat ~/testfile1
cat ~/testfile2
          .
          .
          .
(100000 times ...etc)

当后端完成一个linux命令时,我可以将读取的内容保存到result data中。因此,socket.io将把result data发送到前端.

我想从我的网页上实时获得result data,所以我在下面的项目中做了一些工作。

我的React component代码:

代码语言:javascript
复制
import React from 'react';

import AppActions from '../../../actions/app-actions';
import SocketStore from '../../../stores/socket-store';
import ResultStore from '../../../stores/result-store';

function getSocket () {
    return SocketStore.getSocket();
}

function getResult () {
    return ResultStore.getResultItem();
}

class ListResultItem extends React.Component {
    constructor () {
        super();
    }
    render () {
        return <li>
                {this.props.result.get('name')} {this.props.result.get('txt')}
            </li>;
    }
}

class ShowResult extends React.Component {
    constructor () {
        super();
        this.state = {
            socket: getSocket(),
            result: getResult()
        };
    }
    componentWillMount () {
        ResultStore.addChangeListener(this._onChange.bind(this));
    }
    _onChange () {
        this.setState({
            result: getResult()
        });
    }
    render () {
        return <div>
                <ol>
                    {this.state.result.map(function(item, index) {
                        return <ListResultItem key={index} result={item} />;
                    })}
                </ol>
            </div>;
    }
    componentDidMount () {
        this.state.socket.on('result', function (data) {
            AppActions.addResult(data);
        });
    }
}

我的Flux store (ResultStore)代码:

代码语言:javascript
复制
import AppConstants from '../constants/app-constants.js';
import { dispatch, register } from '../dispatchers/app-dispatcher.js';
import { EventEmitter } from 'events';
import Immutable from 'immutable';

const CHANGE_EVENT = 'changeResult';

let _resultItem = Immutable.List();

const _addResult = (result) => {
    let immObj = Immutable.fromJS(result);

    _resultItem = _resultItem.push(immObj);
}

const _clearResult = () => {
    _resultItem = _resultItem.clear();
}

const ResultStore = Object.assign(EventEmitter.prototype, {
    emitChange (){
        this.emit( CHANGE_EVENT );
    },
    addChangeListener (callback) {
        this.on(CHANGE_EVENT, callback);
    },
    removeChangeListener (callback) {
        this.removeListener(CHANGE_EVENT, callback);
    },
    getResultItem () {
        return _resultItem;
    },
    dispatcherIndex: register(function (action) {
        switch (action.actionType) {
            case AppConstants.ADD_RESULT:
                _addResult(action.result);
            break;
            case AppConstants.CLEAR_RESULT:
                _clearResult();
            break;
        }

        ResultStore.emitChange();
    })
});

但是,在呈现1000多个数据之后,页面将变得非常慢。如何提高渲染性能?我需要持续执行linux脚本超过3天。有什么解决办法吗?谢谢~

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-25 20:10:30

是否需要在屏幕上呈现所有数据?如果没有,那么就有几种方法可以减少可见数据的数量。

过滤/搜索

您可以提供一个搜索/筛选组件来补充列表,并创建一个谓词函数,用于确定每个项是否应该呈现。

代码语言:javascript
复制
<PredicateList>
  <Search />
  <Filter />
  {this.state.result
     .filter(predicate)
     .map(function(item, index) {
       return <ListResultItem key={index} result={item} />;
     })
  }
</PredicateList>

懒惰负载

只有当需要时才加载这些项目。您可以通过跟踪项目是否会出现在屏幕上,或者鼠标是否在屏幕上,来确定是否需要项目。

代码语言:javascript
复制
var Lazy = React.createClass({
  getInitialState: function() {
    return { loaded: false };
  },
  load: function() {
    this.setState({ loaded: true });
  },
  render: function() {
    var loaded = this.state.loaded,
        component = this.props.children,
        lazyContainer = <div onMouseEnter={this.load} />;

    return loaded ?
      component
      lazyContainer;
  }
});

然后简单地将您的数据项包装在这些Lazy包装器中,以便在被请求时呈现它们。

代码语言:javascript
复制
<Lazy>
  <ListResultItem key={index} result={item} />
</Lazy>

这确保只看到用户所需的数据。您还可以改进加载触发器,以便在更复杂的情况下工作,例如组件在屏幕上显示超过2秒时。

分页

最后,最后也是最尝试和测试的方法是分页。为可以一次显示的多个数据项选择一个限制,然后允许用户以块的形式浏览数据集。

代码语言:javascript
复制
var Paginate = React.createClass({
  getDefaultProps: function() {
    return { items: [], perPage: 100 }; 
  },
  getInitialState: function() {
    return { page: 0 };
  },
  next: function() {
    this.setState({ page: this.state.page + 1});
  },
  prev: function() {
    this.setState({ page: this.state.page - 1});
  },
  render: function() {
    var perPage = this.props.perPage,
        currentPage = this.state.page,
        itemCount = this.props.items.length;

    var start = currentPage * perPage,
        end = Math.min(itemCount, start + perPage);

    var selectedItems = this.props.items.slice(start, end);

    return (
      <div className='pagination'>
        {selectedItems.map(function(item, index) {
          <ListResultItem key={index} result={item} />
        })}
        <a onClick={this.prev}>Previous {{this.state.perPage}} items</a>
        <a onClick={this.next}>Next {{this.state.perPage}} items</a>
      </div>
    );
  }
});

这些只是管理以有效方式呈现大量数据的实现的非常粗略的示例,但希望它们对您实现自己的解决方案有足够的意义。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33908246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档