JQuery проверяет большие формы - script работает медленно
Я использую jQuery Validate plugin 1.8.0 с jQuery 1.5. Отлично подходит для малых и средних форм. Для больших форм производительность значительно ухудшается (даже в IE8 и FF4), иногда приводит к тому, что сообщение "script работает слишком медленно". Похоже, что плагин сканирует всю DOM в форме, которая ищет атрибуты и классы для проверки, даже если вы указали пользовательские правила. Кто-нибудь знает, как полностью отключить это? Также есть опция игнорирования, но она все равно сканирует DOM, пропуская их с игнорированием attr.
Вот что делает ASP.NET, кроме примерно 120 строк данных. Пейджинг результатов не является вариантом, к сожалению.
<table id="GridView1">
<tbody>
<tr>
<th scope="col">Header 1</th>
<th scope="col">Header 2</th>
<th scope="col">Header 3</th>
<th scope="col">Header 4</th>
<th scope="col">Header 5</th>
<th scope="col">Header 6</th>
<th style="width: 60px; white-space: nowrap" scope="col">Header 7</th>
<th style="width: 60px; white-space: nowrap" scope="col">Header 8</th>
</tr>
<tr class="gridRow" jquery1507811088779756411="3">
<td style="width: 50px" align="middle">
<span id="GridView1_ctl03_Label1">XXX</span>
</td>
<td>
<span id="GridView1_ctl03_Label2">YYY</span>
</td>
<td style="width: 50px" align="middle">
<span id="GridView1_ctl03_Label3">ZZZ</span>
</td>
<td align="middle">
<select style="width: 70px" id="GridView1_ctl03_Dropdown4" name="GridView1$ctl03$Dropdown4">
<option selected value="Y">Y</option>
<option value="N">N</option>
</select>
</td>
<td style="width: 50px" align="middle">
<input id="GridView1_ctl03_hidId1" value="100" type="hidden" name="GridView1$ctl03$hidId1" />
<input id="GridView1_ctl03_hidId2" value="100" type="hidden" name="GridView1$ctl03$hidId2" />
<input id="GridView1_ctl03_hidId3" value="100" type="hidden" name="GridView1$ctl03$hidId3" />
<input id="GridView1_ctl03_hidId4" value="100" type="hidden" name="GridView1$ctl03$hidId4" />
<select style="width: 40px" id="GridView1_ctl03_Dropdown5" name="GridView1$ctl03$Dropdown5">
<option selected value="A">A</option>
<option value="B">B</option>
</select>
</td>
<td style="width: 50px" align="middle">
<span id="GridView1_ctl03_Label6">101</span>
</td>
<td align="middle">
<input style="width: 60px" id="GridView1_ctl03_Textbox8" class="date required"
title="Please enter a valid start date." type="text" name="GridView1$ctl03$Textbox8"
jquery1507811088779756411="122" />
</td>
<td align="middle">
<input style="width: 60px" id="GridView1_ctl03_Textbox9" class="date"
title="Please enter a valid end date." type="text" name="GridView1$ctl03$Textbox9"
jquery1507811088779756411="123" />
</td>
</tr>
</tbody>
</table>
Ответы
Ответ 1
Я тоже борюсь с этой проблемой. Изменив некоторые проверки, я смог сократить время проверки в IE8 за 80 проверок элементов с 4100 мс до 192 мс. Я опубликую свои выводы здесь, надеюсь, что другие могут извлечь выгоду, а также в надежде, что какой-нибудь эксперт по jquery-validate найдет проблему с моим кодом.
Вот что я нашел полезным:
- Убедитесь, что у вас нет атрибутов проверки на все, что вам действительно не нужно проверять. У меня было какое-то таинственное появление на элементах - я не уверен, почему, но я жестко закодировал data-val = false на них в моем .cshtml, чтобы предотвратить это.
-
Определите свой собственный метод проверки формы. Тот, который встроен в jQuery, делает пару вещей очень медленно, и вам, вероятно, не нужна вся гибкость, которую он предоставляет. Вот мой - использование этого сделало огромную разницу (он называется подмножеством, потому что моя форма делится на вкладки, и я вызываю это на каждой вкладке div по мере продвижения пользователя).
jQuery.validator.prototype.subset = function (container, validateHiddenElements) {
var ok = true;
var validator = this;
// Performance hack - cache the value of errors(), and temporarily patch the function to return the cache
// (it is restored at the end of this function).
var errors = this.errors();
var errorsFunc = this.errors;
this.errors = function () { return errors; };
$(container.selector + " [data-val=true]").each(function () {
!this.name && validator.settings.debug && window.console && console.error("%o has no name assigned", this);
var tagName = this.tagName.toLowerCase();
if (tagName == "input" || tagName == "select" || tagName == "textarea") {
var $this = $(this);
if (!$this.hasClass('doNotValidate') &&
(validateHiddenElements || $this.is(':visible'))) {
if (!validator.element($this)) ok = false;
}
}
});
this.errors = errorsFunc;
return ok;
};
-
Определите свой собственный метод showErrors на validator.settings. Встроенный модуль создает промежутки сообщений об ошибках для каждого допустимого ввода, даже если нет ошибки для отображения. Это происходит довольно медленно, если у вас их много, поэтому вы можете добавить некоторую логику, чтобы избежать этого. Вот мой:
function showErrorsOverride() {
var anyElementsNeedUpdate = false;
for (var i = 0; i < this.errorList.length; i++) {
if (!$(this.errorList[i].element).hasClass(this.settings.errorClass)) {
anyElementsNeedUpdate = true;
}
}
for (var i = 0; i < this.successList.length; i++) {
if ($(this.successList[i]).hasClass(this.settings.errorClass)) {
anyElementsNeedUpdate = true;
}
}
if (anyElementsNeedUpdate)
{
// show the usual errors (defaultShowErrors is part of the jQuery validator)
this.defaultShowErrors();
}
}
Ответ 2
Немного поздно для вечеринки, но для любого, кого интересует - похоже на ответ Джо, я обнаружил, что отключение настройки успеха из функции defaultShowErrors() помогает совсем немного. Все, что кажется, это скрыть метку ошибки для допустимых полей, и если у вас нет меток ошибок, это лишние накладные расходы. Выпустил мою форму с 55 полями от ~ 1,8 секунды до ~ 260 мс в IE8.
$(document).ready(function()
{
$("form").each(function ()
{
$(this).data("validator").settings.success = false;
})
});
Ответ 3
Нам нужно больше кода, чтобы помочь вам. Но пересечение DOM вызывает тяжелую работу.
Возможно, для этих больших форм вы хотите использовать другой подход. Если вы используете множество комбо и текстовых полей, вы можете присоединить обработчик событий (потерянный фокус), чтобы сохранить значение в объекте javascript, а затем использовать этот объект для получения данных.
Ответ 4
У нас были похожие проблемы с большой формой, но нашли следующее решение. Теперь наши большие формы ( > 600 входов) подтверждают в ~ 10 мс.
Я написал ответ здесь:
fooobar.com/info/471200/...