记一次大批量数据同一屏显示的性能问题

背景:

报表中有十几万条数据,前端开发使用iview中的控件进行显示,结果直接卡死。后来尝试只展示500条,也需要5s这样。而且内存飙升。虽然app的类似列表,只创建当前页面展示项是很正常的操作,但是由于对js不熟悉,所以一开始无处下手。

后来在搜索了各个网上的方法后,有一种可用,只是样式还需要自己完善。由于像app的list一样只创建当前展示的项,就算再多的数据也是秒现了。作者出处:https://bbs.csdn.net/topics/330126167

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>表格控件</title>

    <script src="a.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
    var data = [];
    //创建一30万条示例数据
    for (var i = 0; i < 300000; i++) {
        var row = { id: i, text: "text" + i,text1: "textsdfasdfasd1" + i,text2: "texadsfasdft2" + i,text3: "tedfadsfxt3" + i,text4: "texfadsfasdt4" + i,text5: "texdsfadsft5" + i };
        data.push(row);
    }

    //创建滚动条
    var scrbar = new Scrollbar();
    window.onload = function() {
        scrbar.CreateAt("divScroll");
        scrbar.setOptions({ total: 300000,size:1000 });
        scrbar.onScroll = function(pos) {
            ShowData(pos);
        }

        //获取模板
        var items = scrbar.getPageItems();
        var tpl = document.getElementById("trTpl");
        tpl.parentNode.removeChild(tpl);

        //仅创建所看到的几十行表格,所以自然快得多
        var list = document.getElementById("tblList");
        for (var i = 0; i < data.length && i < items; i++) {
            var nr = tpl.cloneNode(true);   //从模板行复制新行
            list.appendChild(nr);
        }
        ShowData(scrbar.getPos());
    }
    
    //根据滚动条,展示数据
    function ShowData(pos) {
        var n=scrbar.getPageItems();
        var rows=document.getElementById("tblList").rows;
        for (var i = 0; i < n; i++) {
            var row = rows[i];
            var item = data[i + pos];
            row.cells["tdID"].innerHTML = item["id"];
            row.cells["tdText"].innerHTML = item["text"];
			row.cells["tdText1"].innerHTML = item["text1"];
			row.cells["tdText2"].innerHTML = item["text2"];
			row.cells["tdText3"].innerHTML = item["text3"];
			row.cells["tdText4"].innerHTML = item["text4"];
			row.cells["tdText5"].innerHTML = item["text5"];
        }
    }
</script>
</head>
<body>
    <div id="divScroll" style="float:right">
    </div>
    <table border="1">
        <!--行标题-->
        <thead><tr>
            <th>ID</th>
            <th>Text</th>
			<th>Text1</th>
			<th>Text2</th>
			<th>Text3</th>
			<th>Text4</th>
			<th>Text5</th>
        </tr></thead>
        
        <!--数据展示区-->
        <tbody id="tblList"><tr id="trTpl">
            <td id="tdID"> </td>
            <td id="tdText"> </td>
			<td id="tdText1"> </td>
			<td id="tdText2"> </td>
			<td id="tdText3"> </td>
			<td id="tdText4"> </td>
			<td id="tdText5"> </td>
        </tr></tbody>
    </table>
</body>
</html>
function Scrollbar() {
    this.options = {
        total: 0,   //数据总数
        pos: 0,     //当前滚动位置
        itemSize: 20,  //单项尺寸
        size: 200  //控件尺寸
    };
}
Scrollbar.prototype = (function() {
    function setOptions(options) {
        for (var attr in options) {
            this.options[attr] = options[attr];
        }
        Refresh(this);
    }
    function Refresh(_this) {
        if (!_this.created) return;

        //设置控件高度
        _this.bar.style.height = _this.options.size + "px";

        //设置内容高度
        var ch = _this.options.total * _this.options.itemSize;
        _this.content.style.height = ch + "px";
    }
    //获取滚动位置
    function getPos() {
        var top = this.bar.scrollTop;
        var pos = parseInt(top / this.options.itemSize);
        return pos;
    }
    //每页可展示的数据数量
    function getPageItems() {
        return this.options.size / this.options.itemSize;
    }
    
    //滚动事件响应
    function OnScroll(_this) {
        var pos = _this.getPos();
        if (pos == _this.options.pos) return;
        _this.options.pos = pos;
        _this.onScroll(pos);
    }

    //滚动条创建
    function CreateAt(dom) {
        var _this = this;

        var bar = document.createElement("div");
        var content = document.createElement("div");
        bar.appendChild(content);

        bar.style.width = "19px";
        bar.style.overflowY = "scroll";
        bar.style.overflowX = "hidden";
        if (bar.attachEvent) {
            bar.attachEvent("onscroll", function() { OnScroll(_this); });
        }
        else {//firefox兼容
            bar.addEventListener("scroll", function() { OnScroll(_this); }, false);
        }
        content.style.backgroundColor = "white";
        content.style.width = "1px";

        this.bar = bar;
        this.content = content;

        if (typeof (dom) == "string") {
            dom = document.getElementById(dom);
        }
        dom.innerHTML = "";
        dom.appendChild(this.bar);
        this.created = true;
        Refresh(this);
    }

    return {
        setOptions: setOptions,
        CreateAt: CreateAt,
        getPos: getPos,
        getPageItems: getPageItems,
        onScroll: null  //模拟滚动条事件
    };
})();

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值