1"use strict";(self.webpackChunktheuxshop=self.webpackChunktheuxshop||[]).push([[1905],{8633:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>h,contentTitle:()=>c,default:()=>u,frontMatter:()=>d,metadata:()=>s,toc:()=>m});const s=JSON.parse('{"id":"guides/performance-for-designers","title":"Performance for Designers","description":"How design decisions affect web performance and what designers can do about it.","source":"@site/.tmp/docs-published/guides/performance-for-designers.mdx","sourceDirName":"guides","slug":"/guides/performance-for-designers","permalink":"/guides/performance-for-designers","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":7,"frontMatter":{"id":"performance-for-designers","title":"Performance for Designers","description":"How design decisions affect web performance and what designers can do about it.","sidebar_position":7},"sidebar":"guidesSidebar","previous":{"title":"CSS Sizing & Spacing","permalink":"/guides/css-sizing-spacing"},"next":{"title":"Accessibility as Foundation: Inclusive Design Best Practices","permalink":"/guides/accessibility-as-foundation"}}');var t=i(4848),r=i(8453),o=i(9176),a=i(5920),l=i(5388);const d={id:"performance-for-designers",title:"Performance for Designers",description:"How design decisions affect web performance and what designers can do about it.",sidebar_position:7},c="Performance for Designers",h={},m=[{value:"Why performance matters for UX",id:"why-performance-matters-for-ux",level:2},{value:"Core Web Vitals explained",id:"core-web-vitals-explained",level:2},{value:"Largest Contentful Paint (LCP)",id:"largest-contentful-paint-lcp",level:3},{value:"First Input Delay (FID) / Interaction to Next Paint (INP)",id:"first-input-delay-fid--interaction-to-next-paint-inp",level:3},{value:"Cumulative Layout Shift (CLS)",id:"cumulative-layout-shift-cls",level:3},{value:"Design decisions that affect performance",id:"design-decisions-that-affect-performance",level:2},{value:"Images",id:"images",level:3},{value:"Fonts",id:"fonts",level:3},{value:"Animation and motion",id:"animation-and-motion",level:3},{value:"Layout complexity",id:"layout-complexity",level:3},{value:"Designing for perceived performance",id:"designing-for-perceived-performance",level:2},{value:"Show something fast",id:"show-something-fast",level:3},{value:"Provide feedback",id:"provide-feedback",level:3},{value:"Avoid jarring changes",id:"avoid-jarring-changes",level:3},{value:"Working with developers on performance",id:"working-with-developers-on-performance",level:2},{value:"During design",id:"during-design",level:3},{value:"During handoff",id:"during-handoff",level:3},{value:"During review",id:"during-review",level:3},{value:"Performance checklist for designers",id:"performance-checklist-for-designers",level:2},{value:"Common performance pitfalls",id:"common-performance-pitfalls",level:2},{value:"Hero video backgrounds",id:"hero-video-backgrounds",level:3},{value:"Carousels with many items",id:"carousels-with-many-items",level:3},{value:"Infinite scroll without limits",id:"infinite-scroll-without-limits",level:3},{value:"Large hero images",id:"large-hero-images",level:3}];function p(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"performance-for-designers",children:"Performance for Designers"})}),"\n",(0,t.jsx)(n.p,{children:"Performance isn't just an engineering concern. Design decisions directly impact how fast pages load and feel. This guide helps designers understand and improve performance."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.em,{children:"Last updated: July 2025"})}),"\n",(0,t.jsx)(n.h2,{id:"why-performance-matters-for-ux",children:"Why performance matters for UX"}),"\n",(0,t.jsx)(n.p,{children:"Slow experiences frustrate users:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"53% of mobile users abandon sites that take over 3 seconds to load"}),"\n",(0,t.jsx)(n.li,{children:"Every 100ms of latency can reduce conversion by 7%"}),"\n",(0,t.jsx)(n.li,{children:"Slow sites feel less trustworthy and professional"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Performance is especially critical for users on
1slower connections or older devices - often the users who most need your service."}),"\n",(0,t.jsxs)(n.p,{children:["For detailed guidance on measuring and improving web performance, see ",(0,t.jsx)(n.a,{href:"https://web.dev/performance/",children:"web.dev's performance documentation"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"core-web-vitals-explained",children:"Core Web Vitals explained"}),"\n",(0,t.jsx)(n.p,{children:"Google's Core Web Vitals measure real-world user experience:"}),"\n",(0,t.jsx)(n.h3,{id:"largest-contentful-paint-lcp",children:"Largest Contentful Paint (LCP)"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"What it measures"}),": How long until the largest visible content loads (usually hero image or main heading)."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Target"}),": Under 2.5 seconds."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Designer impact"}),": Hero image size, font loading strategy, above-the-fold content complexity."]}),"\n",(0,t.jsx)(n.h3,{id:"first-input-delay-fid--interaction-to-next-paint-inp",children:"First Input Delay (FID) / Interaction to Next Paint (INP)"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"What it measures"}),": How long until the page responds to user interaction."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Target"}),": Under 100ms (FID) / under 200ms (INP)."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Designer impact"}),": Animation complexity, number of interactive elements loading initially, JavaScript-dependent interactions."]}),"\n",(0,t.jsx)(n.h3,{id:"cumulative-layout-shift-cls",children:"Cumulative Layout Shift (CLS)"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"What it measures"}),": How much content moves around as the page loads."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Target"}),": Under 0.1."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Designer impact"}),": Image dimensions, font loading, dynamic content, ads and embeds."]}),"\n",(0,t.jsx)(o.A,{variant:"note",title:"Layout shift in practice",children:(0,t.jsx)(n.p,{children:"Every time content jumps while loading - an image appearing and pushing text down, a font switching after loading, a banner inserting itself - that's layout shift. It's disorienting and often causes misclicks."})}),"\n",(0,t.jsx)(n.h2,{id:"design-decisions-that-affect-performance",children:"Design decisions that affect performance"}),"\n",(0,t.jsx)(n.h3,{id:"images",children:"Images"}),"\n",(0,t.jsx)(n.p,{children:"Images are typically the heaviest elements on a page."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Size appropriately"}),": A 4000px image displayed at 400px wastes bandwidth. Provide images at the sizes they'll actually be displayed."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Choose the right format"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"JPEG: photographs"}),"\n",(0,t.jsx)(n.li,{children:"PNG: graphics with transparency"}),"\n",(0,t.jsx)(n.li,{children:"SVG: icons, logos, simple graphics"}),"\n",(0,t.jsx)(n.li,{children:"WebP/AVIF: modern formats with better compression"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Consider necessity"}),": Does this decorative image add enough value to justify its weight? Sometimes the answer is no."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Specify dimensions"}),": Always include width and height attributes so browsers can reserve space before the image loads, preventing layout shift."]}),"\n",(0,t.jsx)(n.h3,{id:"fonts",children:"Fonts"}),"\n",(0,t.jsx)(n.p,{children:"Custom fonts look nice but come with costs."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Limit font weights/styles"}),": Each weight and style is a separate file. Do you really need thin, regular, medium, semibold, bold, and black?"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Consider system fonts"}),": System font stacks (",(0,t.jsx)(n.code,{children:"-apple-system, BlinkMacSystemFont, Segoe UI, Roboto..."}),") load instantly and look good on each platform."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Use font-display"}),": ",(0,t.jsx)(n.code,{children:"font-display: swap"})," shows text immediately with a fallback font, then swaps when the custom font loads. Prevents invisible text."]}),"\n",(0,t.jsx)(n.h3,{id:"animation-and-motion",children:"Animation and motion"}),"\n",(0,t.jsx)(n.p,{children:"Smooth animation requires thoughtful implementation."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Animate transform and opacity"}),": These properties can be GPU-accelerated. Animating width, height, margin, and padding forces layout recalculation - slower and janky."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Avoid animating many elements"}),": Each animated element has a cost. Animating 100 particles may look cool but performs poorly on mobile."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Respect motion preferences"}),": Some users have vestibular disorders or simply prefer reduced motion. Honor the ",(0,t.jsx)(n.code,{children:"prefers-reduced-motion"})," media query."]}),"\n",(0,t.jsx)(n.h3,{id:"layout-complexity",children:"Layout complexity"}),"\n",(0,t.jsx)(n.p,{children:"More elements mean more work for browsers."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Simplify where possible"}),": Deep nesting, excessive elements, and complex CSS selectors all slow rendering."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Consider progressive disclosure"}),": Show what's needed now; load more on interaction. A collapsed FAQ loads faster than all answers expanded."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Be thoughtful with shadows and effects"}),": Complex shadows, multiple gradients, and heavy filters require processing. Use them intentionally."]}),"\n",(0,t.jsx)(n.h2,{id:"designing-for-perceived-performance",children:"Designing for perceived performance"}),"\n",(0,t.jsx)(n.p,{children:"Actual load time matters, but perceived speed matters too. Users experience time subjectively."}),"\n",(0,t.jsx)(n.h3,{id:"show-something-fast",children:"Show something fast"}),"\n",(0,t.jsx)(n.p,{children:"Even if the full page takes time, showing key content quickly improves perceived performance:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Render above-the-fold content first"}
1),"\n",(0,t.jsx)(n.li,{children:"Use skeleton screens to indicate content is coming"}),"\n",(0,t.jsx)(n.li,{children:"Display important text before all images load"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"provide-feedback",children:"Provide feedback"}),"\n",(0,t.jsx)(n.p,{children:"When things take time, let users know:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Loading indicators for operations over 1 second"}),"\n",(0,t.jsx)(n.li,{children:"Progress bars for longer operations"}),"\n",(0,t.jsx)(n.li,{children:"Subtle animation to show the system is working"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"avoid-jarring-changes",children:"Avoid jarring changes"}),"\n",(0,t.jsx)(n.p,{children:"Smooth transitions feel faster than abrupt ones:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Fade in images rather than popping them in"}),"\n",(0,t.jsx)(n.li,{children:"Animate content shifts when unavoidable"}),"\n",(0,t.jsx)(n.li,{children:"Maintain visual stability as elements load"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"working-with-developers-on-performance",children:"Working with developers on performance"}),"\n",(0,t.jsx)(n.h3,{id:"during-design",children:"During design"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Ask about performance constraints before designing"}),"\n",(0,t.jsx)(n.li,{children:"Discuss image budgets (how many KB for key images?)"}),"\n",(0,t.jsx)(n.li,{children:"Review font choices for loading implications"}),"\n",(0,t.jsx)(n.li,{children:"Consider animation complexity trade-offs"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"during-handoff",children:"During handoff"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Provide properly sized images (or specify which sizes to generate)"}),"\n",(0,t.jsx)(n.li,{children:"Document which fonts/weights are essential vs. nice-to-have"}),"\n",(0,t.jsx)(n.li,{children:"Note animation timing and easing (so developers can implement efficiently)"}),"\n",(0,t.jsx)(n.li,{children:"Specify loading priorities (what must appear first?)"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"during-review",children:"During review"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Test on real devices, not just fast development machines"}),"\n",(0,t.jsx)(n.li,{children:"Check with throttled connections"}),"\n",(0,t.jsx)(n.li,{children:"Verify lazy loading is working"}),"\n",(0,t.jsx)(n.li,{children:"Look for layout shift issues"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"performance-checklist-for-designers",children:"Performance checklist for designers"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Images"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Images sized appropriately for their display size"}),"\n",(0,t.jsx)(n.li,{children:"Modern formats (WebP/AVIF) where supported"}),"\n",(0,t.jsx)(n.li,{children:"Width and height specified"}),"\n",(0,t.jsx)(n.li,{children:"Decorative images justified or removed"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Fonts"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Minimum necessary weights and styles"}),"\n",(0,t.jsx)(n.li,{children:"System font alternatives considered"}),"\n",(0,t.jsx)(n.li,{children:"Font loading strategy discussed with development"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Animation"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Animations use transform/opacity where possible"}),"\n",(0,t.jsx)(n.li,{children:"prefers-reduced-motion alternative provided"}),"\n",(0,t.jsx)(n.li,{children:"Animation serves a purpose (not just decoration)"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Layout"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Above-the-fold content loads quickly"}),"\n",(0,t.jsx)(n.li,{children:"Layout doesn't shift as content loads"}),"\n",(0,t.jsx)(n.li,{children:"Progressive disclosure for heavy content"}),"\n",(0,t.jsx)(n.li,{children:"Skeleton states designed for loading"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Content"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Essential content prioritized"}),"\n",(0,t.jsx)(n.li,{children:"Third-party embeds evaluated for necessity"}),"\n",(0,t.jsx)(n.li,{children:"Video/audio optimized and appropriate"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"common-performance-pitfalls",children:"Common performance pitfalls"}),"\n",(0,t.jsx)(n.h3,{id:"hero-video-backgrounds",children:"Hero video backgrounds"}),"\n",(0,t.jsx)(n.p,{children:"Auto-playing hero videos are heavy and often don't add value proportional to their cost. Consider:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Is this video essential to communication?"}),"\n",(0,t.jsx)(n.li,{children:"Would a static image work almost as well?"}),"\n",(0,t.jsx)(n.li,{children:"Can it load after core content?"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"carousels-with-many-items",children:"Carousels with many items"}),"\n",(0,t.jsx)(n.p,{children:"Carousels that load 10 high-res images upfront waste bandwidth. Most users see only the first 1-2 slides. Lazy load subsequent slides."}),"\n",(0,t.jsx)(n.h3,{id:"infinite-scroll-without-limits",children:"Infinite scroll without limits"}),"\n",(0,t.jsx)(n.p,{children:"Loading content forever as users scroll can exhaust device memory. Implement windowing or pagination beyond a certain point."}),"\n",(0,t.jsx)(n.h3,{id:"large-hero-images",children:"Large hero images"}),"\n",(0,t.jsx)(n.p,{children:"A 3MB hero image dominates load time. Optimize aggressively - users often don't notice quality differences between 80% and 100% quality compression."}),"\n",(0,t.jsx)(a.A,{items:[{question:"How do I test performance?",answer:"Use Chrome DevTools Lighthouse for quick audits. PageSpeed Insights provides field data. Test on real mobile devices when possible - your MacBook Pro isn't representative of most users' experience."},{question:"What's a reasonable page weight budget?",answer:"It depends on your audience and content, but under 1MB is a reasonable target for most pages. Image-heavy content (portfolios, e-commerce) might be higher; text-focused content can be much lower."},{question:"Should I avoid animations entirely?",answer:"No - meaningful animation improves UX. The key is intentional, efficient animation. Animate what matters, keep it smooth, and provide reduced-motion alternatives."},{question:"How do design systems help performance?",answer:"Consistent components mean reusable, optimized code. When every card is different, each needs custom implementation. When cards follow a system, they share efficient code."},{question:"What about third-party embeds (maps, videos, social)?",answer:"Third-party embeds often hurt performance significantly. Load them on interaction (click to load map
1), use facades (show a static image until clicked), or evaluate if they're truly necessary."}]}),"\n",(0,t.jsx)(l.A,{title:"Related resources",links:[{label:"CSS Sizing & Spacing",to:"/guides/css-sizing-spacing"},{label:"Accessibility Checklist",to:"/guides/accessibility-checklist"},{label:"UX Metrics Cheatsheet",to:"/tools/ux-metrics-cheatsheet"},{label:"Interaction Feedback Patterns",to:"/patterns/interaction-feedback"}]})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},9176:(e,n,i)=>{i.d(n,{A:()=>r});i(6540);var s=i(4164),t=i(4848);function r({variant:e="default",title:n,children:i}){return(0,t.jsxs)("div",{className:(0,s.A)("ux-callout","default"!==e&&`ux-callout--${e}`),children:[(0,t.jsx)("div",{className:"ux-callout__title",children:n||{default:"Note",tip:"Tip",warning:"Warning",note:"Field Note"}[e]}),(0,t.jsx)("div",{className:"ux-callout__content",children:i})]})}},5920:(e,n,i)=>{i.d(n,{A:()=>t});i(6540);var s=i(4848);function t({items:e}){return(0,s.jsx)("div",{className:"ux-faq",children:e.map((e,n)=>(0,s.jsxs)("div",{className:"ux-faq__item",children:[(0,s.jsx)("div",{className:"ux-faq__question",children:e.question}),(0,s.jsx)("div",{className:"ux-faq__answer",children:(0,s.jsx)("p",{children:e.answer})})]},n))})}},5388:(e,n,i)=>{i.d(n,{A:()=>r});i(6540);var s=i(6289),t=i(4848);function r({title:e="Related Resources",links:n}){return(0,t.jsxs)("div",{className:"ux-related",children:[(0,t.jsx)("div",{className:"ux-related__title",children:e}),(0,t.jsx)("ul",{className:"ux-related__list",children:n.map((e,n)=>(0,t.jsx)("li",{children:(0,t.jsx)(s.A,{to:e.to,className:"ux-related__link",children:e.label})},n))})]})}},8453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>a});var s=i(6540);const t={},r=s.createContext(t);function o(e){const n=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.