--- title: 12 Rendering Panel --- # Chrome DevTools: Rendering Panel ## What the Rendering Panel Is The Rendering panel is a diagnostic overlay toolkit built into Chrome DevTools. It does not show you source code or network requests — it visualizes what the browser's rendering engine is doing at runtime. Every frame your browser draws involves a pipeline of discrete stages: style calculation, layout, paint, and compositing. The Rendering panel lets you watch those stages in real time, highlight expensive operations, emulate visual accessibility conditions, and catch layout shifts as they happen. This panel is the primary tool for answering questions like: - Why does scrolling feel janky? - Which elements are being repainted on every frame? - What is causing my Cumulative Layout Shift score to be high? - How many GPU layers is my page using? - Does my dark mode implementation actually work correctly? - Is my site usable by someone with color blindness? The panel exposes toggles that add visual overlays directly on top of your running page, so you see the effects in context without leaving the browser. --- ## How to Open It **Method 1 — More Tools menu:** 1. Open DevTools (`F12` or `Cmd+Option+I` on Mac, `Ctrl+Shift+I` on Windows/Linux). 2. Click the three-dot menu (`...`) in the top-right corner of the DevTools panel. 3. Hover over **More tools**. 4. Click **Rendering**. The Rendering panel appears as a drawer at the bottom of DevTools. **Method 2 — Command Menu (fastest):** 1. Open DevTools. 2. Press `Cmd+Shift+P` (Mac) or `Ctrl+Shift+P` (Windows/Linux) to open the Command Menu. 3. Type `rendering` and select **Show Rendering**. **Method 3 — Drawer tab:** If you have previously opened the Rendering panel, it persists as a tab in the DevTools drawer. Press `Escape` to toggle the drawer, then click the **Rendering** tab. --- ## UI Layout (All Toggles Listed) When the Rendering panel is open you see a scrollable list of checkboxes and dropdowns. As of Chrome 120+, the full list is: | Toggle / Control | Type | |---|---| | Paint flashing | Checkbox | | Layout Shift Regions | Checkbox | | Layer borders | Checkbox | | Frame Rendering Stats (FPS meter) | Checkbox | | Scrolling performance issues | Checkbox | | Highlight ad frames | Checkbox | | Hit-test borders | Checkbox | | Core Web Vitals | Checkbox | | Disable local fonts | Checkbox | | Emulate a focused page | Checkbox | | Emulate CSS media feature prefers-color-scheme | Dropdown | | Emulate CSS media feature prefers-reduced-motion | Dropdown | | Emulate CSS media feature prefers-reduced-transparency | Dropdown | | Emulate CSS media feature prefers-contrast | Dropdown | | Emulate CSS media feature forced-colors | Dropdown | | Emulate CSS media feature prefers-reduced-data | Dropdown | | Emulate CSS media feature color-gamut | Dropdown | | Emulate vision deficiencies | Dropdown | All toggles are independent. You can enable multiple at once. Overlays are drawn on top of your page content in real time; they do not affect what users see in production. --- ## Paint Flashing (Green Overlay) **What it shows:** Every time the browser needs to repaint a region of the page, that region flashes green for one frame. A steady green flash on every scroll frame is a warning sign. ### What triggers a repaint The browser has to repaint any area where pixels need to change. This is triggered by CSS property changes that affect how an element looks but not its position or geometry within the paint stage: - `color` — text color changed - `background-color` / `background-image` — background changed - `box-shadow` — shadow added or animated - `border-color` — border color changed - `visibility: hidden` toggled — the space is kept but pixels change - `outline` changes - `text-decoration` changes - Any pseudo-element content that changes (`:hover` state with color transitions) Repaints are also triggered by layout changes (since layout feeds into paint), but paint flashing specifically highlights the paint stage. ### Reading the overlay - **Small, infrequent flashes** — acceptable. A button that flashes green when hovered is normal. - **Large portions of the page flashing on every scroll event** — problematic. It means the browser is repainting large areas 60 times per second during scroll. - **The entire viewport flashing** — often caused by a fixed-position element with a `background-color` that participates in scrolling recompositing. ### How to reduce repaints **Use `transform` and `opacity` for animations instead of properties that trigger paint:** ```css /* Bad — triggers paint on every frame */ .animated-box { transition: background-color 300ms ease, left 300ms ease; } /* Good — compositor-only, no paint needed */ .animated-box { transition: transform 300ms ease, opacity 300ms ease; } ``` **Avoid changing `background-color` on scroll:** ```javascript // Bad — causes repaint on every scroll event window.addEventListener('scroll', () => { header.style.backgroundColor = window.scrollY > 100 ? '#fff' : 'transparent'; }); // Better — use a CSS class toggle, and ensure the class change only affects // compositor-friendly properties, or batch the style change with requestAnimationFrame window.addEventListener('scroll', () => { requestAnimationFrame(() => { header.classList.toggle('scrolled', window.scrollY > 100); }); }, { passive: true }); ``` **Contain paint to smaller areas using `contain: paint`:** ```css /* Tells the browser this element's paint is independent */ .card { contain: paint; } ``` With `contain: paint`, a repaint inside `.card` does not invalidate paint outside it. **Promote elements that animate frequently to their own compositor layer:** ```css .frequently-animated { will-change: transform; } ``` Once on its own layer, that element can be moved by the compositor thread without a paint step. See the Layer Borders and `will-change` sections for full details. --- ## Layout Shift Regions (Blue Overlay) **What it shows:** Elements that shift their position unexpectedly flash blue. This directly visualizes the browser's CLS (Cumulative Layout Shift) scoring — every blue flash corresponds to a layout shift event that would contribute to your CLS score. ### What CLS measures CLS is a Core Web Vitals metric. It measures the total visual instability of a page. A score below 0.1 is good, 0.1–0.25 needs improvement, and above 0.25 is poor. Each layout shift event contributes an impact fraction (how much of the viewport moved) multiplied by a distance fraction (how far it moved). ### Finding what elements shift and when 1. Enable **Layout Shift Regions** in the Rendering panel. 2. Load or interact with your page. 3. Watch for blue overlays. The flash is brief, so for content that loads asynchronously you may need to: - Throttle the network in the Network panel to slow down resource loading. - Use the Performance panel simultaneously to record a timeline and inspect layout shift events in detail. 4. Note which element flashed. Open the Elements panel and inspect it. Common culprits: - Images without explicit `width` and `height` attributes. - Ads injected by third-party scripts. - Web fonts that cause text reflow (FOUT — Flash of Unstyled Text). - Dynamic banners or cookie consent bars inserted at the top of the page after initial paint. - Embeds (iframes, videos) without reserved dimensions. ### Fixing layout shifts **Reserve space for images and video with explicit dimensions:** ```html Hero image Hero image ``` For responsive images, use the CSS `aspect-ratio` property: ```css img { width: 100%; aspect-ratio: 16 / 9; height: auto; } ``` **Reserve space for ads and embeds:** ```css .ad-slot { min-height: 250px; /* reserve the expected ad height */ width: 300px; } ``` **Avoid inserting content above existing content:** ```javascript // Bad — inserts a banner at the top, pushing all content down document.body.insertBefore(banner, document.body.firstChild); // Better — use a placeholder that was already in the DOM const placeholder = document.getElementById('banner-slot'); placeholder.appendChild(banner); ``` **Handle web fonts to prevent reflow:** ```css /* Use font-display: optional to prevent FOUT-driven shifts */ @font-face { font-family: 'MyFont'; src: url('/fonts/myfont.woff2') format('woff2'); font-display: optional; } ``` Or preload critical fonts: ```html ``` --- ## Layer Borders (Orange/Olive Borders) **What it shows:** Orange borders highlight GPU compositing layers. Olive/yellow borders highlight tiles (subdivisions within layers used by the compositor). Each distinct bordered region is being composited independently by the GPU. ### GPU compositing layers — what they are The browser divides the rendered page into layers. Think of them as transparent acetate sheets stacked on top of each other. Each layer is uploaded to the GPU as a texture. When the compositor needs to update the page (for example, during a scroll or a CSS `transform` animation), it can reposition and blend those textures on the GPU without asking the main thread to recalculate anything. This is why smooth 60fps animations are possible even when JavaScript is busy: the compositor thread on the GPU continues drawing frames independently. ### Why layers matter: compositor thread vs main thread | Thread | Handles | Can be blocked by | |---|---|---| | Main thread | JavaScript, Style, Layout, Paint | Long JS tasks, heavy style recalculation | | Compositor thread | Compositing, scrolling, transform/opacity animations | Almost nothing — it runs independently | When an animation only requires compositing (not layout or paint), it runs entirely on the compositor thread. This is the reason `transform` and `opacity` are the gold-standard animation properties. ### What promotes an element to its own compositor layer The browser decides which elements get their own layer. You can influence this, but the browser may override your hints. Elements that typically get their own layer: - **`transform` property** — especially 3D transforms like `translateZ(0)` or `translate3d(0,0,0)`. - **`opacity` less than 1** — if animated or transitioned. - **`will-change: transform` or `will-change: opacity`** — explicit hint to the browser. - **`position: fixed`** — fixed elements composite separately from the scroll layer. - **`