Skip to content

7

Optimizing Images
2026 Edition

In the previous chapter, you optimized font loading in your Qwik application. Now let's continue improving the homepage by working on image loading.

In this chapter, you'll see how Qwik handles image optimization, then add a desktop hero image and a mobile version for smaller screens.

🖼️ Why optimize images?

Images often represent a large part of a page's total weight. If they are too large or poorly delivered, they can slow down loading, waste bandwidth, and hurt the experience, especially on mobile networks.

In Qwik, responsive image optimization is built in. It relies on vite-imagetools, so you do not need to install an additional image component just to get started.

The goal is simple: serve lighter images, generate responsive sources, and let the browser choose the most suitable version for the user's device. Qwik also includes image dimensions automatically, which helps prevent layout reflows and improves visual stability.

Under the hood, the final output stays simple: Qwik renders optimized images as regular <img> elements in the HTML.

⚙️ How does it work with Qwik?

  1. 1.Importing images: you import an image from the src folder. Qwik then generates optimized responsive image variants for different breakpoints.
  2. 2.Rendering the <img> element: Qwik renders an optimized <img> element with a srcset, so the browser can choose the most appropriate source depending on the screen size and resolution.
  3. 3.Image attributes: images use loading="lazy" and decoding="async" by default, which helps improve loading performance without blocking page rendering.
  4. 4.Suffix: add the ?jsx suffix at the end of the image import path to enable Qwik's image optimization pipeline. Keep jsx at the end of the path, otherwise TypeScript may complain.

In short, Qwik keeps the developer API small while still generating responsive image output, automatic dimensions, and optimized delivery under the hood.

🖥️ Adding the desktop hero image

Let's add a hero image to your dashboard. This version will be displayed on larger screens.

In your src/assets/ folder, create a new folder called img.

Download the desktop hero image here and add it to the src/assets/img/ folder.

In your src/routes/index.tsx file, import the image. Do not forget the ?jsx suffix at the end of the import path.

Then add the hero image to your file:

src/routes/index.tsx

This is what your homepage should look like now:

Desktop hero image displayed on the homepage.

📱 Practice: add the mobile hero image

Now it's your turn. Add a mobile hero image to your dashboard. This version will be displayed on smaller screens.

You can download the mobile hero image here:

Once you're ready, expand the code snippet below to reveal the solution.

🔎 Inspecting the rendered HTML

Once both images are added, you can inspect the homepage in your browser devtools and look at the HTML that Qwik actually renders.

Here, Qwik outputs responsive <img> elements with srcset, automatic width and height, and default loading behavior.

Rendered HTML in the browser

Here, you can see two optimized <img> elements, each with its own responsive srcset, generated width and height values, and loading="lazy" in the rendered HTML.

🚀 Use eager loading and fetch priority for hero images

Lazy loading is usually a great default for offscreen images, because it avoids downloading them too early.

But hero images are different. In this example, both hero images are visible immediately when the page loads, depending on the screen size. For images in the first viewport, it makes more sense to use loading="eager" instead. And for a truly important image, you can also raise its priority with fetchPriority="high".

💡

Qwik uses loading="lazy" by default for optimized images, which is usually a smart choice for offscreen content, as explained in the Qwik image optimization docs. But for hero images visible in the first viewport, it is better to switch to loading="eager". For a truly critical image, you can also use fetchPriority="high", as recommended in web.dev's guide to browser-level image lazy loading.

You can override the default behavior by passing the loading and fetchPriority props directly to the image components:

src/routes/index.tsx

In JSX, the prop is written as fetchPriority. In the rendered HTML, it appears as fetchpriority.

If you inspect the rendered HTML again, you should now see loading="eager" and fetchpriority="high" on both images:

Rendered HTML after the update

This example shows how you can start with Qwik's defaults, inspect the rendered HTML, and then adjust the loading behavior when an image is critical for the first screen.

It’s time to take a quiz!

Test your knowledge and see what you’ve just learned.

What does the ?jsx suffix do when importing an image in Qwik?

You must choose response !

Why use separate desktop and mobile hero images?

You must choose response !

Why is loading="eager" a better choice here for the hero images?

You must choose response !

Here are two useful references if you want to explore image optimization in more detail.

Source code

You can find the source code for chapter 7 2026 Edition on GitHub.

You've Completed Chapter 7

You've learned how to optimize and render responsive images in your Qwik app.

Next Up

8: Next chapter

The next chapter will continue the 2026 dashboard project.