我已经在Javascript中开发了一段时间,但我遇到的内存泄漏问题有点过头了。抱歉,这是一个很长的问题,但任何帮助将不胜感激。
我有一个日历格式#sxpSolutionTblWrap
的自定义表格,该表格使用每天详细信息的模板动态填充。默认情况下,我加载2周,没有周末,所以我填充了10天的DOM元素。
点击一天调用函数populateInfoPanel
,在此函数中我调用另一个函数loadSingleSolutionRow
,我在其中找到是否在表中选择了前一天并将其删除,然后再次使用基本信息,好像没有被选中一样。
loadSingleSolutionRow: function(dow, dateValue, click, columnId) {
var self = this;
if (click === true) {
$('.sxpTableCol[data-colid="' + dow + '"]').empty();
}
//do stuff
var columnName = click === true ? '.sxpTableCol[data-colid="' + dow + '"]' : '#solCol' + columnId;
if (click === true) {
$(columnName).replaceWith(self.solutionTableRow({
dayId: dow,
date: selectedDate,
dateValue: dateValue,
statusClass: statusClass,
statusIconClass: statusIconClass,
trainerCountEarly: trainerCountEarly,
trainerListEarly: trainerListEarly,
roomCountEarly: roomCountEarly,
roomListEarly: rooomListEarly,
trainerCountLate: trainerCountLate,
trainerListLate: trainerListLate,
roomCountLate: roomCountLate,
roomListLate: rooomListLate,
protip: protip,
statusText: statusText,
}));
} else {
$(columnName).append(self.solutionTableRow({
dayId: dow,
date: selectedDate,
dateValue: dateValue,
statusClass: statusClass,
statusIconClass: statusIconClass,
trainerCountEarly: trainerCountEarly,
trainerListEarly: trainerListEarly,
roomCountEarly: roomCountEarly,
roomListEarly: rooomListEarly,
trainerCountLate: trainerCountLate,
trainerListLate: trainerListLate,
roomCountLate: roomCountLate,
roomListLate: rooomListLate,
protip: protip,
statusText: statusText,
}));
}
//Event listener for clicking on day
$('.sxpTableCol').off().on('click', '.sxpTableHeader', function (e) {
//populateInfoPanel
});
}
然后我继续添加每天的事件以在for循环中加载到日历上,以前在一天中删除DOM元素并将其替换为populateInfoPanel
函数中的新DOM元素
for (var j = 0; j < duration; j++) {
var dayCount = j + 1;
if (dayId !== undefined && daySolutions.Days[dayId].Solution !== undefined) {
//Getting day of solution in calendar grid
var daySolution = daySolutions.Days[dayId].Solution[j];
var solutionDayIndex = daySolution.DayIndex;
var solutionWeekIndex = daySolution.WeekNum;
var startWeek = moment(self.dto.startDate, 'YYYY-MM-DDTHH:mm').diff(moment(this.settings.findWhere({
Key: 'StartDate'
}).get('Value'), 'YYYY-MM-DD').startOf('isoWeek'), 'weeks') + 1;
var weekIndex = solutionWeekIndex - startWeek;
//var day = parseInt(dayId) + j;
var day = solutionDayIndex + (weekIndex * self.numDays);
//DO STUFF -- GETTING ROOM & TRAINER INFORMATION TO APPEND TO DOM
//DO STUFF -- GETTING POSITION OF ELEMENT ON THAT DAY
//DO STUFF -- GETTING LABELS THAT GO ONTO HEADER OF DAY
//APPEND DAY DETAILS TO CALENDAR
$(shiftData + day + '"]').append(self.selectedItemTpl({
dayCourse: dayCourse,
trainerList: trainerLabel,
roomList: roomLabel,
dayId: dayInfoId,
solutionId: j,
shiftId: shiftIndex,
day: day,
trainerIconClass: trainerIconClass,
roomIconClass: roomIconClass,
}));
}
}
我遇到的问题是,当我点击一天然后再点击另一个时,每次都需要更长的时间。当解决方案在2周的网格上只有1到5天时,这很好,但是当解决方案在5周的网格上长达20天并且每天点击的时间更加明显时,它会非常慢。
populateInfoPanel
长约500行,不确定是否与它有任何关系。我不确定我删除元素的方法是否实际上是从内存中删除它们,如果是这种情况,我该如何更有效地执行此操作?任何帮助将不胜感激。
从5周的网格上的10天解决方案(Grid上25天的DOM元素),这里是时间点30天之间点击的时间线视图,因为您可以看到第一次点击需要十分之八秒,最终点击需要1.5秒,并且点击的次数越多越明显。
以下是在几天之间点击30秒期间的一些堆快照,如果您需要进一步了解可能导致此问题的更多信息,那将非常有用