我试图使用knockout observable array在网页中显示大约5000条记录,这需要花费很多时间,
有没有办法处理这个没有分页?
请帮忙..
视图模型中的JS代码,数据来自gridData源中的ajax调用:
groupGrid.prototype.updateGrid = function (gridDataSource, groupGridOptions) { var self = this; self.ColumnName(groupGridOption.ColumnNameList); // List of column name available in the data source. self.gridData(gridDataSource); // taking time while executing this code self.totalRowCount(self.gridData().length); self.selectedItems.removeAll(); self.selectedRowCount(0); };
HTML代码:
sifriday.. 5
我最近在KO应用程序中一直在摔跤.我刚刚在这里添加了另一个问题的答案,并提出了一些想法:
Knockout订阅阻止了该页面
由此产生的,这是一个小提琴,表明你不需要太多延迟 - 这个演示有3000个项目,并为每个项目生成一个简单的div.根据上面链接的博客文章,这些项目首先在JS数组中构建,然后再转换为observableArray.所以我很确定在这个阶段你看到的性能问题很简单就是KO工作引起的DOM操作.
http://jsfiddle.net/HBYyL/1/
这并不能解决性能问题,但是如果循环遍历数千个项目并且它使用的模式可以确保在长KO操作之前出现加载微调器,则表明延迟可能是不可避免的,然后隐藏事后呢.所以它至少改善了用户体验.
确保您可以加载微调器:
// Show the spinner immediately... $("#spinner").show(); // ... by using a timeout. window.setTimeout(function() { ko.applyBindings(vm) }, 1)
隐藏微调器:
更新1:
我记得当我使用Opera在机顶盒上工作时,使用DOM操作构建UI时的旧技术.它的速度令人震惊,因此解决方案是将大块HTML存储为字符串,并通过设置innerHTML属性来加载字符串.单页应用的早期版本.无论如何,作为我在这个领域的持续摆弄的一部分,这里是一个jsfiddle,显示通过KO加载的5000个项目,但通过计算的中间html.
http://jsfiddle.net/9ZF3g/1/
换句话说,您从列表中计算HTML,并使用html绑定一次性设置它.我把这个例子设置为5000个项目,几乎是即时的.
巨大的缺点是它严重限制了你在每个项目内绑定所能做的事情......
更新2:
这是一个小提琴,显示了通过数组索引从项目链接回KO视图模型的一些外观.你可以使用这样的结构来做KO支持的大部分工作,但是你会失去一些魔力; 我想你必须自己编写更多代码.
http://jsfiddle.net/9ZF3g/2/
更新3:
这个小提琴显示了一种使用超时将每个项目逐个推入列表的技术.通过在推送操作之间设置超时,DOM逐项更新.因此整体渲染时间仍然很大,但用户可以立即获得反馈:
http://jsfiddle.net/rosenfeld/7TwcV/1/
更新4:
显示上述技术,但通过删除记录做一些有用的事情.
http://jsfiddle.net/9ZF3g/3/
2 个回答
我已经做了很多关于在浏览器中快速生成数据表的研究.使用
foreach
和text
绑定的标准Knockout方法非常慢.简化绑定代码可以实现一些改进,正如我的重复绑定所示.但生成数据表的最快方法是将其组合为JavaScript代码中的字符串,然后将innerHTML
其插入到DOM中.我的表绑定是如何做到这一点的一个例子.在您的情况下,组装数据表的自定义绑定将提供巨大的速度提升.这是我根据你的例子放在一起的自定义绑定:
ko.bindingHandlers.myDataTable = { init: function () { return { controlsDescendantBindings: true }; }, update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { var output = [], value = valueAccessor(), columns = ko.unwrap(value.columns), column1 = columns[0], column2 = columns[1], column3 = columns[2], data = ko.unwrap(value.data), dataLength = data.length, clickFunction = value.click; output.push('<table><tbody class="ngTBody">'); for (var i = 0; i < dataLength; ++i) { output.push('<tr class="ngdatarow"><td><span class="nameHeader" data-index="'); output.push(i + '">'); output.push(data[i][column1]); output.push('</span></td><td><span class="displayBlock">'); output.push(data[i][column2]); output.push('</span></td><td><span class="displayBlock">'); output.push(data[i][column3]); output.push('</span></td></tr>'); } output.push('</tbody></table>'); element.innerHTML = output.join(''); $(element).on('click', 'span.nameHeader', function (event) { var index = event.target.getAttribute('data-index'); if (index) { clickFunction(data[index], event); } }); } };为了比较,我把以下两个小提琴放在一起:
http://jsfiddle.net/mbest/csP6k/使用
foreach
.在我的计算机上渲染表需要2到3秒.http://jsfiddle.net/mbest/8cKuP/使用自定义绑定.渲染表格的速度快了近25倍.
我还创建了一个包含绑定和用法的示例,但它需要比上面的示例更长的时间,因为它必须设置5000个事件处理程序而不是一个.
click
ko.applyBindingsToDescendants
2023-01-01 15:27 回答手机用户2502920591_700我最近在KO应用程序中一直在摔跤.我刚刚在这里添加了另一个问题的答案,并提出了一些想法:
Knockout订阅阻止了该页面
由此产生的,这是一个小提琴,表明你不需要太多延迟 - 这个演示有3000个项目,并为每个项目生成一个简单的div.根据上面链接的博客文章,这些项目首先在JS数组中构建,然后再转换为observableArray.所以我很确定在这个阶段你看到的性能问题很简单就是KO工作引起的DOM操作.
http://jsfiddle.net/HBYyL/1/
这并不能解决性能问题,但是如果循环遍历数千个项目并且它使用的模式可以确保在长KO操作之前出现加载微调器,则表明延迟可能是不可避免的,然后隐藏事后呢.所以它至少改善了用户体验.
确保您可以加载微调器:
// Show the spinner immediately... $("#spinner").show(); // ... by using a timeout. window.setTimeout(function() { ko.applyBindings(vm) }, 1)隐藏微调器:
<div data-bind="template: {afterRender: hide}">
更新1:
我记得当我使用Opera在机顶盒上工作时,使用DOM操作构建UI时的旧技术.它的速度令人震惊,因此解决方案是将大块HTML存储为字符串,并通过设置innerHTML属性来加载字符串.单页应用的早期版本.无论如何,作为我在这个领域的持续摆弄的一部分,这里是一个jsfiddle,显示通过KO加载的5000个项目,但通过计算的中间html.
http://jsfiddle.net/9ZF3g/1/
换句话说,您从列表中计算HTML,并使用html绑定一次性设置它.我把这个例子设置为5000个项目,几乎是即时的.
巨大的缺点是它严重限制了你在每个项目内绑定所能做的事情......
更新2:
这是一个小提琴,显示了通过数组索引从项目链接回KO视图模型的一些外观.你可以使用这样的结构来做KO支持的大部分工作,但是你会失去一些魔力; 我想你必须自己编写更多代码.
http://jsfiddle.net/9ZF3g/2/
更新3:
这个小提琴显示了一种使用超时将每个项目逐个推入列表的技术.通过在推送操作之间设置超时,DOM逐项更新.因此整体渲染时间仍然很大,但用户可以立即获得反馈:
http://jsfiddle.net/rosenfeld/7TwcV/1/
更新4:
显示上述技术,但通过删除记录做一些有用的事情.
http://jsfiddle.net/9ZF3g/3/
2023-01-01 15:28 回答啊啊毛撰写答案