【问题标题】:Why is Javascript causing my page to crash?为什么 Javascript 会导致我的页面崩溃?
【发布时间】:2014-08-23 09:01:33
【问题描述】:

所以我正在使用 MVC 4 C#/Razor,并且正在开发一个使用 SlickGrid 来显示网格数据的页面。一切正常,除非我尝试使用它来显示大量数据(大约 100 万行)。

当这种情况发生时,它似乎做得很好,直到它即将完成。就在似乎要完成所有数据加载的时候,网页崩溃了。我使用 getJSON 从 SQL 数据库中提取数据。我按列进行,分批 300000 条记录。我曾尝试使用 Chrome 内存分析工具,但找不到任何有用的东西。下面是一些代码sn-ps:

    function pullAllGridData(tableName, colArray)
    {
        for (var i = 0; i < colArray.length; i++)
        {
            fetchColumn(tableName, colArray[i], 0);
        }
    }


    function fetchColumn(tableName, fieldName, startAt)
    {
        $.getJSON('/WIMenu/GetTableData', { tableName: tableName, fieldName: fieldName }, function (data)
        {
            if (data.slice(-1) !== '~')
            {
                var startPass = populateSlickData(data, fieldName, startAt);
                colStatus[fieldName] = true;
                if (loadFirstBatch())
                { populateGrid(); }
                fetchColumn(tableName, fieldName, startPass);
            }
            else
            {
                data = data.slice(0, -1);
                populateSlickData(data, fieldName, startAt);
                colStatus[fieldName] = true;
                if (loadFirstBatch())
                { populateGrid(); }
            }
        });
    }

    function populateSlickData(input, fieldName, startAt)
    {
            var output = startAt;
            var valueArray = input.split('|');
            output += valueArray.length;
            if (!isInBlackList(fieldName, tableName))
            {
                var datatype = columns[getColumnIndex(fieldName)].datatype;
                var startIndex = startAt;
                var endIndex = startAt + valueArray.length;
                var counter = 0;
                alert(fieldName + ': startIndex: ' + startIndex + ' endIndex: ' + endIndex + ' count: ' + endIndex-startIndex);
                for (var x = startIndex; x < endIndex; x++)
                {
                    if (!slickdata[x])
                    { slickdata[x] = {}; }
                    if (valueArray[x - startAt] == 'null') { valueArray[x - startAt] = ''; }
                    if (datatype == 'System.DateTime')
                    {
                        if (valueArray[x-startAt] !== '')
                        {
                            var date = new Date(valueArray[x - startAt]);
                            valueArray[x - startAt] = (date.getMonth() + 1) + '-' + date.getDate() + '-' + date.getFullYear();
                        }
                    }
                    else if (datatype == 'System.Decimal' || datatype == 'System.Int32' || datatype == 'System.Int16' || datatype == 'System.Int64')
                    {
                        valueArray[x - startAt] = parseFloat(valueArray[x - startAt]);
                    }
                    slickdata[x][fieldName] = valueArray[x - startAt];
                    counter++;
                }
            }
            currentColumn = fieldName;

        filteredData = slickdata;
        return output;
    }

fetchColumn 使用递归来不断获取列数据,直到所有数据都被接收。 populateGrid 方法只是将 SlickGrid 对象同步到 slickdata 对象。我的目标是找出页面崩溃的原因并了解如何修复它。

通过使用警报,它似乎在某些时候卡在 populateSlickData 方法的 for 循环中,我不知道为什么。我已经尝试打印用于索引的数据,但似乎一切正常。

【问题讨论】:

  • 真的很有意思,递归真的有必要吗?只执行一个 ajax 调用并返回所有内容不是更有效吗?
  • @gustavodidomenico - 我在示例中看不到任何递归......确实有回调再次调用 out 函数,但我不会称之为递归。
  • 旁注:在其他职业中,它可能被称为wing load test...事实上,如果您对其施加足够的负载,任何软件/硬件都会损坏。有些更抗拒,但真的有 100 万条记录可以在浏览器中显示?
  • 我认为人们只见树木不见森林。他同时将一百万行数据加载到内存中。
  • 一百万行,来自 JSON,在浏览器中。当然,服务器可以处理该负载,但即使浏览器可以保存那么多数据/许多对象,渲染它也不会顺利进行。

标签: c# asp.net-mvc slickgrid


【解决方案1】:

您不能将一百万行数据放入内存中,并期望任何网页除了缓慢爬行或确实崩溃之外会做任何事情。这就是网格 分页 的用途,再加上按需 ajax。您的网格应该只在页面更改时提取显示当前数据页面所需的数据。您不应该提前加载所有内容。

这是 SlickGrid github 网站上的一个示例:http://mleibman.github.io/SlickGrid/examples/example4-model.html

这里有更多信息:https://github.com/teleological/slickback/wiki/Pagination

【讨论】:

  • 嗯,我认为分页是在 SlickGrid 内部内置的......我想你可能让我走上了正确的轨道。
  • 分页内置在 slickgrid 中,但您需要将分页和按需加载相结合。如果您将一万行加载到内存中,则可以进行分页,但是当您一次只显示 50 行时,这仍然是内存中的一万行。您希望网格仅在切换页面时使用 ajax。你不应该提前加载它们:)
  • 所以,这里的最终目标是建立一个网格,允许用户将数据过滤成他们实际观察和使用的更少量的数据。您所说的似乎只是 slickdata 对象的大小导致页面崩溃(如果我误解了您,请纠正我)。所以,如果我错了,再次纠正我,你是说设置我的 JSON/Web 服务器交互以仅在用户过滤或滚动时从服务器检索数据?
  • 我想我将完全重组整个事情,使其以浏览器实际可以处理的方式运行。这个答案是我大修的基础。谢谢@x0n!
  • @peppajack 是的 - 这是您加载到内存中的数据的绝对大小导致浏览器崩溃。诚然,浏览器不应该崩溃,但内存不足是一个好方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-03
相关资源
最近更新 更多