PageSpeed Insights Performance Issues
PageSpeed Insights Performance Issues
PageSpeed Insights surfaces a mix of opportunities (things you can fix to speed up the page) and diagnostics (things worth checking that don’t always have a direct score impact, like accessibility). Below are the issues we see most often, what they mean, and how to fix them.
Opportunities
🔺 Largest Contentful Paint image was lazily loaded
Above-the-fold images that are lazily loaded render later in the page lifecycle, which can delay the largest contentful paint. Learn more about optimal lazy loading. LCP
loading="lazy" tells the browser it’s safe to defer a resource until it’s needed — but the browser doesn’t know
in advance which image will become the LCP element. If you lazy-load an image that turns out to be above the
fold, the browser delays fetching it until it’s already scrolled the DOM and computed layout, adding a completely
avoidable round-trip to your LCP. Never lazy-load the hero image or any image likely to be above the fold; mark it
loading="eager" (or fetchpriority="high") instead. Reserve loading="lazy" for images that are actually
below the fold.
🔺 Image elements do not have explicit width and height
Set an explicit width and height on image elements to reduce layout shifts and improve CLS. CLS
Without a width/height (or CSS aspect-ratio), the browser doesn’t know how much space to reserve for an
image before it loads. As the image arrives, surrounding content jumps to make room — a layout shift that hurts
both CLS and the user’s experience. Always set the image’s intrinsic dimensions (or an aspect-ratio) so the
browser can reserve the correct space up front. visionary-image does this automatically using the dimensions
encoded in the Blurhash URL.
🔺 Eliminate render-blocking resources
Resources are blocking the first paint of your page. Consider delivering critical JS/CSS inline and deferring all non-critical JS/styles. LCP FCP
Any stylesheet or synchronous script the browser encounters before it can paint extends the
critical render path. Fix this by inlining the small amount of CSS needed
above the fold, loading the rest asynchronously, and adding defer or async to scripts that don’t need to run
before first paint.
🔺 Reduce unused CSS
Reduce unused rules from stylesheets and defer CSS not used for above-the-fold content to decrease bytes consumed by network activity. LCP FCP
This usually comes from shipping a single global stylesheet (or a full component library’s CSS) to every page. Split styles per route where practical, remove dead rules, and let a bundler tree-shake unused CSS modules.
🔺 Reduce unused JavaScript — Potential savings of 21 KiB
Reduce unused JavaScript and defer loading scripts until they are required to decrease bytes consumed by network activity. LCP FCP
Code-split by route so pages only load the JavaScript they actually run, lazy-load below-the-fold widgets (modals, carousels, chat widgets), and audit third-party scripts — analytics and embed snippets are frequent offenders.
🟨 Properly size images
Serve images that are appropriately-sized to save cellular data and improve load time. LCP
Serving a 2000px-wide image into a 400px-wide container wastes bytes the browser has to download before it can
paint. Request an image at (or slightly above, for high-DPI screens) its rendered size — this is exactly what
visionary-image handles automatically via responsive srcset generation.
🟨 Serve images in next-gen formats
Image formats like WebP and AVIF often provide better compression than PNG or JPEG, which means faster downloads and less data consumption.
Re-encode images as WebP or AVIF, or use an image CDN that negotiates format automatically based on the
Accept header. Both typically cut 25–50% off the file size of an equivalent-quality JPEG with no visible
difference.
🟨 Serve static assets with an efficient cache policy
Set a long max-age (and immutable) on fingerprinted static assets — JS/CSS bundles, fonts, and images with a
content hash in the filename — since the filename changes whenever the content does. There’s no reason for a
returning visitor’s browser to re-fetch a file it already has.
🔺 Avoid large layout shifts
These DOM elements contribute most to the Cumulative Layout Shift of the page. CLS
Layout shift almost always comes from content that has no reserved space before it loads: images without a
width/height (or aspect-ratio), web fonts that swap in and reflow text, ads or embeds injected into the flow,
or content inserted above existing content. Reserve space up front — set explicit dimensions on images, use
font-display: optional or preload critical fonts, and reserve a slot for dynamically-injected content.
Accessibility diagnostics
🔺 Image elements do not have [alt] attributes
Informative elements should aim for short, descriptive alternate text. Decorative elements can be ignored with an empty alt attribute.
Make sure every <img> (or visionary-image) has an alt attribute. Describe what the image conveys — not just
“image” or the filename. Purely decorative images should use alt="" so screen readers skip them instead of
announcing something meaningless.
🔺 Buttons do not have an accessible name
When a button doesn’t have an accessible name, screen readers announce it as “button”, making it unusable for users who rely on screen readers.
This commonly happens with icon-only buttons (a close “×”, a hamburger menu, a trash icon) that have no visible
text. Add an aria-label describing the action:
<button aria-label=“Close dialog”><XIcon /></button>
🔺 Links do not have a discernible name
Link text (and alternate text for images, when used as links) that is discernible, unique, and focusable improves the navigation experience for screen reader users.
Avoid generic link text like “click here” or “read more” with no surrounding context, and avoid links whose only
content is an icon with no aria-label. Every link should make sense read on its own, since that’s how many
screen reader users navigate a page — by tabbing between links.
🔺 Heading elements are not in a sequentially-descending order
Properly ordered headings that do not skip levels convey the semantic structure of the page, making it easier to navigate and understand when using assistive technologies.
Headings should form an outline — an <h2> shouldn’t be followed directly by an <h4> with no <h3> in between.
Pick heading levels based on document structure, not font size; style visual size with CSS instead of by skipping
levels.
Further reading
- Lighthouse performance audits on developer.chrome.com
- Learn Core Web Vitals on web.dev