Thu, Oct 28, 21, Javascipt Patterns 책의 8장 'DOM 과 브라우저 패턴' 을 요약
This is a draft, the content is not complete and of poor quality!

J1988

Javascipt Patterns 책의 8장 “DOM 과 브라우저 패턴” 을 요약하였습니다.

DOM 접근

  • dom 접근은 최소화한다.
  • 루프문 내에서 DOM 접근은 피한다.

    // 안티패턴
    for (var i = 0; i < 100; i += 1) {
      document.getElementById("result").innerHTML += i + ", ";
    }
    
    // 지역 변수를 이용한 개선
    var i, content = "";
    for (var i = 0; i < 100; i += 1) {
      content += i + ", ";
    }
    document.getElementById("result").innerHTML += content;
    
  • DOM 참조를 지역변수에 할당하여 사용한다.

    // 안티패턴
    var padding = document.getElementById("result").style.padding,
        margin = document.getElementById("result").style.margin;
    
    // 개선안
    var style = document.getElementById("result").style.
        padding = style.padding;
        margin = style.margin;
    
    document.querySelector("ul .selected");
    // 쿼리 셀렉터는 다른 DOM 메서드 선택방식보다 빠르다.
    
  • 자주 접근하는 엘리먼트에 id 속성을 추가하는 것도 성능 향상에 도움이 된다. 왜냐면, document.getElementById("id") 가 노드를 찾는 가장 빠른 방법

DOM 조작

  • DOM 업데이트는 최소화 하는 것이 좋다.
  • 업데이트시에 화면을 repaint 하고, 엘리먼트를 reflow 하는데 비용이 많이 들어가기 떄문
  • 서브트리를 추가할 시에는 서브 트리의 구성요소를 모두 생성한 후에 마지막에 한번만 추가해준다.

    // 안티 패턴
    var p, t;
    p = document.createElement("p");
    t = document.createTextNode("first paragraph");
    p.appendChild(t);
    document.body.appendChild(p);
    
    p = document.createElement("p");
    t = document.createTextNode("second paragraph");
    p.appendChild(t);
    document.body.appendChild(p);
    
    // 개선
    var p, t, frag;
    frag = document.createDocumentFragment();
    
    p = document.createElement("p");
    t = document.createTextNode("first paragraph");
    p.appendChild(t);
    frag.appendChild(p);
    
    p = document.createElement("p");
    t = document.createTextNode("second paragraph");
    p.appendChild(t);
    frag.appendChild(p);
    
    document.body.appendChild(frag);
    
  • 존재하는 트리를 변경하는 경우에는 서브트리의 루트를 복제해서 변경한 뒤 원래의 노드와 바꾼다.

    var oldnode = document.getElementById("result"),
        clone = oldnode.cloneNode(true);
    
    oldnode.parentNode.replaceChild(clone, oldnode);
    

이벤트

  • 이벤트 리스너는 아래와 같이 구현할 수 있다.

    var b = document.getElementById("clickme");
    if (document.addEventListener) {
      b.addEventListener("click", myHandler, false);
    } else if (document.attachEvent) {
      b.attachEvent("onclick". myHandler);
    } else {
      b.onclick = myHandler;
    }
    
    function myHandler(e) {
        var src, parts;
    
        e = e || window.event;
        src = e.target || e.srcElement;
    
        if (src.nodeName.toLowerCase() !== "button") {
          return ;
        }
    
        parts = src.innerHTML.split(": ");
        parts[1] = parseInt(parts[1], 10) + 1;
        src.innerHTML = parts[0] + ": " + parts[1];
    
        if (typeof e.stopPropagation === "function") {
          e.stopPropagation();
        }
        if (typeof e.cancelBubble !== "undefined") {
          e.cancelBubble = true;
        }
    
        if (typeof e.preventDefault() === "funtion") {
          e.preventDefault();
        }
        if (typeof e.preventDefault() !== "undefined") {
          e.returnValue = false;
        }
    
    }
    
  • setTimeOut() 이나 Web Worker 를 이용하여 쓰레드 같은 기능을 구현할 수 있다.

XMLHttpRequest

  • 자바스크립트에서 HTTP 요청을 생성하는 특별한 객체 (생성자 함수)
  • 생성과정은 아래와 같다.

    1. XMLHttpRequest(XHR) 객체를 생성
    var xhr = new XMLHttpRequest();
    
    1. 응답 객체의 상태 변경시 알림을 받기 위한 콜백함수 지정
    xhr.onreadystatechange = handleResponse;
    
    1. 요청을 보낸다.
    xhr.open("GET", "page.html", true); // 마지막 true 값은 요청의 비동기 여부, 가급적 true 로 사용자 경험 올리기
    xhr.send();
    

JSONP

  • JSON with padding
  • 브라우저의 동일 도메인 정책의 제약을 받지 않는다.
  • JSONP 의 요청 URL 형태

    http://example.org/getdata.php?callback=myHandler
    
  • 위에서 getdata.php 가 웹페이지 이거나 스크립트가 될 수 있다.
  • getdata.php 파일이 수신되면, myHandler({“hello”: “world”}) 같은 콜백함수가 실행된다.

웹 페이지 로딩 전략

  • script 태그에 들어가는 엘리멘트를 살펴보자.

    • type=”text/javascript” : HTML5 에서는 필수 속성이 아니고, 마크업 유효성 검사를 위한 경우가 아니라면 사용하지 않는다.
    • async (defer) : 비동기 스크립트 로딩으로, 스크립트를 받는 동안 다른 다운로드를 방해하지 않는다.

The following wiki, pages and posts are tagged with

TitleTypeExcerpt
learningjavascript canvas tag post Friday, getting started with the book by coding for user input canvas, amazing!
ES6 tools techniques and paradigm post Fri, Oct 15, 21, a practical and thorough coverage of important language concepts.
Javascript 101 post Tue, Oct 19, 21, quick reference for fundamental things in javascript
Javascript tips at par with this jekyll post Tue, Oct 26, 21, reload page, lose focus, add MathJax to website, hover anchor links, default event, search result navigation, starred repo json
Javascript dome pattern post Thu, Oct 28, 21, Javascipt Patterns 책의 8장 'DOM 과 브라우저 패턴' 을 요약
D3 square.github.io data binding post Thu, Nov 11, 21, data binding
D3.js square.github.io tutorial post Thu, Nov 11, 21, data binding
자바스크립트는 왜 그 모양일까? page 더글라스 크락포드가 알려주는
javascript for impatient page Exploit the power of modern javascript and avoid the pitfalls
리팩토링 2판 page 코드 구조를 체계적으로 개선하여 효율적인 리팩터링 구현하기
자바스크립트 코딩의 기술 page 똑똑하게 코딩하는 법
jsimpatient learning path post javascript revisited