티스토리 뷰
반응형
6.3. DOM과 자바스크립트
JS가 DOM을 변경하고 검색할 때,
repaint 또는 reflow가 발생하여,
컴퓨팅 자원 소모가 심해진다.
6.3.1 DOM repaint
가. 정의
DOM위치가 변경되지 않고,
스타일이 변경될 때 화면을 다시 그리는 것
나. 예제(272p)
(function () { document.getElementById("changeBackground").addEventListener('click', function () { this.style.backgroundColor = "black"; this.style.color = "white"; }); document.getElementById("changeVisibility").addEventListener("click", function () { this.style.visibility = "hidden"; }); }());
위 그림을 비교하였을 때,
JS를 통하여
visibility 혹은 배경색상(스타일)은 수정되었지만,
위치는 변경 안됨.
6.3.2 DOM reflow
가. 정의
DOM위치가 변경되고,
위치에 대한 재계산 과정이 일어나는 것
나. 특징
- 해당 DOM의 위치가 변경 될 경우,
자식 DOM의 위치도 재계산 해야한다.
===> repaint보다 자원 소모가 더 큼
다. 발생 상황
- 특정 DOM이 삭제되거나 크기가 변경된 경우
- 자바스크립트를 통해 className이 변경된 경우
- 브라우저 창 크기가 변경된 경우
다. 예제(275p)
$('#secondDiv').remove();
두번째 DIV가 삭제되면서 세번째 DIV의 위치가 변경됨
6.3.2 reflow, repaint 최소화 방법
1. 크기가 변경될 DOM의 자식 DOM을 최소화
2. position을 이용(279p)
부모부분을 position:relative
위치 고정할 부분을 position:absolute
- 예제 1)
- 예제 2)
3. position 이용2(283p)
가운데 영역의 최상위 부모를 position:relative 로 잡고
안에 position:absolute로 잡음
목록이 reflow를 일으키지않고 자유롭게 에니메이션 효과
4. JS에서 태그명이 아닌, className, Id로 DOM을 탐색한다.
5. 특정영역에 많은 DIV 추가할 경우, createDocumentFragment 이용(290p)
createDocumentFragment을 통한 방법 290p
(function () { /** * STEP 1. createDocumentFragment생성 **/ var fragGuestbook = document.createDocumentFragment(); inputName = document.getElementById("name"), inputSubject = document.getElementById("subject"), inputContents = document.getElementById("contents"), tbodyGuestbook = document.getElementById("guestbookTbody"), /** * STEP 2. 담을 객체들 생성 **/ trGuestbook = document.createElement("tr"), tdName = document.createElement("td"), tdSubject = document.createElement("td"), tdContents = document.createElement("td"); /** * STEP 3. createDocumentFragment에 객채 담기 **/ fragGuestbook.appendChild(trGuestbook); trGuestbook.appendChild(tdName); trGuestbook.appendChild(tdSubject); trGuestbook.appendChild(tdContents); document.getElementById("writeForm").addEventListener("submit", function () { tdName.innerHTML = inputName.value; tdSubject.innerHTML = inputSubject.value; tdContents.innerHTML = inputContents.value; /** * STEP 4. 객체를 담음 **/ tbodyGuestbook.appendChild(fragGuestbook.cloneNode(true)); event.returnValue = false; return false; }); }());
- appendChild 예제 295p
(function () { var inputName = document.getElementById("name"), inputSubject = document.getElementById("subject"), inputContents = document.getElementById("contents"), divGuestbook = document.getElementById("guestbook"), tbodyGuestbook = document.getElementById("guestbookTbody"); document.getElementById("writeForm").addEventListener("submit", function () { /** * STEP 1. 담고자하는 객채 생성 **/ var trGuestbook = document.createElement("tr"), tdName = document.createElement("td"), tdSubject = document.createElement("td"), tdContents = document.createElement("td"); tdName.innerHTML = inputName.value; tdSubject.innerHTML = inputSubject.value; tdContents.innerHTML = inputContents.value; trGuestbook.appendChild(tdName); trGuestbook.appendChild(tdSubject); trGuestbook.appendChild(tdContents); /** * STEP 2. appendChild()통하여 객채 담기 **/ tbodyGuestbook.appendChild(trGuestbook); return false; }); }());
- ※ createDocumentFragment() 혹은 appendChild()이용 시,
한번의 reflow()로 여러개의 객체를 담을 수 있다.
6. clientHeight, offsetWidth등의 스타일 접근을 최소화
7. DOM을 객체로 선언함으로써, 탐색 횟수를 최소화
- 잘못된 방법
document.getElementById("changeDiv").style.backgroundColor = "#EEE"; document.getElementById("changeDiv").style.fontSize = "10em"; document.getElementById("changeDiv").style.width = "100px";
- 올바른 방법
var changDivStyle = document.getElementById("changeDiv").style; changDivStyle.backgroundColor = "#EEE"; changDivStyle.fontSize = "10em"; changDivStyle.width = "100px";
DOM트리를 탐색하는 횟수를 줄여준다.
8. 메모제이션 패턴을 이용
var test = 1 || 2;
가. 정의
함수나 객체를 '메모'하는 것
(function () { var memo = {}; document.getElementById("myForm").onsubmit = function () { var inputFirstName = getMemo("firstName"), inputMiddleName, inputLastName; if (inputFirstName.value === "") { alert("First name is mandatory"); inputFirstName.focus(); return false; } inputLastName = getMemo("lastName"); } function getMemo(id) { memo[id] = memo[id] || document.getElementById(id); return memo[id]; } }());
getMemo() 함수에서 memo라는 변수를 캐시값에 해두었다가,
메모가 있으면 캐시를 반환
없으면 DOM탐색한다.
입력폼 값을 여러번 검사 하여도 DOM탐색은 한번만 한다.
반응형
'ES6' 카테고리의 다른 글
6.4 웹 워커 (0) | 2019.02.15 |
---|---|
6.1단일 스레드 환경 (0) | 2019.02.15 |
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- nginx
- 중간연산
- webpack
- Intellij
- vscode
- install
- BeanFactory
- container
- ngnix
- 스트림
- java
- MAC
- lambda
- 최종연산
- JPA
- 영속성 컨텍스트
- 람다
- ApplicationContext
- mvn
- 자바8
- NPM
- 차이
- Vuex
- Vue
- springboot
- map
- elasticsearch
- stream
- AnnotationConfigApplicationContext
- docker
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함