Category: Responsive Delivery

Practical responsive image markup, art direction, sizing, and performance guidance.

  • How do you optimize an LCP image?

    How do you optimize an LCP image?

    Short answer: Make the LCP image discoverable in initial HTML, do not lazy-load it, give it appropriate priority, send only the pixels the layout needs, and serve a cached optimized response quickly. Measure which LCP subpart is slow before changing the image encoder.

    Largest Contentful Paint measures when the largest eligible content element in the viewport finishes rendering. When that element is an image, its result includes more than transfer time. Discovery can be late, the request can wait behind other resources, the server can respond slowly, or rendering can be delayed after the bytes arrive.

    Is the browser discovering the image early?

    Prefer an <img> in server-rendered or initial HTML. A background image hidden in CSS, a URL inserted by client JavaScript, or an image gated behind hydration can be discovered later. The preload scanner is effective when the resource and its responsive candidates are visible in markup.

    Do not set loading="lazy" on the likely LCP image. Lazy loading deliberately delays some requests and conflicts with the goal. web.dev’s LCP optimization guide identifies resource discovery delay as a major opportunity and recommends making the resource discoverable from HTML.

    If a framework image component produces the markup, inspect the rendered HTML rather than assuming its defaults are correct. Confirm that src, srcset, and sizes appear before client code runs.

    Does the request have the right priority?

    Use fetchpriority="high" for the likely LCP image when it competes with other images. This is a hint, not a guarantee, and it should be reserved for genuinely important resources. Marking every image high priority removes the browser’s ability to rank them.

    A preload can help when the image remains hard to discover, but it is easy to preload the wrong candidate. A responsive image preload must mirror imagesrcset and imagesizes. The web.dev article on preloading responsive images explains the syntax and limitations.

    Check the network trace for duplicate requests. If the preload URL, crossorigin mode, or responsive candidates differ from the final image request, the browser may fetch twice. Removing an incorrect preload is often better than keeping a theoretically helpful one.

    Is the selected image larger than the slot?

    Record the rendered CSS width, device-pixel ratio, currentSrc, intrinsic width, and transferred bytes. The selected candidate should be close to the rendered width multiplied by DPR, allowing for the available ladder. If it is much larger, correct sizes or add a more appropriate candidate.

    The sizes mistakes guide explains common selection errors, while the width ladder guide shows how to bound derivatives. Fix geometry before fine-tuning quality because excess pixels are often the biggest source of waste.

    Declare intrinsic dimensions or a stable aspect ratio so the browser can reserve layout space. This primarily protects layout stability, but predictable geometry also helps the page reach its final state without unnecessary work.

    Are format and quality appropriate?

    Deliver a modern format when it provides a meaningful size reduction and the client supports it. Keep a correct fallback and verify CDN cache variation. Use an automatic or preset quality policy that has been visually tested against hero content.

    Do not chase the smallest file at the cost of visible hero degradation. A useful target is the smallest version that meets the design’s quality threshold. Test photographs, illustrations, gradients, text overlays, and mobile crops separately.

    Metadata removal can save some bytes, but resizing and encoding usually have much more leverage. Avoid expensive transformations that do not visibly improve the rendered result.

    Is the server or image API the bottleneck?

    Inspect time to first byte for the image and for the HTML. A cold derivative may include source retrieval and encoding. Warm the small number of critical hero variants during deployment or content publication if your service supports it. Keep the full set bounded so warming does not become an uncontrolled generation job.

    The site’s guide to the first image request explains the cold path. For repeat traffic, confirm that edge responses are actually cached, that cache keys are stable, and that source versioning does not force unnecessary misses.

    Use long-lived immutable caching for versioned public derivatives. If a hero changes, publish a new versioned URL rather than purging the same identifier and hoping every layer refreshes together.

    How should you measure the improvement?

    Start with field data segmented by page template, device class, and connection where available. Lab tools are excellent for traces and controlled comparisons, but a single simulated run is not the user population. Google’s documentation on Largest Contentful Paint explains the metric and its recommended thresholds.

    Break LCP into time to first byte, resource load delay, resource load duration, and element render delay. Improve the largest portion first. If load delay dominates, a smaller image will not solve late discovery. If duration dominates, dimensions and bytes matter. If render delay dominates, inspect CSS, fonts, main-thread work, and reveal animations.

    Retest at mobile and desktop sizes because they may select different art direction and candidates. Confirm no regression in visual quality or layout stability. Then monitor field percentiles after rollout.

    LCP image optimization is a delivery-chain task, not a single compression switch. The winning sequence is early discovery, correct priority, accurate responsive selection, appropriate encoding, reliable caching, and evidence from real pages.

  • Use the picture element for image art direction

    Use the picture element for image art direction

    Short answer: Use <picture> when different layouts need meaningfully different compositions, not merely different resolutions of the same composition. Put media-specific crops in <source> elements and keep a complete <img> fallback with dimensions, alt text, and sensible defaults.

    A wide desktop hero can place a person to the left of a headline. On a narrow phone, shrinking that canvas may make the person tiny or place text over the subject. Art direction solves the composition problem by choosing a tighter or differently positioned crop.

    Art direction is not resolution switching

    Resolution switching delivers the same visual content at several pixel widths. A width-descriptor srcset and accurate sizes are usually enough. The browser chooses a resource based on the slot and device.

    Art direction changes the image content or crop for a layout. It may use a wide source above one breakpoint and a portrait source below it. MDN distinguishes these cases in its responsive images guide. Keeping the distinction clear prevents needlessly complex markup.

    Each art-directed source can still have its own width ladder. The mobile crop might offer 480w and 720w candidates, while the desktop crop offers 960w, 1280w, and 1600w. Use the responsive width ladder to bound each set.

    How should the picture markup be structured?

    Order <source> elements so their media conditions express the intended precedence. Each source can include media, srcset, sizes, and optionally type. The nested <img> remains mandatory because it supplies the fallback request, semantic alt text, intrinsic dimensions, loading behavior, and other image attributes.

    Do not duplicate alt text on sources. The alternatives represent the same semantic image, so the img text describes the shared purpose. If the mobile and desktop visuals communicate different information, the design may require two semantic images or a reconsidered content structure, not cleverer source selection.

    The HTML Living Standard defines the picture element and image candidate model. Use standards-based markup first, then let the image API provide derivatives.

    How do you create reliable alternate crops?

    The best input is explicit editorial intent. Store focal coordinates, a named gravity, or approved crop boxes with the asset. Generate a small set of named transformations such as hero-wide-v1 and hero-portrait-v1. Named presets are easier to review than arbitrary crop parameters embedded in templates.

    Automatic subject or face detection can be useful, but it should not be treated as infallible. Test difficult cases: groups of people, products near edges, text inside an image, transparent objects, and scenes with competing focal points. Provide an editorial override for valuable assets.

    Cloudinary documents crop and gravity options in its image transformation reference. Other providers use different names and behavior, so isolate the vendor mapping behind your URL builder.

    Avoid upscaling after a tight crop. A portrait crop extracted from a small source may not have enough pixels for a high-density phone. Validate the crop’s effective dimensions during ingestion or editorial preview.

    Can picture also select formats?

    Yes. A source can declare a MIME type so supporting browsers choose AVIF or WebP while the img supplies another format. But combining format selection, art direction, and many responsive widths can create a large candidate matrix.

    Prefer service-side format negotiation when it is correctly cached and observable, or use a small explicit format stack. Whichever method you choose, ensure every art-directed crop has a compatible fallback. The site’s guide to AVIF, WebP, and JPEG helps frame that decision.

    What are the performance pitfalls?

    Do not preload a desktop URL while the phone selects a different source. That can download both. If the art-directed image is the likely LCP element and needs a preload, use responsive preload attributes that mirror the candidates and media logic. web.dev explains the constraints in its responsive image preload guide.

    Set the fetchpriority and loading behavior on the nested image according to its role. A page’s likely LCP image should not be lazily loaded. Images far below the fold generally can be. The dedicated LCP optimization guide covers the complete discovery path.

    Reserve stable space. If desktop and mobile crops have different aspect ratios, CSS can set an aspect ratio appropriate to each breakpoint. The intrinsic width and height on the fallback still provide useful default geometry.

    How do you test art direction?

    Review every breakpoint with real content, not only a placeholder. Inspect currentSrc to confirm the intended crop and candidate were selected. Resize through breakpoint boundaries and test direct navigation, cached navigation, and slow networks.

    Automate screenshots for a small corpus of challenging assets. A visual test can reveal a subject cut in half even when the URL and dimensions are technically valid. Also validate the accessibility tree and alt text because responsive sources should not change the meaning exposed to assistive technology.

    Use <picture> when composition genuinely changes. Keep the source set small, make crop intent explicit, preserve a complete fallback, and test visual meaning as carefully as byte size.

  • Five sizes attribute mistakes that waste image bytes

    Five sizes attribute mistakes that waste image bytes

    Short answer: Most sizes problems come from describing the viewport instead of the image slot, ordering media conditions incorrectly, forgetting layout gaps, allowing markup to drift from CSS, or omitting sizes entirely. The browser then makes a reasonable choice from inaccurate information.

    srcset provides candidate files. sizes tells the browser how wide the image will be before layout completes. The browser uses both pieces to start a request early. It cannot wait for every stylesheet and component to settle without delaying the image.

    MDN’s responsive images guide is the best starting point for the syntax. The mistakes below are implementation problems that appear when the syntax no longer matches the design.

    1. Declaring 100vw for a constrained image

    sizes="100vw" says the image occupies the full viewport width. That can be close for a full-bleed mobile image, but it is wrong for a 760-pixel article column on a 1440-pixel display. The browser may choose a candidate nearly twice as wide as necessary.

    Describe the slot. For a fluid content image with side padding and a desktop cap, use a value like (max-width: 792px) calc(100vw - 32px), 760px. Match those numbers to actual CSS tokens, not an illustration in a design file.

    2. Writing media conditions in the wrong order

    The browser uses the first matching condition. If a broad condition appears before a narrow one, the narrow rule never runs. This often happens when breakpoints are copied from mobile-first CSS into sizes without considering first-match evaluation.

    Read the list from left to right at several viewport widths. For each one, identify the first true condition and calculate the resulting slot. Keep the final item as the default without a media condition.

    3. Ignoring columns, gaps, and containers

    A three-column card is not 33vw when the grid has a maximum width, side padding, and gaps. At some breakpoints the card may span two columns; at others it may become a list row with a fixed thumbnail. A rough fraction can be wrong in both directions.

    Use calc() where the layout is predictably derived from the viewport. For complex component states, generate sizes alongside the component variant so the code understands whether it is in a one-, two-, or three-column layout. If the slot cannot be described, consider simplifying the design contract.

    The site’s width ladder guide explains how candidate widths should be derived from these same slots. Candidates and sizes must be designed as one system.

    4. Letting HTML drift from CSS

    A developer changes the content maximum width from 720 to 800 pixels but forgets the sizes string. Nothing looks broken. Users simply download an unnecessarily large or slightly soft image.

    Avoid duplicated magic numbers. Export shared breakpoint and container tokens to the image component where practical. Add visual fixtures for component variants and a browser test that compares rendered width with the selected image’s intrinsic width.

    Do not make tests too strict. Candidate selection can vary between browsers and depends on density. Test a reasonable ratio, such as whether the selected intrinsic width stays within an agreed overhead above rendered width multiplied by DPR.

    5. Omitting sizes with width descriptors

    When a width-descriptor srcset has no useful sizes, the browser commonly behaves as if the slot is 100vw. That may be safe for visual quality, but it often wastes bytes for constrained content. The absence is especially costly on dense displays.

    If the image truly spans the viewport, say so intentionally. Otherwise, add the real slot formula. For fixed-size icons or avatars, density descriptors such as 1x and 2x may express the problem more directly than a width ladder.

    How do you find an incorrect sizes value?

    Open the page in a clean browser session with the Network and Elements panels visible. Set a viewport and device-pixel ratio. Record the image’s rendered width, its currentSrc, the chosen resource’s intrinsic width, and transfer size. The HTMLImageElement.currentSrc property is documented by MDN.

    Calculate rendered width multiplied by DPR. The selected candidate should usually be the first useful width at or above that requirement. If it is much larger, inspect sizes. If it is smaller and visibly soft, inspect missing candidates, source limits, and density assumptions.

    Repeat at the precise breakpoint edges and just between them. A rule can be correct at 768 and 1024 pixels but wrong at 900. Also test the component in every context where it can appear; a reusable card may have different slots on search, home, and article pages.

    Does sizes affect LCP?

    Yes, when the LCP element is a responsive image. An exaggerated slot can cause a heavier file to be selected. An understated slot can yield a soft image and may trigger another fetch if scripts later alter the markup. The LCP image optimization guide covers discovery and priority in addition to sizing.

    web.dev recommends that images generally include dimensions and appropriate responsive markup in its guidance on fast image loading. The important point is systemic: format, quality, preload, and CDN delivery cannot compensate for a browser being told the wrong display size.

    Treat sizes as executable layout documentation. Review it when grids change, test it against rendered slots, and keep it close to the component that owns the CSS. That small discipline often saves more bytes than another round of encoder tuning.

  • Build a responsive image width ladder

    Build a responsive image width ladder

    Short answer: Start from measured layout widths, multiply them by the device-pixel ratios you intend to support, merge nearby results, and cap the set at the source’s useful size. A compact ladder usually serves users better than dozens of finely spaced variants.

    An image API makes any width look cheap because a new derivative is one URL parameter away. At scale, arbitrary widths increase transformation work, storage, cache fragmentation, and operational noise. The browser also needs a truthful sizes value before its selection from srcset can be efficient.

    What is a width ladder?

    A width ladder is the approved set of derivative widths an application can request, such as 320, 480, 640, 800, 1024, 1280, and 1600 pixels. Each value becomes a candidate in a width-descriptor srcset. The browser combines those candidates with the declared slot size and device conditions to choose one resource.

    MDN’s responsive images guide explains how width descriptors and sizes work together. The HTML standard leaves the final selection to the user agent, so your job is to provide useful choices and accurate layout information, not force an exact file.

    The ladder should be shared policy. If every component invents widths, two visually identical cards may request different derivatives. Centralizing candidates makes the cache warmer and keeps the variant set inspectable.

    How do you derive candidate widths?

    Inventory the actual rendered slots in your design system. A card might be about 280 pixels in a narrow grid and 360 pixels in a wider one. An article image may range from 320 pixels on a phone to 760 pixels in the content column. A hero may reach 1440 pixels.

    For each slot, calculate the physical pixel need at the device-pixel ratios you support. A 360 CSS-pixel card needs 720 source pixels at 2x. Do not blindly support every theoretical density. Above a point, extra bytes may produce little visible benefit, especially after compression and typical viewing distance.

    Combine the resulting numbers, sort them, then merge close neighbors. A candidate at 780 and another at 800 rarely justify separate transforms. Round to stable values that your image service and component library can reuse.

    Finally, cap candidates at the meaningful source width. Upscaling a 1000-pixel original to 1600 pixels does not create detail. Your URL builder should select the largest available candidate at or below the source constraint, or explicitly apply the platform’s no-upscale option.

    How far apart should widths be?

    There is no universal increment. Equal 100-pixel steps overproduce large variants and underserve the smallest range. Multiplicative spacing is a better starting point because the byte and perceptual differences scale with image area.

    A ratio around 1.25 to 1.5 between adjacent values can produce a manageable initial set. Then validate it using real slots and content. Remove candidates that are almost never selected. Add one where field data shows browsers frequently choosing a much larger resource than required.

    The goal is not mathematical elegance. It is to limit overfetch while keeping the cache and transformation surface bounded. The guide to preventing image variant explosion covers the operational side.

    What should the markup look like?

    Use width descriptors when the rendered size varies with layout. A simplified content image might offer 480w, 640w, 800w, and 1024w candidates, with sizes="(max-width: 700px) calc(100vw - 32px), 760px". That tells the browser that the image tracks the viewport on small screens and stops growing at the article column.

    Generate every URL through the same transformation builder so crop, quality, format, and version remain consistent. Cloudinary provides responsive image concepts in its responsive images documentation, and the site’s responsive image API guide shows how browser markup fits the delivery contract.

    Always include intrinsic width and height or an equivalent aspect ratio. Responsive selection saves bytes; intrinsic dimensions reserve layout space and reduce shifts. They solve different problems.

    How do you validate the ladder?

    Test representative pages at common breakpoints and a few intermediate widths. In browser developer tools, record the rendered CSS width, selected candidate, intrinsic width, transfer size, and device-pixel ratio. A selected resource modestly larger than the physical need is normal. A resource several times larger points to a bad sizes value or a missing candidate.

    Repeat tests with a cold cache and network throttling. Confirm that the hero or likely LCP image is discoverable early. The web.dev guide to responsive image preloading explains how imagesrcset and imagesizes can be used when a responsive preload is genuinely necessary.

    Review server logs after rollout. Aggregate requested widths by component or preset. Unexpected values reveal callers bypassing the ladder. Candidates with negligible traffic may be removable. High fallback use may reveal a gap.

    A good width ladder is deliberately boring: a small shared list, grounded in the layout, enforced in code, and adjusted from evidence. That predictability is what lets an on-demand image API stay efficient.

Share with