We are experiencing a crippling memory leak using a Kendo Grid. We are using the knockout-kendo.js library to bind a Kendo Grid to an existing Knockout observable array such that the grid responds to row insertions and removals in the array.
Attached is a stand-alone example page that demonstrates the issue. Basically, this sample binds an array of objects with observable fields, and a button removes the first item in the array. If you load it you should see the grid of test values. If you keep pressing the button and watch your Task Manager, you should see the memory usage of the browser slowly climbing (we've confirmed that it happens in IE10, IE11, and Firefox). The grid in the real app is bigger so the memory leak gets big enough to crash IE10 after a relatively small number of operations.
This is a high-priority issue, so any help you can give
us would be greatly appreciated!
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="Scripts/jquery-1.8.2.js"></script>
<script src="Scripts/kendo.all.js"></script>
<script src="Scripts/knockout-3.2.0.js"></script>
<script src="Scripts/knockout-kendo.js"></script>
</head>
<body>
<script id="Row-Template" type="text/html">
<tr data-uid="#: uid #">
<td data-bind="text: col1"></td>
<td data-bind="text: col2"></td>
<td data-bind="text: col3"></td>
<td data-bind="text: col4"></td>
<td data-bind="text: col5"></td>
<td data-bind="text: col6"></td>
<td data-bind="text: col7"></td>
<td data-bind="text: col8"></td>
<td data-bind="text: col9"></td>
</tr>
</script>
<div>
<button data-bind="click: OnClick">Remove One</button>
</div>
<div data-bind="kendoGrid:
{
editable: false,
data: Rows,
rowTemplate: 'Row-Template',
useKOTemplates: true,
sortable: false,
scrollable: true,
columns:
[
{ title: 'col1', width: '50px' },
{ title: 'col2', width: '50px' },
{ title: 'col3', width: '50px' },
{ title: 'col4', width: '50px' },
{ title: 'col5', width: '50px' },
{ title: 'col6', width: '50px' },
{ title: 'col7', width: '50px' },
{ title: 'col8', width: '50px' },
{ title: 'col9', width: '50px' }
]
}">
</div>
<script type="text/javascript">
function ViewModel() {
var self = this;
var rows = [];
for (var i = 0; i < 100; i++) {
rows.push({ col1: ko.observable("test"), col2: ko.observable("test"), col3: ko.observable("test"), col4: ko.observable("test"), col5: ko.observable("test"), col6: ko.observable("test"), col7: ko.observable("test"), col8: ko.observable("test"), col9: ko.observable("test")});
}
self.Rows = ko.observableArray(rows);
self.OnClick = function () {
self.Rows.remove(self.Rows()[0]);
};
}
ko.applyBindings(new ViewModel());
</script>
</body>
</html>