[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"quiz-css-will-change-performance-hint":44,"search-suggestions":60,"quiz-article-css-will-change-performance-hint":107},[4,20,32],{"id":5,"slug":6,"name":7,"tagline":8,"description":9,"accentFrom":10,"accentTo":11,"icon":12,"defaultLocale":13,"locales":14,"features":16,"position":19},"019fe637-3d33-714b-b57f-23e163ffca0c","dev","Web Development","Read it. Run it. Prove it.","A post a day on modern web development — most with an editable playground and a quiz that explains every answer. Free, no account needed.","violet-500","cyan-400","◇","en",[13,15],"fa",{"courses":17,"paths":17,"articles":17,"exams":18,"flashcards":18,"packages":17,"community":17,"certificates":17,"teams":17,"commerce":17},true,false,0,{"id":21,"slug":22,"name":23,"tagline":24,"description":25,"accentFrom":26,"accentTo":10,"icon":27,"defaultLocale":13,"locales":28,"features":30,"position":31},"019fe637-3dc2-754c-8657-0f175bfee7c6","lang","Languages","Learn a language the way you learn a codebase.","Grammar explained the way good documentation explains an API — one idea at a time, each with a quiz.","amber-400","⌘",[13,15,29],"es",{"courses":18,"paths":18,"articles":17,"exams":18,"flashcards":17,"packages":18,"community":17,"certificates":17,"teams":18,"commerce":18},2,{"id":33,"slug":34,"name":35,"tagline":36,"description":37,"accentFrom":38,"accentTo":39,"icon":40,"defaultLocale":13,"locales":41,"features":42,"position":43},"7b3c16f2-931d-410e-802e-e1fa4edab7de","soft","Soft Skills","The half of the job nobody wrote documentation for.","Weekly, on the parts of working life that decide more than your code does — first weeks, meetings, interviews, promotions, and the people around you. Written from what actually happens, and recorded as a podcast you can listen to on the walk.","emerald-400","teal-300","◉",[13],{"courses":18,"paths":18,"articles":17,"exams":18,"flashcards":18,"packages":18,"community":17,"certificates":18,"teams":18,"commerce":18},3,{"id":45,"slug":46,"kind":47,"title":48,"description":49,"config":50,"verticalId":5,"vertical":55,"course":52,"_count":56,"access":57,"attempts":59,"questionCount":51},"01a10aaf-5fa3-75db-8a72-9d48bb1edb99","css-will-change-performance-hint","PRACTICE_QUIZ","will-change — test yourself","Eight questions on what will-change actually promises the browser, why broad or permanent use backfires, and the narrow, temporary pattern that holds up.",{"questionCount":51,"timeLimitSec":52,"shuffleQuestions":18,"shuffleOptions":17,"negativeMarking":19,"passScorePct":53,"maxAttempts":52,"revealAnswers":54,"allowFlagging":18,"allowBacktracking":17},8,null,70,"AFTER_SUBMIT",{"slug":6,"name":7},{"questions":51},{"allowed":17,"reason":58},"FREE",[],[61,65,69,73,77,81,85,89,93,97,100,104],{"slug":62,"name":63,"articles":64},"webdev","Webdev",131,{"slug":66,"name":67,"articles":68},"javascript","Javascript",107,{"slug":70,"name":71,"articles":72},"frontend","Frontend",82,{"slug":74,"name":75,"articles":76},"tutorial","Tutorial",50,{"slug":78,"name":79,"articles":80},"css","Css",42,{"slug":82,"name":83,"articles":84},"typescript","Typescript",18,{"slug":86,"name":87,"articles":88},"performance","Performance",17,{"slug":90,"name":91,"articles":92},"react","React",16,{"slug":94,"name":95,"articles":96},"browser","Browser",12,{"slug":98,"name":99,"articles":96},"node","Node",{"slug":101,"name":102,"articles":103},"html","Html",9,{"slug":105,"name":106,"articles":103},"accessibility","Accessibility",{"id":108,"slug":46,"title":109,"subtitle":52,"excerpt":110,"coverUrl":111,"locale":13,"readingMinutes":112,"publishedAt":113,"viewCount":114,"likeCount":19,"commentCount":19,"author":115,"vertical":120,"topic":121,"tags":123,"_count":128,"playground":130,"body":132,"bodyMd":272,"seo":273,"translationGroupId":276,"series":52,"podcastUrl":52,"verticalId":5,"thread":277,"assessments":279,"translations":282,"quiz":284},"01a10aaf-5ec4-700b-bbd2-5fc17c27d4e0","You Added `will-change` to Fix the Jank. You Made It Worse.","will-change: transform looks like a free performance switch. Applied broadly or left on permanently, it does the opposite — here's the narrow, temporary pattern that actually works.","\u002Fmedia\u002Fcovers\u002Fcss-will-change-performance-hint.png",5,"2026-10-10T12:12:00.282Z",29,{"id":116,"name":117,"username":118,"avatarUrl":52,"headline":119},"019fe637-3c25-7088-9034-39c9f15dc3c8","Parsa Jiravand","parsa","Frontend engineer · building bestpractic",{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":78,"name":122},"CSS",[124,125,126,127],{"slug":78,"name":79,"color":52},{"slug":86,"name":87,"color":52},{"slug":62,"name":63,"color":52},{"slug":70,"name":71,"color":52},{"assessments":129},1,{"slug":46,"title":131},"will-change — interactive playground",{"blocks":133,"version":129},[134,138,141,144,149,152,157,160,163,166,169,172,175,178,181,186,189,192,195,198,201,204,208,211,214,217,220,223,226,229,232,235,238,241,244,247,254,257,260,263,266],{"id":135,"html":136,"type":137},"b1","\u003Cp>Open DevTools on almost any site that&#39;s been &quot;optimized&quot; for animation and check the \u003Cstrong>Layers\u003C\u002Fstrong> panel. There&#39;s a decent chance half the card grid, the nav, a modal backdrop, and a few \u003Ccode>div\u003C\u002Fcode>s nobody can explain are each sitting in their own compositor layer — because at some point, someone added \u003Ccode>will-change: transform\u003C\u002Fcode> to fix a stutter, and it never came back off.\u003C\u002Fp>","paragraph",{"id":139,"html":140,"type":137},"b2","\u003Cp>The property does exactly what it promises, which is the whole problem. Set it on one element, right before that element animates, and the browser can promote it to the GPU ahead of time instead of scrambling mid-animation. The jank goes away. That&#39;s a real, measurable win — and it&#39;s also the exact experience that teaches people the wrong lesson: \u003Cstrong>\u003Ccode>will-change\u003C\u002Fcode> makes animations smooth, so sprinkle it wherever something moves.\u003C\u002Fstrong>\u003C\u002Fp>",{"id":142,"html":143,"type":137},"b3","\u003Cp>That&#39;s the myth. It falls apart the moment it meets a loop.\u003C\u002Fp>",{"id":145,"html":146,"text":147,"type":148,"level":31},"b4","The rule that&#39;s correct on one element and wrong on two hundred","The rule that's correct on one element and wrong on two hundred","heading",{"id":150,"html":151,"type":137},"b5","\u003Cp>Here&#39;s the version that ships after someone reads &quot;just add \u003Ccode>will-change\u003C\u002Fcode>&quot;:\u003C\u002Fp>",{"id":153,"code":154,"type":155,"language":78,"highlight":156},"b6",".card {\n  will-change: transform;\n}","code",[],{"id":158,"html":159,"type":137},"b7","\u003Cp>If your page has one \u003Ccode>.card\u003C\u002Fcode>, this is fine — arguably exactly right. If \u003Ccode>.card\u003C\u002Fcode> is a grid of 200 dashboard tiles, this rule now applies to all 200 of them, permanently, the moment the stylesheet loads. Not &quot;while hovering.&quot; Not &quot;while animating.&quot; Forever, whether that card has moved once or never.\u003C\u002Fp>",{"id":161,"html":162,"type":137},"b8","\u003Cp>Each one of those 200 elements is a standing request to the browser: keep a compositor layer ready for this, indefinitely, just in case. \u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FCSS\u002Fwill-change\">MDN is direct about what that costs\u003C\u002Fa>: &quot;overusing the property can cause the page to slow down instead of improving its performance,&quot; and the fix is to use it &quot;sparingly,&quot; on &quot;deeply nested elements, containing as little of the document as possible&quot; — the opposite of a blanket rule on a repeated class. The \u003Ca href=\"https:\u002F\u002Fwww.w3.org\u002FTR\u002Fcss-will-change-1\u002F\">CSS spec\u003C\u002Fa> puts the extreme case more bluntly: push it far enough and it &quot;can cause the page to slow down or even crash.&quot;\u003C\u002Fp>",{"id":164,"html":165,"type":137},"b9","\u003Cp>There&#39;s also a version of this mistake the browser won&#39;t even let you make: \u003Ccode>will-change: all\u003C\u002Fcode> looks tempting as a catch-all, but it&#39;s explicitly disallowed in the spec, specifically so people can&#39;t do what the \u003Ccode>.card\u003C\u002Fcode> rule above does by accident with a long, honest property list instead.\u003C\u002Fp>",{"id":167,"html":168,"text":168,"type":148,"level":31},"b10","Why the wrong lesson feels right",{"id":170,"html":171,"type":137},"b11","\u003Cp>Nobody adds \u003Ccode>will-change\u003C\u002Fcode> to be reckless. They add it to one laggy modal, watch the animation go from choppy to smooth in DevTools, and reasonably conclude: more of this, applied more broadly, should help more. The demo that teaches the property is always a single element. The failure only shows up at scale, after the feature ships, on a machine with less GPU memory than whoever wrote the CSS was testing on — which is exactly the kind of bug report that never says &quot;it&#39;s the \u003Ccode>will-change\u003C\u002Fcode> rule&quot; in the subject line.\u003C\u002Fp>",{"id":173,"html":174,"text":174,"type":148,"level":31},"b12","The mental model that actually holds up: a promise, not a setting",{"id":176,"html":177,"type":137},"b13","\u003Cp>\u003Ccode>will-change\u003C\u002Fcode> isn&#39;t a performance mode you flip on. It&#39;s a \u003Cstrong>promise to the browser\u003C\u002Fstrong>, and like any promise, breaking it has a cost. &quot;This specific element&#39;s \u003Ccode>transform\u003C\u002Fcode> is about to change&quot; is a promise you can keep for one element for a few hundred milliseconds. &quot;Every card in this grid might change at some unknown point&quot; is a promise you can&#39;t keep, and the browser ends up paying for the ones you broke.\u003C\u002Fp>",{"id":179,"html":180,"type":137},"b14","\u003Cp>The pattern that holds up adds the hint in JavaScript, right before the change, and removes it right after:\u003C\u002Fp>",{"id":182,"code":183,"type":155,"language":184,"highlight":185},"b15","const card = document.querySelector(\".card\");\n\ncard.addEventListener(\"pointerenter\", () => {\n  card.style.willChange = \"transform\";\n});\n\ncard.addEventListener(\"transitionend\", () => {\n  card.style.willChange = \"auto\";\n});","js",[],{"id":187,"html":188,"type":137},"b16","\u003Cp>Now the browser only reserves a layer for the exact window where it&#39;s useful — from the moment you signal intent to the moment the transition actually finishes — and gives that memory back immediately after. One card hovered is one layer, briefly. Two hundred cards sitting untouched are two hundred cards costing nothing.\u003C\u002Fp>",{"id":190,"html":191,"type":137},"b17","\u003C!-- playground:start -->",{"id":193,"html":194,"text":194,"type":148,"level":31},"b18","🎮 Try it yourself",{"id":196,"html":197,"type":137},"b19","\u003Cp>\u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcss-will-change-performance-hint\u002Fplayground\">▶️ Open the interactive playground →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":199,"html":200,"type":137},"b20","\u003Cp>\u003Cem>Runs right in your browser — poke at it and watch the concept react live.\u003C\u002Fem>\u003C\u002Fp>",{"id":202,"html":203,"type":137},"b21","\u003C!-- playground:end -->",{"id":205,"html":206,"text":207,"type":148,"level":31},"b22","When the old way — no \u003Ccode>will-change\u003C\u002Fcode> at all — is the right call","When the old way — no will-change at all — is the right call",{"id":209,"html":210,"type":137},"b23","\u003Cp>Most elements on most pages don&#39;t need this property, full stop. Browsers already run their own heuristics for promoting layers around \u003Ccode>transform\u003C\u002Fcode> and \u003Ccode>opacity\u003C\u002Fcode> changes, and for a single button or a handful of elements, those heuristics are usually good enough on their own. \u003Ccode>will-change\u003C\u002Fcode> is specifically for the case you&#39;ve already profiled: you opened the \u003Cstrong>Performance\u003C\u002Fstrong> or \u003Cstrong>Layers\u003C\u002Fstrong> panel, watched a specific element genuinely struggle, and confirmed a manual hint fixes it. MDN&#39;s own framing is &quot;use it as a last resort to deal with existing performance problems&quot; — never &quot;add it in advance in case one shows up.&quot; If you haven&#39;t profiled anything yet, you don&#39;t have evidence \u003Ccode>will-change\u003C\u002Fcode> is the fix; you have a hunch, and hunches are how a stylesheet ends up with a permanent rule on \u003Ccode>.card\u003C\u002Fcode>.\u003C\u002Fp>",{"id":212,"html":213,"text":213,"type":148,"level":31},"b24","The honest caveat",{"id":215,"html":216,"type":137},"b25","\u003Cp>\u003Ccode>will-change\u003C\u002Fcode> doesn&#39;t make anything \u003Cem>faster\u003C\u002Fem> in the way a code change makes a function faster — it changes \u003Cem>when\u003C\u002Fem> the browser pays a cost it was always going to pay, trading a little memory for a smoother first frame. On a memory-constrained device, that trade can go the other way: enough simultaneous layers and you&#39;re not avoiding jank, you&#39;re causing it, just somewhere else in the pipeline. The fix for &quot;I added \u003Ccode>will-change\u003C\u002Fcode> and it&#39;s still janky&quot; is often &quot;remove \u003Ccode>will-change\u003C\u002Fcode> and check whether you&#39;re promoting too much at once&quot; — not &quot;add more of it.&quot;\u003C\u002Fp>",{"id":218,"html":219,"text":219,"type":148,"level":31},"b26","The takeaway",{"id":221,"html":222,"type":137},"b27","\u003Cp>\u003Ccode>will-change\u003C\u002Fcode> works exactly as advertised on exactly as much as you apply it to. The mistake was never the property — it was treating a scoped, temporary hint like a global setting you set once and forget. Scope it to the element that&#39;s actually changing, add it right before the change, take it back off right after, and you get the smooth animation without two hundred standing GPU layers paying for cards that never moved.\u003C\u002Fp>",{"id":224,"html":225,"type":137},"b28","\u003Cp>Go check your own stylesheet for a bare \u003Ccode>will-change\u003C\u002Fcode> sitting on a class that matches more than one element — how many of those elements have actually animated today?\u003C\u002Fp>",{"id":227,"html":228,"type":137},"b29","\u003C!-- quiz:start -->",{"id":230,"html":231,"text":231,"type":148,"level":31},"b30","🧠 Test yourself",{"id":233,"html":234,"type":137},"b31","\u003Cp>Think it clicked? \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcss-will-change-performance-hint\u002Fquiz\">Take the 8-question quiz →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":236,"html":237,"type":137},"b32","\u003Cp>\u003Cem>Instant feedback, a hint on every question, and an explanation for each answer — right or wrong.\u003C\u002Fem>\u003C\u002Fp>",{"id":239,"html":240,"type":137},"b33","\u003C!-- quiz:end -->",{"id":242,"html":243,"type":137},"b34","\u003C!-- related:start -->",{"id":245,"html":246,"text":246,"type":148,"level":31},"b35","📚 Read next",{"id":248,"type":249,"items":250,"ordered":18},"b36","list",[251,252,253],"\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcontent-visibility-skip-offscreen-rendering\">Your browser renders everything, even what you can&#39;t see — \u003Ccode>content-visibility: auto\u003C\u002Fcode> fixes that\u003C\u002Fa>","\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fmutation-observer-dom-change-detection\">You&#39;re polling setInterval to detect DOM changes. \u003Ccode>MutationObserver\u003C\u002Fcode> fires when they happen.\u003C\u002Fa>","\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Frequestidlecallback-can-wait-forever\">The Background Task That Waited 40 Seconds for &#39;Idle&#39;\u003C\u002Fa>",{"id":255,"html":256,"type":137},"b37","\u003C!-- related:end -->",{"id":258,"type":259},"b38","divider",{"id":261,"html":262,"type":137},"b39","\u003Cp>🚀 \u003Cstrong>Want more like this?\u003C\u002Fstrong> Every guide, playground, and quiz lives on \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002F\">bestpractic.org\u003C\u002Fa>\u003C\u002Fstrong> — open it and \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002F\">sign up free\u003C\u002Fa>\u003C\u002Fstrong> so the next one finds you.\u003C\u002Fp>",{"id":264,"html":265,"type":137},"b40","\u003Cp>\u003Cem>Thanks for reading! Let&#39;s stay connected:\u003C\u002Fem>\u003C\u002Fp>",{"id":267,"type":249,"items":268,"ordered":18},"b41",[269,270,271],"⭐ \u003Cstrong>GitHub\u003C\u002Fstrong> — follow me and star the projects: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fparsajiravand\">github.com\u002Fparsajiravand\u003C\u002Fa>","💬 \u003Cstrong>Discord\u003C\u002Fstrong> — join the frontend best-practices community: \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ\">discord.gg\u002Fd9KRhuAwQ\u003C\u002Fa>","📸 \u003Cstrong>Instagram\u003C\u002Fstrong> — frontend best practices, daily: \u003Ca href=\"https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F\">@bestpractice___\u003C\u002Fa>","Open DevTools on almost any site that's been \"optimized\" for animation and check the **Layers** panel. There's a decent chance half the card grid, the nav, a modal backdrop, and a few `div`s nobody can explain are each sitting in their own compositor layer — because at some point, someone added `will-change: transform` to fix a stutter, and it never came back off.\n\nThe property does exactly what it promises, which is the whole problem. Set it on one element, right before that element animates, and the browser can promote it to the GPU ahead of time instead of scrambling mid-animation. The jank goes away. That's a real, measurable win — and it's also the exact experience that teaches people the wrong lesson: **`will-change` makes animations smooth, so sprinkle it wherever something moves.**\n\nThat's the myth. It falls apart the moment it meets a loop.\n\n## The rule that's correct on one element and wrong on two hundred\n\nHere's the version that ships after someone reads \"just add `will-change`\":\n\n```css\n.card {\n  will-change: transform;\n}\n```\n\nIf your page has one `.card`, this is fine — arguably exactly right. If `.card` is a grid of 200 dashboard tiles, this rule now applies to all 200 of them, permanently, the moment the stylesheet loads. Not \"while hovering.\" Not \"while animating.\" Forever, whether that card has moved once or never.\n\nEach one of those 200 elements is a standing request to the browser: keep a compositor layer ready for this, indefinitely, just in case. [MDN is direct about what that costs](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FCSS\u002Fwill-change): \"overusing the property can cause the page to slow down instead of improving its performance,\" and the fix is to use it \"sparingly,\" on \"deeply nested elements, containing as little of the document as possible\" — the opposite of a blanket rule on a repeated class. The [CSS spec](https:\u002F\u002Fwww.w3.org\u002FTR\u002Fcss-will-change-1\u002F) puts the extreme case more bluntly: push it far enough and it \"can cause the page to slow down or even crash.\"\n\nThere's also a version of this mistake the browser won't even let you make: `will-change: all` looks tempting as a catch-all, but it's explicitly disallowed in the spec, specifically so people can't do what the `.card` rule above does by accident with a long, honest property list instead.\n\n## Why the wrong lesson feels right\n\nNobody adds `will-change` to be reckless. They add it to one laggy modal, watch the animation go from choppy to smooth in DevTools, and reasonably conclude: more of this, applied more broadly, should help more. The demo that teaches the property is always a single element. The failure only shows up at scale, after the feature ships, on a machine with less GPU memory than whoever wrote the CSS was testing on — which is exactly the kind of bug report that never says \"it's the `will-change` rule\" in the subject line.\n\n## The mental model that actually holds up: a promise, not a setting\n\n`will-change` isn't a performance mode you flip on. It's a **promise to the browser**, and like any promise, breaking it has a cost. \"This specific element's `transform` is about to change\" is a promise you can keep for one element for a few hundred milliseconds. \"Every card in this grid might change at some unknown point\" is a promise you can't keep, and the browser ends up paying for the ones you broke.\n\nThe pattern that holds up adds the hint in JavaScript, right before the change, and removes it right after:\n\n```js\nconst card = document.querySelector(\".card\");\n\ncard.addEventListener(\"pointerenter\", () => {\n  card.style.willChange = \"transform\";\n});\n\ncard.addEventListener(\"transitionend\", () => {\n  card.style.willChange = \"auto\";\n});\n```\n\nNow the browser only reserves a layer for the exact window where it's useful — from the moment you signal intent to the moment the transition actually finishes — and gives that memory back immediately after. One card hovered is one layer, briefly. Two hundred cards sitting untouched are two hundred cards costing nothing.\n\n\u003C!-- playground:start -->\n\n## 🎮 Try it yourself\n\n**[▶️ Open the interactive playground →](https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcss-will-change-performance-hint\u002Fplayground)**\n\n_Runs right in your browser — poke at it and watch the concept react live._\n\n\u003C!-- playground:end -->\n\n## When the old way — no `will-change` at all — is the right call\n\nMost elements on most pages don't need this property, full stop. Browsers already run their own heuristics for promoting layers around `transform` and `opacity` changes, and for a single button or a handful of elements, those heuristics are usually good enough on their own. `will-change` is specifically for the case you've already profiled: you opened the **Performance** or **Layers** panel, watched a specific element genuinely struggle, and confirmed a manual hint fixes it. MDN's own framing is \"use it as a last resort to deal with existing performance problems\" — never \"add it in advance in case one shows up.\" If you haven't profiled anything yet, you don't have evidence `will-change` is the fix; you have a hunch, and hunches are how a stylesheet ends up with a permanent rule on `.card`.\n\n## The honest caveat\n\n`will-change` doesn't make anything *faster* in the way a code change makes a function faster — it changes *when* the browser pays a cost it was always going to pay, trading a little memory for a smoother first frame. On a memory-constrained device, that trade can go the other way: enough simultaneous layers and you're not avoiding jank, you're causing it, just somewhere else in the pipeline. The fix for \"I added `will-change` and it's still janky\" is often \"remove `will-change` and check whether you're promoting too much at once\" — not \"add more of it.\"\n\n## The takeaway\n\n`will-change` works exactly as advertised on exactly as much as you apply it to. The mistake was never the property — it was treating a scoped, temporary hint like a global setting you set once and forget. Scope it to the element that's actually changing, add it right before the change, take it back off right after, and you get the smooth animation without two hundred standing GPU layers paying for cards that never moved.\n\nGo check your own stylesheet for a bare `will-change` sitting on a class that matches more than one element — how many of those elements have actually animated today?\n\n\u003C!-- quiz:start -->\n\n## 🧠 Test yourself\n\nThink it clicked? **[Take the 8-question quiz →](https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcss-will-change-performance-hint\u002Fquiz)**\n\n_Instant feedback, a hint on every question, and an explanation for each answer — right or wrong._\n\n\u003C!-- quiz:end -->\n\n\u003C!-- related:start -->\n\n## 📚 Read next\n\n- [Your browser renders everything, even what you can't see — `content-visibility: auto` fixes that](https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcontent-visibility-skip-offscreen-rendering)\n- [You're polling setInterval to detect DOM changes. `MutationObserver` fires when they happen.](https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fmutation-observer-dom-change-detection)\n- [The Background Task That Waited 40 Seconds for 'Idle'](https:\u002F\u002Fbestpractic.org\u002Fblog\u002Frequestidlecallback-can-wait-forever)\n\n\u003C!-- related:end -->\n\n---\n\n🚀 **Want more like this?** Every guide, playground, and quiz lives on **[bestpractic.org](https:\u002F\u002Fbestpractic.org\u002F)** — open it and **[sign up free](https:\u002F\u002Fbestpractic.org\u002F)** so the next one finds you.\n\n*Thanks for reading! Let's stay connected:*\n\n- ⭐ **GitHub** — follow me and star the projects: [github.com\u002Fparsajiravand](https:\u002F\u002Fgithub.com\u002Fparsajiravand)\n- 💬 **Discord** — join the frontend best-practices community: [discord.gg\u002Fd9KRhuAwQ](https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ)\n- 📸 **Instagram** — frontend best practices, daily: [@bestpractice___](https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F)",{"title":109,"canonical":274,"description":275},"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcss-will-change-performance-hint","will-change: transform looks like a free performance switch. Applied broadly or left on permanently, it does the opposite — here's the narrow, temporary pattern that actually works","01a10aaf-5ec4-700b-bbd2-615aee3e7659",{"id":278,"locked":18},"01a10aaf-5f60-721b-8d5f-6049a2294ddc",[280],{"id":45,"slug":46,"title":48,"_count":281},{"questions":51},[283],{"locale":13,"slug":46},{"id":45,"slug":46,"title":48,"_count":285,"questionCount":51},{"questions":51}]