Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 13.08.2010, 14:48
Новичок на форуме
Отправить личное сообщение для MadLord Посмотреть профиль Найти все сообщения от MadLord
 
Регистрация: 13.08.2010
Сообщений: 2

утечка памяти при создании DOM
вот уже пару дней бьюсь над кодом...суть такова:
есть таблица сформированная с помощью jquery.Datatables...для получения данных используется serverside(php возвращает json)...после отрисовки самой таблицы необходмо наложить на нее дополнительные DOM элементы(ссылки и прочее), для чего написана небольшая функция fnRend с использованием jquery, кот вызывается один раз после отрисовки всей таблицы...вот в ней то и проблема...
если обновлять таблицу без вызова fnRend - все работает быстро и практически без утечек памяти...
если использовать fnRend, то при каждом обновлении таблицы происходит небольшая, но существенная утечка - особенно это заметно в IE(6 и 8): за 15 мин с обновлением через каждые 10сек(таблица 10х100 ячеек) память вырастает метров на 70!...
уже перечитал несколько статей - оптимизировал насколько мог функцию, но все равно что-то остается в памяти при обновлении(обновляется на страница, а только таблица)...
может кто посмотрит проф взглядом и найдет еще недочеты в функции, кот могу приводить к утечке?...
function fnRend()
{
//цикл по каждому row таблицы
	$(oTable_q.fnGetNodes()).each( function() {
//массив изначальных данных в ячейках
		var aData = [];
		for (var i = 0, len = $("td", this).length; i < len; i++) {
			aData.push($("td:eq(" + i + ")", this).html());
		}
//преобразую данные 1-й ячейки - втсавка 3-х ссылок
		var td = $("<div></div>");
		var td0 = td.clone();
		$('td:eq(0)', this).html(td0);
		td0.append('<a href="#"></a>')
			.append('&nbsp;')
			.append('<a href="#"></a>')
			.append('&nbsp;')
			.append('<a href="#"></a>')
			.find('a:eq(0)')
			.append(aData[0])
			.attr("id", "result")
			.attr("title", "Результат команды")
			.end()
			.find('a:eq(1)')
			.attr("title", "Результат команды в RAW-формате")
			.append('<img id="raw" src="./images/pic_agr.gif" border=0>')
			.end()
			.find('a:eq(2)')
			.attr('id', 'repeat')
			.attr("title", "Повтор команды")
			.addClass('iframe')
			.append('<img id="repeat" src="./images/pic_agr.gif" border=0>');

//преобразую данные 7-й ячейки
		var aData7 = aData[7].match(/^([A-Z]+):::([01])$/);
		$('td:eq(7)', this).html(aData7[1]);
		if (aData7[2] == '1') {
			$('td', this).addClass('qrowdisable');
		}
//преобразую данные 6-й ячейки - преобразование времени из 
//unixtime в читабельный вид
		var times = aData[6].split(':');
		var dec = ['00','01','02','03','04','05','06','07','08','09'];
		var day, month, year, date, hour, min, sec, time;
		for (i = 0; i < 3; i++)
		{
			times[i] = new Date(times[i] * 1000);
			day = ((day = times[i].getDate()) < 10) ? dec[day] : day;
			month = ((month = times[i].getMonth() + 1) < 10) ? dec[month] : month;
			year = times[i].getUTCFullYear().toString().substring(2);
			date = [day, month, year];
			hour = ((hour = times[i].getHours()) < 10) ? dec[hour] : hour;
			min = ((min = times[i].getMinutes()) < 10) ? dec[min] : min;
			sec = ((sec = times[i].getSeconds()) < 10) ? dec[sec] : sec;
			time = [hour, min, sec];
			delete times[i];
			times[i] = date.join('.') + " " + time.join(':');
		}
		var td6 = td.clone();
		$('td:eq(6)', this).html(td6);
		td6.append('<img src="./images/pic_agr.gif">')
			.append('<img src="./images/pic_agr.gif">')
			.append('&nbsp;')
			.append('<img src="./images/pic_agr.gif">')
			.find('img:eq(0)')
			.attr('id', 'qtime')
			.attr("title", times[0])
			.after('&nbsp;' + times[0] + '&nbsp;')
			.end()
			.find('img:eq(1)')
			.attr('id', 'stime')
			.attr("title", times[1])
			.end()
			.find('img:eq(2)')
			.attr('id', 'etime')
			.attr("title", times[2]);
		times = null;
//помечаю нужные ячейки тегом span
		$('td', this).each( function(i) {
			if ((i >= 1 && i <=5) || i == 7 || i == 8)
			{
				var k = (i == 7 || i == 8) ? i - 1 : i;
				$(this).wrapInner('<span id="td' + k + '"></span>')
					.find('span')
					.css("cursor", "pointer");
			}
		});
		aData = null;
		td = null;
	});

//onClick на всю таблицу - и выборка действия в зависимости от места евента
	$('#queue_table').unbind();
	$('#queue_table').click(function(e) {
		var form_params = (window.navigator.userAgent.match(/MSIE/)) ? 'left=200,top=100,height=640,width=900,scrollbars=yes' : '';
		var data;
		if (e.target.nodeName == 'SPAN')
		{
			var col = {
				0 : 'search_tt',
				1 : 'search_rr',
				2 : 'search_yy',
				3 : 'search_ww',
				4 : 'search_oo',
				5 : 'search_pp',
				6 : 'search_zz',
				7 : 'search_ss'
			};
			var oSettings = oTable_q.fnSettings();
			var k = $(e.target).attr('id').replace("td", "");
			$("input[id=" + col[k]+ "]").val($(e.target).text());
			oSettings.aoPreSearchCols[k].sSearch = $(e.target).text();
//обновление самой таблицы
			oTable_q.fnDraw(false);
			oSettings = null;
			col = null;
		}
//открытие нового окна
		else if ($(e.target).attr('id') == 'result')
		{
			data = $(e.target).text();
			window.open('/cgi-bin/result.pl?guid=' + data, '', form_params);
			data = null;
		}
		else if ($(e.target).attr('id') == 'raw')
		{
			data = e.target.parentNode.parentNode;
			data = $("a:eq(0)", data).text();
			window.open('/cgi-bin/show.pl?guid=' + data, '', form_params);
			data = null;
		}
	});
}
Ответить с цитированием
  #2 (permalink)  
