브라우저 런타임 환경 - (2) 코드실행과 렌더링

GY·2021년 11월 3일
0

Basic CS

목록 보기
5/28
post-thumbnail

🥞 DOM 요소는 한번에 렌더링된다

1. style & appendChild

button.addEventListener('click', () => {
	const element = document.createElement('li');
	document.body.appendChild(element);
	element.style.color = 'black';
	element.innerText = 'text';
}

렌더링할 때 자식노드를 붙이는 것과 style을 수정하는 것의 순서는 어떻게 해야할까? 어떻게 하는 것이 성능에 도움이 될까?

  • 버튼을 클릭하면 이벤트가 발생된다.
  • 이벤트가 발생하면 web API에서 콜백함수를 task queue에 넣는다.
  • task queue에서 호출되면 각 코드를 이벤트 루프가 자바스크립트 엔진의 call stack에 넣어 실행한다.
  • 코드를 모두 실행한 다음, 이벤트 루프가 한번 렌더링할 때 한 번에 레이아웃과 페인트를 하기 때문에 코드의 순서는 상관 없다.

2. style.transform

button.addEventListener('click', () => {
  box.style.transition = 'all 0.5s ease';
  box.style.transform = 'translateX(300px)';
  box.style.transform = 'translateX(-500px)';
});

위의 예시와 마찬가지다.

  • 버튼 클릭시 이벤트 발생
  • 이벤트 발생 시 web API에서 콜백함수를 task queue에 전달
  • task queue에서 호출되면 각 코드를 자바스크립트 엔진의 call stack에 넣어 실행
  • 코드를 모두 실행한 다음, 이벤트 루프가 한번에 렌더링하므로 최종값만 렌더링. 즉 오른쪽으로 300px갔다가 -500만큼 다시 가는 것이 아니라, 브라우저에서는 처음부터 -200px만큼 이동한 값만 업데이트 된다.

3. window.requestAnimationFrame()

브라우저에게 수행하기를 원하는 애니메이션을 알리고 다음 리페인트가 진행되기 전에 해당 애니메이션을 업데이트하는 함수를 호출하게 한다. 이 메소드는 리페인트 이전에 실행할 콜백을 인자로 받는다.

button.addEventListener('click', () => {
	requestAnimationFrame(() => {
    	document.body.style.backgroundColor = 'red';
    });
  	requestAnimationFrame(() => {
    	document.body.style.backgroundColor = 'orange';
    });
  	requestAnimationFrame(() => {
    	document.body.style.backgroundColor = 'yellow';
    });
});
  • requestAnimationFrame() API는 브라우저에서 다음 렌더링이 발생하기 전에 콜백을 수행하는 것을 보장한다. 따라서 렌더링 전에 모든 콜백함수가 실행된다.
  • 렌더링은 한번에 되기 때문에 가장 마지막으로 실행된 yellow로 색깔이 렌더링된다.


🥞 함수를 계속해서 실행하는 와중에 렌더링을 동시에 처리한다

setTimeout()

function handleClick() {
  console.log('handleClick')
  setTimeout(() => {
    console.log('setTimeout');
    handleClick();
  }, 0);
}

const button = document.querySelector('button');
button.addEventListener('click', () => {
  handleClick();
});
  • 버튼을 클릭하면 handleClick이벤트가 실행된다.
  • 이벤트가 발생했을 때 콜백함수를 webAPI가 task queue에 전달한다.
  • task queue에서 자바스크립트 엔진의 call stack이 비었을 때 함수를 전달해준다.
  • handleClick내부의 setTimeout함수는 web API에 전달되었다가 시간이 지난 후 taskqueue로 전달된다. 이후 call stack에서 실행된다.
  • 계속 이 과정이 반복된다.
  • 중요한 부분은, 이 과정을 끊임 없이 반복하는 와중에도 이벤트 루프는 한번씩 렌더링을 처리한다. 따라서 버튼의 hover효과나, 다른 부분에 대한 렌더링을 동시해 업데이트 할 수 있다.


Reference

profile
Why?에서 시작해 How를 찾는 과정을 좋아합니다. 그 고민과 성장의 과정을 꾸준히 기록하고자 합니다.

0개의 댓글