critical-rendering-path
Q&A 정리: critical-rendering-path
Critical Rendering Path(CRP)란 무엇이며, 어떤 단계로 구성되는가?
브라우저가 HTML, CSS, JavaScript를 화면에 보이는 픽셀로 변환하는 일련의 단계다. 이 과정을 최적화하면 사용자가 웹페이지를 더 빠르게 볼 수 있다.
The Critical Rendering Path is the sequence of steps the browser goes through to convert the HTML, CSS, and JavaScript into pixels on the screen. Optimizing the critical render path improves render performance.
수천 개의 리스트 항목 렌더링 시 성능 문제가 발생하는 이유는?
화면에 표시할 요소(노드)가 많아질수록 브라우저가 각 단계에서 처리해야 할 양이 늘어난다. 수천 개의 리스트 항목은 그만큼 레이아웃 계산과 그리기 작업을 증가시켜 성능 저하를 유발한다.
The greater the number of nodes, the longer the following events in the critical rendering path will take. Measure! A few extra nodes won't make a big difference, but keep in mind that adding many extra nodes will impact performance.
HTML 파싱 중 async나 defer 없는 <script> 태그를 만나면 어떻게 되는가?
이미지 같은 리소스는 HTML 파싱을 멈추지 않지만, async나 defer 속성 없는 스크립트 태그를 만나면 브라우저는 HTML 읽기를 중단하고 스크립트를 먼저 다운로드하고 실행한다. 그동안 화면 렌더링도 멈춘다.
When the HTML parser finds non-blocking resources, such as an image, the browser will request those resources and continue parsing. Parsing can continue when a CSS file is encountered, but
<script>tags—particularly those without an async or defer attribute—blocks rendering, and pauses parsing of HTML.
DOM 트리 구축 중 리소스 다운로드가 지연될 수 있는데, 브라우저는 이를 어떻게 완화하는가?
브라우저는 프리로드 스캐너를 사용해, HTML을 파싱하는 동안 미리 CSS, JavaScript, 폰트 등 중요한 리소스를 백그라운드에서 다운로드한다. 덕분에 파서가 해당 리소스에 도달했을 때 이미 받아져 있거나 받는 중이다.
While the browser builds the DOM tree, this process occupies the main thread. As this happens, the preload scanner will parse through the content available and request high-priority resources like CSS, JavaScript, and web fonts. Thanks to the preload scanner, we don't have to wait until the parser finds a reference to an external resource to request it. It will retrieve resources in the background so that by the time the main HTML parser reaches the requested assets, they may already be in flight or have been downloaded.
<head>에 <link rel="stylesheet">를 넣어도 HTML 파싱을 막지 않는다면, CSS가 JavaScript 실행을 막는 이유는?
CSS 파일은 HTML 파싱을 멈추지는 않지만, JavaScript는 요소의 스타일 정보를 조회하는 경우가 많아 CSS가 완전히 로드될 때까지 JavaScript 실행이 대기한다. CSS가 JavaScript를, JavaScript가 HTML 파싱을 막는 연쇄 차단이 일어나는 것이다.
Parsing can continue when a CSS file is encountered, but
<script>tags—particularly those without an async or defer attribute—blocks rendering, and pauses parsing of HTML. Waiting to obtain CSS doesn't block HTML parsing or downloading, but it does block JavaScript because JavaScript is often used to query CSS properties' impact on elements.
CSSOM(CSS Object Model)이란 무엇이며, DOM과의 관계는?
CSSOM은 CSS를 JavaScript로 읽고 수정할 수 있게 해주는 구조화된 모델이다. HTML이 DOM이라는 트리 구조로 변환되듯, CSS도 CSSOM이라는 트리 구조로 변환되어 브라우저가 스타일을 계산하는 데 사용된다.
The CSS Object Model is a set of APIs allowing the manipulation of CSS from JavaScript. It is much like the DOM, but for the CSS rather than the HTML. It allows users to read and modify CSS style dynamically.
브라우저는 수신한 CSS로 CSSOM 트리를 어떻게 구축하는가?
브라우저는 CSS 규칙을 읽어 부모-자식-형제 관계를 가진 트리 구조로 변환한다. HTML을 DOM으로 변환하는 과정과 동일한 원리로, CSS 선택자의 계층 구조에 따라 노드를 배치한다.
The browser converts the CSS rules into a map of styles it can understand and work with. The browser goes through each rule set in the CSS, creating a tree of nodes with parent, child, and sibling relationships based on the CSS selectors. As with HTML, the browser needs to convert the received CSS rules into something it can work with. Hence, it repeats the HTML-to-object process, but for the CSS.
CSSOM 구축은 성능 병목인가? DevTools에서 어떻게 확인하는가?
CSSOM 구축 자체는 매우 빨라서 성능 병목이 되는 경우는 드물다. 개발자 도구에서는 "Recalculate Style" 항목으로 CSS 파싱과 스타일 계산 시간을 확인할 수 있으며, 보통 DNS 조회 한 번보다도 짧은 시간이 걸린다.
Building the CSSOM is very, very fast, and this build time information is not displayed in the developer tools. Rather, the "Recalculate Style" in developer tools shows the total time it takes to parse CSS, construct the CSSOM tree, and recursively calculate computed styles. In terms of web performance, there are many better ways to invest optimization effort, as the total time to create the CSSOM is generally less than the time it takes for one DNS lookup.
파싱 완료 후 Render Tree는 어떻게 구성되는가?
DOM 트리와 CSSOM 트리를 합쳐 Render Tree를 만든다. Render Tree는 화면에 실제로 보이는 요소들만 포함하며, 각 요소에 어떤 스타일이 적용되는지 계산된 결과를 담고 있다.
The CSSOM and DOM trees created in the parsing step are combined into a render tree which is then used to compute the layout of every visible element, which is then painted to the screen. The computed style tree, or render tree, construction starts with the root of the DOM tree, traversing each visible node. The render tree holds all the visible nodes with content and computed styles — matching up all the relevant styles to every visible node in the DOM tree, and determining, based on the CSS cascade, what the computed styles are for each node.
Render Tree에서 display: none과 visibility: hidden은 어떻게 다르게 처리되는가?
display: none은 요소를 Render Tree에서 완전히 제외하여 공간도 차지하지 않는다. 반면 visibility: hidden은 요소가 보이지는 않지만 Render Tree에 포함되어 공간을 그대로 차지한다. 투명인간이 자리를 차지하고 있는 것과 아예 없는 것의 차이다.
Elements that aren't going to be displayed, like the
<head>element and its children and any nodes withdisplay: none, such as thescript { display: none; }you will find in user agent stylesheets, are not included in the render tree as they will not appear in the rendered output. Nodes withvisibility: hiddenapplied are included in the render tree, as they do take up space.
Render Tree 구축 후 Layout 단계에서 브라우저는 무엇을 하는가?
Layout 단계에서 브라우저는 Render Tree의 모든 요소에 대해 화면에서의 정확한 위치와 크기를 계산한다. 뷰포트(화면 크기)를 기준으로 body부터 시작해 자식 요소들의 크기와 위치를 순서대로 결정해 나간다.
Layout is the process by which the dimensions and location of all the nodes in the render tree are determined, plus the determination of the size and position of each object on the page. Taking the size of the viewport as its base, layout generally starts with the body, laying out the sizes of all the body's descendants, with each element's box model properties, providing placeholder space for replaced elements it doesn't know the dimensions of, such as our image.
Layout과 Reflow의 차이는 무엇이고, Reflow는 왜 발생하는가?
처음 요소들의 크기와 위치를 계산하는 것이 Layout이고, 이후 변경이 생겨 다시 계산하는 것이 Reflow다. 예를 들어 이미지 크기를 지정하지 않으면 이미지가 로드된 후 크기가 확정되면서 Reflow가 발생한다.
The first time the size and position of each node is determined is called layout. Subsequent recalculations of layout are called reflows. In our example, suppose the initial layout occurs before the image is returned. Since we didn't declare the dimensions of our image, there will be a reflow once the image dimensions are known.
부드러운 애니메이션을 위해 브라우저는 한 프레임을 몇 밀리초 안에 완료해야 하며, Paint 성능을 개선하는 전략은?
60fps 부드러운 애니메이션을 위해 한 프레임을 약 16.67ms 안에 완료해야 한다. 성능 개선을 위해 특정 요소를 별도의 GPU 레이어로 승격시키면, CPU 대신 GPU가 그리기를 담당하여 Paint 속도가 빨라진다.
To ensure smooth scrolling and animation, everything occupying the main thread, including calculating styles, along with reflow and paint, must take the browser less than 16.67ms to accomplish. Painting can break the elements in the layout tree into layers. Promoting content into layers on the GPU (instead of the main thread on the CPU) improves paint and repaint performance. There are specific properties and elements that instantiate a layer, including
<video>and<canvas>, and any element which has the CSS properties of opacity, a 3D transform, will-change, and a few others.
GPU 레이어를 더 많이 만들면 항상 성능이 좋아지는가?
아니다. 레이어는 각각 메모리를 소비하기 때문에, 무분별하게 늘리면 오히려 메모리 부족으로 성능이 나빠질 수 있다. 레이어 승격은 꼭 필요한 곳에만 적용하는 것이 중요하다.
Layers do improve performance but are expensive when it comes to memory management, so should not be overused as part of web performance optimization strategies.