This website requires JavaScript.

Background-Image injection problem in UX

A story about line of generous code that 90% Frontend Developer are falling into

5 min read
Updated: Aug 17, 2025

🎯 Real case

Imagine you’re building a beautiful landing page. Everything is perfect, smooth animations, sharp typography, and an impressive background image gallery from the CMS. Then deploy it to production, proudly show it off to everyone. Then one day, users complain: β€œThe site loads terribly slow!”. I know you’ll check the network tab, but you won’t see any problems. Bundle size is fine. So where’s the problem?

The answer may surprise you: it’s in the seemingly β€œharmless” lines of code you write every day. Take a look at this code β€” you’ve probably written it hundreds of times:

import React from "react";
const Images = ({ images }: { images: string[] }) => {
  return (
    <div className="flex">
      {images.map((image, index) => (
        <div
          key={index}
          style={{ backgroundImage: `url(${image})` }}
        />
      ))}
    </div>
  );
};
export default Images;

Looks familiar, right? Simple, clean, easy to understand. But this is a ticking time bomb in the application you are developing.

Have you found the problem yet? If not, don't worry. We need to dig into the "brain" of the browser to understand why this code is so dangerous.

πŸ›£ The Browser's Journey

When the Browser Receives HTML:

The HTML parser kicks in - Like a book reader, the browser reads from top to bottom, building the DOM tree step by step. When it encounters a

CSS Parser has an important task:

  • Building the CSSOM (CSS Object Model) tree
  • Allowing JavaScript to interact with styles
  • Completing the Critical Rendering Path - the important process of turning code into pixels on the screen

But it has a fatal weakness...

When CSS Parser encounters an external link (like url() in CSS), it will NOT stop to download immediately! Instead, it notes "need to download this image". CSSOM tree is still built normally. Images are only loaded when the browser needs to render that element. But here's the real problem...

When you map through 10 images and set them as background, what happens?

πŸ” What the Browser actually does?

Parse HTML/CSS β†’ Build DOM/CSSOM tree normally. When elements need to be rendered β†’ Detect need 10 images. Send 10 HTTP requests AT THE SAME TIME (in parallel). Problems start:

  • HTTP Connection Limits - If with HTTP/1.1, the Browser limits 6-8 connections per domain. 10 images = immediate bottleneck! (Note: HTTP/2 with multiplexing reduces this problem but has bandwidth issues - see point 4)
  • No Lazy Loading - All images load immediately, even those outside the viewport. The user has to download them before scrolling! 🀦
  • Inline Styles = Difficult to Optimize and Reuse - Inline styles are difficult to maintain, do not take advantage of CSS optimization techniques. Images are still cached based on the URL but style management becomes more complicated.
  • Bandwidth Competition - Even with parallel downloads, with multiple large images, 10 large images downloading at the same time will "share" the bandwidth, slowing down ALL.

πŸ‘‰ Result:

  • First Contentful Paint is delayed
  • Largest Contentful Paint skyrockets
  • User experience is "crippled" - especially on mobile/3G.

That's why customers complain about load speeds. The Network tab doesn't show the problem because requests are still parallel, but the total wait time is the culprit!

🧠 Conclusion

Lesson Learned: Performance is not only bundle size.

Many developers focus on: Code splitting, Tree shaking, Minification,... But we forget that the way the browser works is the key factor.

A seemingly harmless piece of code can:

  • Trigger dozens of unnecessary HTTP requests
  • Load resources when the user doesn't need them
  • Clog up network bandwidth
  • Tank Core Web Vitals (LCP, FCP, CLS)

So what is the solution? Here's a question for you guys πŸ’‘

And in your current project, how many places are you using backgroundImage with external URLs? Maybe that's the "culprit" slowing down your product, fix it right away πŸ˜™πŸ˜™πŸ˜™

  • performance
  • uiux
  • css
Enable PWA and Service Worker in Nuxt
Jul 01, 2025
Classification and functionality of the servers
Feb 26, 2025

πŸƒ Related posts