JavaScript-функция «createCallback» вызывается> 50 раз, когда я использую addClass / removeClass в Firefox - PullRequest
2 голосов
/ 21 июля 2011

Я работаю над веб-приложением в ASP.NET 2.0, которое включает в себя несколько GridView элементов. Когда пользователи щелкают одну из строк в сетке, эта строка должна отображать свой выбор путем изменения цвета. Каждая строка имеет атрибуты, установленные для идентификации ее типа записи и уникального идентификатора:

<tr data-elementType='myType' data-myID='12' onclick='selectionFunction();'></tr>

Я выполняю выделение с помощью обработчика javascript onclick в каждой строке, которая вызывает функцию, которая:

  • Удаляет класс selected из ранее выбранной строки
  • Добавляет класс selected к новой выбранной строке
  • Обновляет значение скрытого поля с новым выбранным уникальным идентификатором, чтобы код на стороне сервера мог знать, над каким элементом нужно выполнить действие при нажатии кнопки (просмотреть, удалить и т. Д.).

Одна из этих сеток теперь содержит чуть более 700 записей. В Firefox 3.6 операция выбора в этой сетке ужасно медленная (около двух секунд); в других браузерах (даже IE 7 и 8) это не проблема. Я помещаю операторы console.log в начало и конец функции выбора, а в Firebug они очень быстро появляются в конце задержки, предполагая, что не функция выбора замедляет процесс. Я использовал профилировщик в Firebug, и он говорит, что «createCallback», который определен в одном из файлов сценариев «ScriptResource», сгенерированных ASP.NET, занимает огромное количество времени. Что такое createCallback и почему он кажется таким медленным в Firefox 3.6? Это ошибка в FF, или это проблема, которую я могу решить?

ОБНОВЛЕНИЕ : Я, конечно, использую jQuery для добавления / удаления классов из строк. Я работал с jQuery 1.5.2 и jQueryUI 1.8.11, но я обновился до последней версии (1.6.2 и 1.8.14 в настоящее время) безрезультатно. Я попытался установить точку останова в createCallback, чтобы увидеть, где он вызывается, и когда он прерывается, в стеке вызовов на несколько кадров переходит от removeClass. Вот как выглядит стек в Firebug:

createCallback() - в ScriptResource.axd? ......

wherever possible trim: trim ? function(text=" ") - в jQuery

removeClass(value="selectedRow") - в jQuery

removeClass(classNames="selectedRow", speed=undefined, easing=undefined, callback=undefined) - в jQueryUI

selectionFunction() - на моей странице .aspx

onclick

Я не понимаю, почему jQuery вызывает сгенерированную ASP.NET функцию, подобную этой.

ОБНОВЛЕНИЕ 2 : дальнейшее расследование предоставило еще больше деталей. Кажется, что эта функция «createCallback» получает название A LOT, когда я использую addClass / removeClass, и это происходит как в Firefox 3.6, так и в Firefox 5. Я нашел ту же функцию в Chrome и установил для нее точку останова, и это вообще не вызывается, так что это похоже на Firefox. Я поставил точку останова на рассматриваемой функции / строке и выбрал строку, и точка останова получила ее 57 раз . Только первые два вовлекли меня, звоня removeClass и addClass; у остальных было createCallback несколько раз в стеке вызовов, а иногда и BeginRequestEventArgs. Я заметил, что он вызывается также при наведении указателя мыши на другие элементы jQueryUI на странице (вкладки), когда jQuery использует addClass и removeClass. Но почему он так часто вызывается, когда я работаю над элементами tr?

Я изменяю заголовок и теги, чтобы отразить реальную проблему.

UPDATE 3 : createCallback вызывается примерно одинаковое количество раз, когда я выбираю строку в любой из сеток, даже если в ней всего 6 строк. Но в этом случае это не проблема производительности, и профилировщик показывает, что он занимает всего около 30% времени выполнения, тогда как при выборе профиля для таблицы большего размера это не менее 80%. Так что createCallback, кажется, работает хуже, когда используется в контексте большего количества материалов, видимых на странице. Но все равно кажется, что jQuery не должен вызывать вызов createCallback, тем более что я не мог вообще отследить какие-либо ссылки на него в поиске скриптов Firebug. И кажется, что он вызывается только в Firefox!

Обратите внимание, что все эти сетки находятся на одной странице, но одновременно видна только одна, потому что я использую вкладки jQueryUI.

