jQuery проверяет большие формы - скрипт работает медленно - PullRequest
12 голосов
/ 04 апреля 2011

Я использую плагин jQuery Validate 1.8.0 с jQuery 1.5. Прекрасно подходит для малых и средних форм. Для больших форм производительность значительно снижается (даже в IE8 и FF4), иногда вызывая сообщение «скрипт выполняется слишком медленно». Похоже, что плагин сканирует весь DOM в форме в поисках атрибутов и классов для проверки, даже если вы указали пользовательские правила. Кто-нибудь знает, как полностью отключить это? Также есть опция игнорирования, но она все равно будет сканировать DOM, пропуская те с помощью атрибута ignore.

Вот что визуализирует 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>

Ответы [ 4 ]

11 голосов
/ 26 января 2012

Я тоже боролся с этой проблемой.Изменяя некоторые параметры проверки, я смог сократить время проверки в IE8 для 80 элементов проверки с 4100 мс до 192 мс.Я опубликую свои выводы здесь в надежде, что другие могут извлечь выгоду, а также в надежде, что какой-то эксперт в jquery-validate найдет проблему с моим кодом.

Вот некоторые вещи, которые я нашел полезными:

  1. Убедитесь, что у вас нет атрибутов проверки того, что вам не нужно проверять.У меня были некоторые загадочные признаки элементов - я не уверен, почему, но я жестко запрограммировал data-val = false на них в своем .cshtml, чтобы предотвратить это.
  2. Определите свой собственный метод дляподтвердите форму.Тот, который встроен в 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;
    };
    
  3. Определите свой собственный метод 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();
        }
    }
    
9 голосов
/ 19 октября 2012

Немного опоздал на вечеринку, но для всех, кто заинтересовался, - как и в ответе Джо, я обнаружил, что отключение параметра успеха из функции defaultShowErrors () очень помогает. Все, что он делает, это скрывает метку ошибки для допустимых полей, и если у вас нет меток ошибок, это лишние затраты. Ускорение формы с 55 полями с ~ 1,8 секунды до ~ 260 мс в IE8.

$(document).ready(function()
{
    $("form").each(function ()
    {
        $(this).data("validator").settings.success = false;
    })
});
0 голосов
/ 17 апреля 2014

У нас были похожие проблемы с большой формой, но мы нашли следующее решение.Теперь наши большие формы (> 600 входных данных) проверяются в течение ~ 10 мс.

Я разместил ответ здесь: https://stackoverflow.com/a/23132844/1821717

0 голосов
/ 04 апреля 2011

Нам нужно больше кода, чтобы помочь вам. Но обход объектов DOM - это тяжелая операция. Может быть, для этих больших форм вы хотите использовать другой подход. Если вы используете много комбо и текстовых полей, вы можете прикрепить обработчик событий (в случае потери фокуса), чтобы вы могли сохранить значение в объекте javascript и позже использовать этот объект для получения данных.

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