We have a dynamic web site which uses the Kendo grid to continually update statistics. While leaving a grid displayed and updating and while using aggregates, the grid will eventually consume enough memory to kill the browser window. This is due to the fact that DOM elements are being orphaned when the grid refreshes new data. If a memory snapshot is taken in the developer pane of the browser, you will notice many HTMLDivElements with class "k-grid-footer-wrap" and "k-grid-footer-locked" are still in memory but not attached to the DOM. Each element only takes 92 bytes, but they accumulate over time and are never released. The problem is reproducible and shown in the below code.
Removing the aggregate data and the footer templates from the kendo initialization causes the memory to remain stable.
Please advise. Thanks.
<!DOCTYPE html>
<
html
lang
=
"en"
dir
=
"ltr"
xmlns
=
"http://www.w3.org/1999/xhtml"
>
<
head
>
<
title
>Realtime Table</
title
>
<
meta
charset
=
"utf-8"
>
<
meta
http-equiv
=
"X-UA-Compatible"
content
=
"IE=edge"
/>
<
meta
http-equiv
=
"Cache-Control"
content
=
"no-cache"
>
<
meta
http-equiv
=
"Pragma"
content
=
"no-cache"
>
<
meta
http-equiv
=
"Expires"
content
=
"-1"
>
<
meta
name
=
"viewport"
content
=
"width=device-width, initial-scale=1.0"
/>
<
link
rel
=
"stylesheet"
href
=
"http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"
type
=
"text/css"
/>
<
link
rel
=
"stylesheet"
href
=
"/OptiRampWeb5/Css/kendo.bootstrap.min.css"
type
=
"text/css"
/>
<
link
rel
=
"stylesheet"
href
=
"/OptiRampWeb5/Css/kendo.common-office365.min.css"
type
=
"text/css"
>
<
link
rel
=
"stylesheet"
href
=
"/OptiRampWeb5/Css/kendo.rtl.min.css"
type
=
"text/css"
>
<
link
rel
=
"stylesheet"
href
=
"/OptiRampWeb5/Css/kendo.default.min.css"
type
=
"text/css"
>
<
link
rel
=
"stylesheet"
href
=
"/OptiRampWeb5/Css/kendo.dataviz.min.css"
type
=
"text/css"
>
<
script
type
=
"text/javascript"
src
=
"http://code.jquery.com/jquery-1.12.1.js"
></
script
>
<
script
type
=
"text/javascript"
src
=
"http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"
></
script
>
<
script
type
=
"text/javascript"
src
=
"/OptiRampWeb5/Script/kendo.all.min.js"
></
script
>
<
script
type
=
"text/javascript"
src
=
"/OptiRampWeb5/Script/console.js"
></
script
>
</
head
>
<
body
>
<
div
id
=
"mainbody"
>
<
div
style
=
"position:absolute;left:29.0px;top:21.0px;background-color:#FFFFFF;border:1.0px Solid #000000;"
selectionoffset
=
"3"
oncontextmenu
=
"return false;"
objecttype
=
"RealtimeTable"
onmousedown
=
"objectOnMouseDown(event)"
uniqueid
=
"5113,5117,5121,5114,5118,5122,5115,5119,5123"
uniquepath
=
"Системa1.Reference Table Test.Folder #1.Tag #1,Системa1.Reference Table Test.Folder #2.Tag #1,Системa1.Reference Table Test.Folder #3.Tag #1,Системa1.Reference Table Test.Folder #1.Tag #2,Системa1.Reference Table Test.Folder #2.Tag #2,Системa1.Reference Table Test.Folder #3.Tag #2,Системa1.Reference Table Test.Folder #1.Tag #3,Системa1.Reference Table Test.Folder #2.Tag #3,Системa1.Reference Table Test.Folder #3.Tag #3"
url
=
"http://TEST-LENOVO:9001/api/RTData"
>
<
div
id
=
"object_14-header"
style
=
"width:740.0px;text-align:center;color:#000000;font-size:12pt;font-weight:Bold;font-family:Tahoma;background-color:#FFFFFF;"
uniqueid
=
"5113,5117,5121,5114,5118,5122,5115,5119,5123"
uniquepath
=
"Системa1.Reference Table Test.Folder #1.Tag #1,Системa1.Reference Table Test.Folder #2.Tag #1,Системa1.Reference Table Test.Folder #3.Tag #1,Системa1.Reference Table Test.Folder #1.Tag #2,Системa1.Reference Table Test.Folder #2.Tag #2,Системa1.Reference Table Test.Folder #3.Tag #2,Системa1.Reference Table Test.Folder #1.Tag #3,Системa1.Reference Table Test.Folder #2.Tag #3,Системa1.Reference Table Test.Folder #3.Tag #3"
url
=
"http://TEST-LENOVO:9001/api/RTData"
>This is the title</
div
>
<
div
id
=
"object_14"
style
=
"width:740.0px;height:190.0px;"
uniqueid
=
"5113,5117,5121,5114,5118,5122,5115,5119,5123"
uniquepath
=
"Системa1.Reference Table Test.Folder #1.Tag #1,Системa1.Reference Table Test.Folder #2.Tag #1,Системa1.Reference Table Test.Folder #3.Tag #1,Системa1.Reference Table Test.Folder #1.Tag #2,Системa1.Reference Table Test.Folder #2.Tag #2,Системa1.Reference Table Test.Folder #3.Tag #2,Системa1.Reference Table Test.Folder #1.Tag #3,Системa1.Reference Table Test.Folder #2.Tag #3,Системa1.Reference Table Test.Folder #3.Tag #3"
url
=
"http://TEST-LENOVO:9001/api/RTData"
></
div
>
</
div
>
</
div
>
<
script
>
var
object_14data =
new
kendo.data.ObservableArray([
new
kendo.data.ObservableObject({ col0:
"Folder #1"
, folderId:
"5110"
, folderIndex:
"1"
, folderPath:
"Системa1.Reference Table Test.Folder #1"
, col1:
"---"
, col2:
"---"
, col3:
"---"
, col0uid:
"-1"
, col1uid:
"5113"
, col2uid:
"5114"
, col3uid:
"5115"
, col0path:
"Системa1.Reference Table Test.Folder #1"
, col1path:
"Системa1.Reference Table Test.Folder #1.Tag #1"
, col2path:
"Системa1.Reference Table Test.Folder #1.Tag #2"
, col3path:
"Системa1.Reference Table Test.Folder #1.Tag #3"
}),
new
kendo.data.ObservableObject({ col0:
"Folder #2"
, folderId:
"5116"
, folderIndex:
"2"
, folderPath:
"Системa1.Reference Table Test.Folder #2"
, col1:
"---"
, col2:
"---"
, col3:
"---"
, col0uid:
"-1"
, col1uid:
"5117"
, col2uid:
"5118"
, col3uid:
"5119"
, col0path:
"Системa1.Reference Table Test.Folder #2"
, col1path:
"Системa1.Reference Table Test.Folder #2.Tag #1"
, col2path:
"Системa1.Reference Table Test.Folder #2.Tag #2"
, col3path:
"Системa1.Reference Table Test.Folder #2.Tag #3"
}),
new
kendo.data.ObservableObject({ col0:
"Folder #3"
, folderId:
"5120"
, folderIndex:
"3"
, folderPath:
"Системa1.Reference Table Test.Folder #3"
, col1:
"---"
, col2:
"---"
, col3:
"---"
, col0uid:
"-1"
, col1uid:
"5121"
, col2uid:
"5122"
, col3uid:
"5123"
, col0path:
"Системa1.Reference Table Test.Folder #3"
, col1path:
"Системa1.Reference Table Test.Folder #3.Tag #1"
, col2path:
"Системa1.Reference Table Test.Folder #3.Tag #2"
, col3path:
"Системa1.Reference Table Test.Folder #3.Tag #3"
})
]);
$(document).ready(
function
() {
$.ajaxSetup({ cache:
false
});
$.support.cors =
true
;
if
($(
"#object_14"
).data(
"kendoGrid"
) ==
null
) {
$(
"#object_14"
).kendoGrid({
dataSource: {
data: object_14data,
schema: {
model: {
fields: {
col0: { type:
"string"
},
col1: { type:
"number"
},
col2: { type:
"number"
},
col3: { type:
"number"
},
}
}
},
aggregate: [
{ field:
"col1"
, aggregate:
"sum"
},
{ field:
"col2"
, aggregate:
"average"
},
]
},
groupable:
false
,
resizable:
true
,
sortable:
false
,
pageable:
false
,
columns: [
{
field:
"col0"
,
locked:
true
,
footerTemplate:
"<div style='text-align:center;font-family: \"Arial\";font-size: 8pt;font-weight: normal;'>Tot/Avg:</div>"
,
title:
"Name<br/><div> </div>"
,
headerAttributes: {
"style"
:
"text-transform: none;text-align:center;font-family: \'Arial\';font-size: 8pt;font-weight: normal;"
},
width: 419,
template:
'<div onmousedown="objectOnMouseDown(event);" istablecell="true" tableid="object_14" uniqueid="#= col0uid #" uniquepath="#= col0path #" style="text-align:left;"><span style="font-family: \'Arial\';font-size: 8pt;font-weight: normal;">#= col0 #</span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="padding-left:5px;display:none;" width="16.0px" height="16.0px"><image width="16px" height="16px" x="0" y="0" xlink:href="http://localhost/OptiRampWeb5/images/warning3.svg"></image></svg></div>'
},
{
field:
"col1"
,
locked:
false
,
footerTemplate:
"<div style='text-align:center;font-family: \"Arial\";font-size: 8pt;font-weight: normal;'>#=kendo.format('{0:n2}',sum)#</div>"
,
title:
"Tag #1<br/><div></div>"
,
headerAttributes: {
"style"
:
"text-transform: none;text-align:center;font-family: \'Arial\';font-size: 8pt;font-weight: normal;"
},
width: 100,
template:
'<div onmousedown="objectOnMouseDown(event);" istablecell="true" tableid="object_14" uniqueid="#= col1uid #" uniquepath="#= col1path #" style="text-align:center;"><span style="font-family: \'Arial\';font-size: 8pt;font-weight: normal;">#= (col1 == null) ? "---" : kendo.toString(col1, "0.00") #</span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="padding-left:5px;display:#=(col1 == "---") ? \'inline\' : \'none\' #;" width="16.0px" height="16.0px"><image width="16px" height="16px" x="0" y="0" xlink:href="http://localhost/OptiRampWeb5/images/warning3.svg"></image></svg></div>'
},
{
field:
"col2"
,
locked:
false
,
footerTemplate:
"<div style='text-align:center;font-family: \"Arial\";font-size: 8pt;font-weight: normal;'>#=kendo.format('{0:n2}',average)#</div>"
,
title:
"Tag #2<br/><div></div>"
,
headerAttributes: {
"style"
:
"text-transform: none;text-align:center;font-family: \'Arial\';font-size: 8pt;font-weight: normal;"
},
width: 100,
template:
'<div onmousedown="objectOnMouseDown(event);" istablecell="true" tableid="object_14" uniqueid="#= col2uid #" uniquepath="#= col2path #" style="text-align:center;"><span style="font-family: \'Arial\';font-size: 8pt;font-weight: normal;">#= (col2 == null) ? "---" : kendo.toString(col2, "0.00") #</span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="padding-left:5px;display:#=(col2 == "---") ? \'inline\' : \'none\' #;" width="16.0px" height="16.0px"><image width="16px" height="16px" x="0" y="0" xlink:href="http://localhost/OptiRampWeb5/images/warning3.svg"></image></svg></div>'
},
{
field:
"col3"
,
locked:
false
,
footerTemplate:
"<div style='text-align:center;font-family: \"Arial\";font-size: 8pt;font-weight: normal;'></div>"
,
title:
"Tag #3<br/><div></div>"
,
headerAttributes: {
"style"
:
"text-transform: none;text-align:center;font-family: \'Arial\';font-size: 8pt;font-weight: normal;"
},
width: 100,
template:
'<div onmousedown="objectOnMouseDown(event);" istablecell="true" tableid="object_14" uniqueid="#= col3uid #" uniquepath="#= col3path #" style="text-align:center;"><span style="font-family: \'Arial\';font-size: 8pt;font-weight: normal;">#= (col3 == null) ? "---" : kendo.toString(col3, "0.00") #</span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="padding-left:5px;display:#=(col3 == "---") ? \'inline\' : \'none\' #;" width="16.0px" height="16.0px"><image width="16px" height="16px" x="0" y="0" xlink:href="http://localhost/OptiRampWeb5/images/warning3.svg"></image></svg></div>'
},
]
});
}
startTimer();
});
function
startTimer() {
timerVar = setInterval(changeData, 2000, 0);
}
function
changeData() {
var
grid = $(
"#object_14"
).data(
"kendoGrid"
);
grid.dataSource._data.forEach(
function
(item) {
item.col1 = Math.random() * 100;
item.col2 = Math.random() * 100;
item.col3 = Math.random() * 100;
});
grid.refresh();
grid.dataSource.read();
}
</
script
>
</
body
>
</
html
>