ОБНОВЛЕНИЕ 4 : Мне удалось получить что-то похожее на jsFiddle в соответствии с просьбой.Смотрите здесь .В Firebug найдите createCallback и установите точку останова (чуть ниже моего обработчика кликов в скрипте, где он начинается с Function.__typeName = "Function"; Function.__class = true; Function.createCallback = function (b, a) и перезагрузите страницу. Я получаю много звонков.

Ответы [ 3 ]

1 голос
/ 21 июля 2011

У меня очень мало знаний об ASP, но, похоже, ваша проблема - чисто клиентская сторона.

Объявление события onclick для каждой строки - не самый разумный способ обработки строк, по которым щелкают. Особенно, когда вы попадаете в количество строк, о которых вы говорите (~ 700+).

Лучшим способом было бы добавить обработчик события click в таблицу и выяснить, что происходит при нажатии. Я написал приложение, в котором обрабатывается таблица аналогичного размера, и мы не видим ничего похожего на задержку, которую вы испытываете при нажатии. вполне могут быть и другие факторы, приводящие к замедлению событий щелчка, однако я бы по-прежнему предложил что-то вроде следующего, которое стоит реализовать в любом случае:

$(function(){
    var rowSelectedClass = 'rowSelectedClass';
    $('#myTableID').click(function(e){
        if(e.target.nodeName === 'TD'){
            var $tr = $(e.target).parent();
            $('tr.' + rowSelectedClass).removeClass(rowSelectedClass);
            $tr.addClass(rowSelectedClass);

            // ....
            // Do whatever else you want to do when the row is clicked
            // ....

        }
    });
}

Хорошую статью, в которой можно взглянуть на сторонников этого метода (и несколько других полезных советов jQuery), можно найти здесь: http://www.artzstudio.com/2009/04/jquery-performance-rules/#leverage-event-delegation

Также стоит отметить, что если в вашей таблице есть строки, добавляемые динамически после загрузки страницы, рассмотрите возможность использования .live() вместо .click().

ОБНОВЛЕНИЕ @ 28 июля 2011 г. 9 AM
Посмотрев на источник более внимательно, я думаю, что предполагаемые вызовы «createCallback» - красная сельдь. Строка в вашем исходном источнике jsFiddle, которая содержит функцию «createCallback», на самом деле представляет собой очень длинную строку (~ 90 000 символов) javascript. Я думаю, тот факт, что «createCallback» является первой функцией в этой строке, вводит в заблуждение профилировщик Firebug. Когда вы профилируете загрузку своей исходной страницы, происходит 2261 вызов, и, как вы сказали, для «createCallback» будет много лотов

Я "украсил" (ненавижу эту фразу) эту длинную строку JS через http://jsbeautifier.org/, чтобы сделать ее читабельной, и заново добавил ее на страницу jsFiddle. Вы можете увидеть это здесь: http://fiddle.jshell.net/KvpmE/1/show/. Теперь, когда вы профилируете загрузку этой страницы, вы увидите такое же количество вызовов (2267 - не уверен, что случилось с остальными 6!), Но, что важно, ни одного, чтобы "createCallback" ».

Я до сих пор не могу предложить какое-либо решение, потому что по сути я не смог воссоздать вашу исходную проблему, которая заключалась в том, что в Firefox 3.6 было 2-секундное отставание при нажатии на строку.

Это все еще проблема, с которой вы столкнулись?

Не могли бы вы попытаться выяснить, можете ли вы воссоздать проблему на обновленной странице jsFiddle?

Также попробуйте добавить на свою страницу деинициализированный JS, чтобы увидеть, поможет ли он отследить фактические функции, вызываемые при щелчке строки, и, следовательно, место задержки.

0 голосов
/ 27 июля 2011

Function.createCallback часто используется Ajax Toolkit для внутреннего использования, и, возможно, он также вызывается непреднамеренно в вашем коде http://msdn.microsoft.com/en-us/library/dd409287.aspx.

Поскольку это зависит от браузера, я бы проверял выполняемые пути кодана основе конкретного браузера.

Другой ключ, который нужно искать, это наличие у вас каких-либо компонентов Ajaxtoolkit для сетки или отдельных строк, поскольку это объясняет увеличение количества вызовов с увеличением количества строк.

Тамтакже функция Type.createCallback (http://msdn.microsoft.com/en-us/library/bb397568.aspx), поэтому, если у вас есть какой-либо код или методы, связанные с Type, я бы их проверил.

0 голосов
/ 25 июля 2011

г. Джефферсон,

Мне действительно кажется, что вы выполняете постбэк, не зная об этом. Вы уже установили точку останова на стороне сервера, чтобы проверить, не запускает ли что-то непреднамеренно вашу панель обновлений? Похоже, что происходит какая-то обратная передача, требующая перезагрузки зависимых скриптов.

Я говорю это потому, что 1) проблема, с которой вы сталкиваетесь, не имеет абсолютно никакого смысла - вы на 100% на деньгах с JQuery и ASP.NET Client Framework, даже не зная, что в этом случае они соседи, и 2 ) экземпляр BeginRequestEventArgs звучит так, как будто PageRequestManager думает, что он должен что-то делать в ответ на ваши триггеры ... Вы также можете попробовать отключить Fiddler и просто выполнить быструю проверку работоспособности, чтобы убедиться, что какая-то ваша панель обновлений не срабатывает. Во время описываемых операций не должно быть HTTP-трафика.

Извините, если это абсолютно бесполезная публикация для вас, но со всей работой, которую вы проделали для устранения неполадок на стороне клиента, не повредит установить точку останова на стороне сервера, просто чтобы выполнить быструю проверку работоспособности / occam's бритва ...

Удачи - счастливого кодирования.

B

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...