{
    "componentChunkName": "component---src-templates-blog-post-js",
    "path": "/21-10-19-event-loop-raf/",
    "result": {"data":{"site":{"siteMetadata":{"title":"irrationnelle","author":"irrationnelle","siteUrl":"https://dev.rase.blog","comment":{"disqusShortName":"","utterances":"irrationnelle/devlog"},"sponsor":{"buyMeACoffeeId":""}}},"markdownRemark":{"id":"69ba0c61-2d6c-5ae4-87c1-8be349bc0b0c","excerpt":"이벤트 루프 자바스크립트는 기본적으로 싱글스레드에서 작동한다. 그래서 콜스택에 처리할 연산 목록을 쌓아두어 차례차례 실행한다. 콜스택에 연산 목록과 별개로 브라우저 API 요청이 있으면, 우선순위 queue 에다가 보관해놓고 콜스택을 비운 뒤 각 queue 에서 이벤트 루프가 연산들을 가져간다. 이 queue 에는 task queue, microtask queue, animation frame 등이 있다. requestAnimationFrame setInterval…","html":"<h2 id=\"이벤트-루프\" style=\"position:relative;\"><a href=\"#%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84\" aria-label=\"이벤트 루프 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>이벤트 루프</h2>\n<p>자바스크립트는 기본적으로 싱글스레드에서 작동한다.</p>\n<p>그래서 콜스택에 처리할 연산 목록을 쌓아두어 차례차례 실행한다.</p>\n<p>콜스택에 연산 목록과 별개로 브라우저 API 요청이 있으면,</p>\n<p>우선순위 queue 에다가 보관해놓고</p>\n<p>콜스택을 비운 뒤 각 queue 에서 이벤트 루프가 연산들을 가져간다.</p>\n<p>이 queue 에는 task queue, microtask queue, animation frame 등이 있다.</p>\n<h2 id=\"requestanimationframe\" style=\"position:relative;\"><a href=\"#requestanimationframe\" aria-label=\"requestanimationframe permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>requestAnimationFrame</h2>\n<p>setInterval 보다 성능이 좋다고 한다.</p>\n<p>이유는 setInterval 자체가 그리 정확하게 작동하지 않는 것도 있고</p>\n<p>두번째 인자로 전달하는 interval 값이 사용자가 느끼기엔 어색한 빈도일 수 있기 때문.</p>\n<p>하지만 requestAnimationFrame 은 브라우저가 현재 디스플레이 환경에 맞춰</p>\n<p>최적의 빈도로 실행을 한다.</p>\n<p>디스플레이 환경에 맞춘다는 것은, 모니터가 초당 60프레임으로 움직임을 보여준다면 requestAnimationFrame 도 초당 60프레임으로 작동한다는 것이다.</p>\n<h2 id=\"queue-우선-순위\" style=\"position:relative;\"><a href=\"#queue-%EC%9A%B0%EC%84%A0-%EC%88%9C%EC%9C%84\" aria-label=\"queue 우선 순위 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>queue 우선 순위</h2>\n<p>일반적으로 이벤트 루프가 콜스택에 무엇을 채워넣을지 결정할 때, microtask 를 가장 먼저 처리한다고 한다.</p>\n<p>microtask 로는 promise 등이 속한다. setTimeout 같은 건 그냥 task.</p>\n<p>그 후에는 animation frame 에 속하는 연산을 처리하는데, 이게 바로 rAF 의 첫번재 인자로 전달하는 콜백이다.</p>\n<p>근데 때로는 task queue 에 있는 작업을 먼저 수행하기도 한다고 하는데</p>\n<p>이거 때문에 누구 말이 맞나 꽤 혼란스러웠다.</p>\n<p>결론은 우선순위는 animation frame 이 먼저이지만,</p>\n<p>앞서 예시를 든 환경이라면 초당 60프레임으로 보여주는 상황을 잘 충족하고 있다면</p>\n<p>우선순위를 task queue 에게 양보하기도 한다는 것.</p>\n<h2 id=\"requestanimationframe-추가\" style=\"position:relative;\"><a href=\"#requestanimationframe-%EC%B6%94%EA%B0%80\" aria-label=\"requestanimationframe 추가 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>requestAnimationFrame 추가</h2>\n<p>브라우저가 작동할 때 reflow 후에 repaint 를 하는데</p>\n<p>rAF 는 reflow 가 아니라 repaint 에 관여를 한다.</p>\n<p>프로그레스바 같은 것이 채워지는 것도 width 나 height 가 길어진다고 생각해서</p>\n<p>reflow 라고 생각할 수 있지만, repaint 임을 명심하자.</p>\n<h2 id=\"나중에-공부하려고-남기는-레퍼런스-링크\" style=\"position:relative;\"><a href=\"#%EB%82%98%EC%A4%91%EC%97%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%A0%A4%EA%B3%A0-%EB%82%A8%EA%B8%B0%EB%8A%94-%EB%A0%88%ED%8D%BC%EB%9F%B0%EC%8A%A4-%EB%A7%81%ED%81%AC\" aria-label=\"나중에 공부하려고 남기는 레퍼런스 링크 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>나중에 공부하려고 남기는 레퍼런스 링크</h2>\n<p><a href=\"https://www.w3.org/TR/animation-timing/#dom-windowanimationtiming-requestanimationframe\">https://www.w3.org/TR/animation-timing/#dom-windowanimationtiming-requestanimationframe</a></p>\n<p>이 포스팅에서 정리한 것들은 이 레퍼런스 글이 아니라 여기저기서 지식을 주워담은 것을 정리한 것이다.</p>","frontmatter":{"title":"event loop 와 requestAnimationFrame","date":"October 19, 2021"}}},"pageContext":{"slug":"/21-10-19-event-loop-raf/","previous":{"fields":{"slug":"/21-10-07-context-and-state-management/"},"frontmatter":{"title":"React 에서 Context API 와 상태관리","category":"react","draft":false}},"next":{"fields":{"slug":"/21-10-29-firebase-emulator-test/"},"frontmatter":{"title":"firebase 에뮬레이터로 테스트 코드 작성하기","category":"dev","draft":false}}}},
    "staticQueryHashes": ["3128451518","3474900066"]}