Старый 13.08.2010, 15:01
Аватар для Snipe
Профессор
Отправить личное сообщение для Snipe Посмотреть профиль Найти все сообщения от Snipe
 
Регистрация: 06.05.2008
Сообщений: 765

Я вот, кстати, у знатоков jQuery спросить хотел.
Он где-то у себя хранит элементы, которые уже давно потерты?

Просто брал элемент через jQuery, что-то с ним делал, потом этот элемент терся через innerHTML родителя.
Обычный document.getElementById('id') - выдавал undefind, а $('#id') показывал и сам элемент и все его атрибуты, присвоенные ранее.
Ответить с цитированием
  #3 (permalink)  
Старый 16.08.2010, 12:01
Новичок на форуме
Отправить личное сообщение для MadLord Посмотреть профиль Найти все сообщения от MadLord
 
Регистрация: 13.08.2010
Сообщений: 2

посмотрел с помощью JavaScript Memory Validator...самыми трубоемкими оказались цилы each...изменил их так:
первый(где формируется массив aData) вообще убрал - ведь пользовался только 3-ми значениями из него...стал брать значения сразу через $("td:eq(_номер_ячейки_)", this).html()...
второй заменил на такую конструкцию:
var tds = [1, 2, 3, 4, 5, 7, 8];                               
var tde = $("<span></span>").css("cursor", "pointer");         
for (i = 0; i < tds.length; i++)                               
{                                                              
    var k = (tds[i] == 7 || tds[i] == 8) ? tds[i] - 1 : tds[i];
    data = $("td:eq(" + tds[i] + ")", this).html();            
    var tdec = tde.clone();                                    
    $("td:eq(" + tds[i] + ")", this).html(tdec.html(data));    
    tdec.attr('id', 'td' + k);                                 
}

утечки значительно уменьшились, но все равно есть - за час набежало 250 метров...
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
утечка памяти. $.post otvernu jQuery 16 17.08.2010 12:40
Баг Firefox: по F5 перескакивает radio при динамическом добавлении в DOM input Atoll Events/DOM/Window 6 22.06.2010 18:25
jQuery + Google Chrome ( утечка памяти ??? ) idler jQuery 4 24.04.2010 14:09
Как происходит утечка памяти в даном случае? Yazla Общие вопросы Javascript 2 09.11.2009 13:02
Кто чем пользуется при создании html элементов vflash Общие вопросы Javascript 14 24.08.2009 21:12