대량의 Input 태그가 있는 페이지에서 jquery validation의 Submit가 얼마나 느린 것은 options.success 때문이었을지도 모른다.

타이틀 길이 ぇ.

jquery Validation 사이코



프런트 엔드의 Validation으로 간편하고 없어서는 안된다 jQuery Validation Plugin
입력 체크가 필요한 곳에서는 거의 반드시 사용하고 있었지만, 유저의 조작에 따라서는 수천의 체크 대상이 생겨 버리는 Form로 체크를 걸면 몇 초~수십초도 브라우저마다 굳어 버린다는 현상이 나왔다.
(jQuery Validation Plugin v1.16.0)



why?

why도 아무것도 그런 대량의 태그 토하는 디자인이 나쁘다.
   / \::/\
  /。(一)::(一)。
  |::。゚(_人_)゚| まったくもってそのとおりです
  \ ゚ `⌒´/゚
  / ⌒ヽ ̄ ̄ヽ゚。
  / __\ \/\ \
 と__)_ヽ_つ ヽ_つ


프로파일링



Chrome의 개발자 도구로 Submit시의 성능 스캔을 찍어 본다.


이것은 끔찍하다.

Bottom-Up에서 Total Time으로 정렬해 보면

이었다.

EventLog에서 보면

jquery.validation#showErrors의 흐름에서 일어나고있는 것 같습니다.

코드 상세



jquery-validation/jquery.validate.js at 29b9c702b9c831419f9f774d2acb86f42f803e11 · jquery-validation/jquery-validation
코드에서 쫓아 본다.

#912 showLabel()



"대상 컨트롤에 대한 에러 표시용 라벨이 없으면 라벨을 등록해 둔다"적인 처리 같다.
이 때문에 1000을 넘는 컨트롤에 대해 숨겨진 라벨을 추가하는 처리가 달려 시간이 걸리는 것 같다.

그러나 에러가 없어도 우선 컨트롤을 만들어 두는 것은 어떨까.

#875 defaultShowErrors()



jquery.validation.js
defaultShowErrors: function() {
    var i, elements, error;
    for ( i = 0; this.errorList[ i ]; i++ ) {
        error = this.errorList[ i ];
        if ( this.settings.highlight ) {
            this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
        }
        this.showLabel( error.element, error.message );
    }
    if ( this.errorList.length ) {
        this.toShow = this.toShow.add( this.containers );
    }
    if ( this.settings.success ) {
        for ( i = 0; this.successList[ i ]; i++ ) {
            this.showLabel( this.successList[ i ] );
        }
    }

응? 오류가 있으면 this.showLabel(), 그것에 관계없이 this.settings.success 그렇다면 this.showLabel()?

settings.success란 무엇입니까?



문서 낚시하면

성공
Type: String or Function()
If specified, the error label is displayed to show a valid element. If a String is given, it is added as a class to the label. If a Function is given, it is called with the label (as a jQuery object) and the validated input (as a DOM element). The label can be used to add a text like "ok!".

그리고, 에러 표시하는 라벨의 에러가 되어 있지 않을 때의 표시를 설정할 수 있는 것 같다.
라고 하는 것은, 검증 OK로 무엇인가 표시할 때용으로 필요한 것이고, OK의 경우 특히 아무것도 표시하지 않는다면 원래 만들 필요가 없지 않을까···?

체크의 흐름을 방해해 보자


  • \$.validator.form/\$.validator.element 로부터 element.check() 가 불려 체크
  • 오류라면 formatAndAdd() 를 통해 errorList 에 추가됩니다.
  • OK라면 successList 에 추가

  • showErrors()
  • successList 에서 errorList 의 것을 제외
  • this.setting.showErrors() 또는 this.defaultShowErrors()
  • errorList 물건을 showLabel()
  • this.settings.success 그렇다면 successList
  • 표시해야 할 것을 showLabel() 표시해서는 안되는 것을 toShow로 정리 한 다음 toHide로 숨기기 처리

    아, 역시 이것 OK로 아무것도 표시하지 않으면 만들 필요 없어.

    그래서


    $("#myform").validate({
      success: null
    });
    

    했던 곳



    0.8초 정도까지 단축할 수 있었다.

    「Major GC(1.9MB collected)」로 160ms나 걸려 있는 것은 원래 이런 구조로 하고 있기 때문입니다.
       / \::/\
      /。(一)::(一)。
      |::。゚(_人_)゚| すみませんすみません
      \ ゚ `⌒´/゚
      / ⌒ヽ ̄ ̄ヽ゚。
      / __\ \/\ \
     と__)_ヽ_つ ヽ_つ
    
    

    요약



    jquery.validation을 사용하여 오류를 검사 할 때 오류가 아니면 단순히 오류 표기를 지우면,
    form.validate({success: null});
    

    해야합니다.
  • 좋은 웹페이지 즐겨찾기