# Performance

> Follow these tips to improve loading times and Core Web Vitals scores.

---

### `image_url` filter

Use `image_url` to generate fast, responsive, modern images without changing your original assets.


:::highlight gray 📌 
Use `image_url` to serve AVIF/WebP images, control quality, and generate multiple sizes on the fly. 
:::

---

### What it does

The `image_url` filter is a macro built into the Vitrin theme SDK. It lets you:

1. Convert images to modern formats (AVIF / WebP) dynamically
2. Adjust image quality for faster downloads, especially on mobile
3. Generate different sizes for responsive layouts (`srcset`, etc.)

---

### Signature

```jinja
image_url(path, w=None, h=None, q=None, f=None)
```

**Parameters:**

* **`path`** *(required)* – URL or path to the original image
* **`w`** – Output width in pixels
* **`h`** – Output height in pixels
* **`q`** – Output quality from `0` to `100`
* **`f`** – Output format. Use `'auto'` to let the client’s browser choose the best supported format (recommended)

---

### Basic usage

```jinja
{{ image_url(ny_image, w=400, q=85, f='auto') }}
```

This returns a URL to a 400px-wide, high-quality, auto-formatted image.

---

### Responsive `srcset` example

```html
<img
  style="width: 100%; height: 100%; object-fit: cover"
  srcset="
    {{ image_url(gallery.image, w=400,  q=100, f='auto') }} 400w,
    {{ image_url(gallery.image, w=640,  q=100, f='auto') }} 640w,
    {{ image_url(gallery.image, w=750,  q=100, f='auto') }} 750w,
    {{ image_url(gallery.image, w=960,  q=100, f='auto') }} 960w,
    {{ image_url(gallery.image, w=1700, q=100, f='auto') }} 1700w
  "
  sizes="(max-width: 768px) 100vw, 50vw"
/>
```

The browser will automatically pick the most appropriate size for the user’s device and viewport.

---

<Steps>
  <Step title="Step 1 – Start simple">
    Replace hard-coded image URLs with <code>{{ image_url(...) }}</code> in your templates.
  </Step>
  <Step title="Step 2 – Tune quality">
    Use <code>q</code> (e.g. <code>q=70</code>) to balance visual quality and performance, especially for mobile.
  </Step>
  <Step title="Step 3 – Add responsiveness">
    Generate several widths and build a <code>srcset</code> so images stay sharp on all screen sizes.
  </Step>
</Steps>

---


### Preload Critical Assets

Preloading key images can significantly improve your **Core Web Vitals**:

- **First Contentful Paint (FCP)** — Preload the store logo so it appears as soon as possible.
- **Largest Contentful Paint (LCP)** — Preload large banners or hero images to speed up main visual rendering.

Add the preload tags in your `<head>` section:

```jinja
<link rel="preload" as="image"
      href="{{ image_url(logoUrl, h=175, q=100) }}"
      media="(min-width: 992px)">

{% if logoUrlMobile %}
  <link rel="preload" as="image"
        href="{{ image_url(logoUrlMobile, h=175, q=100) }}"
        media="(max-width: 991px)">
{% else %}
  <link rel="preload" as="image"
        href="{{ image_url(logoUrl, h=175, q=100) }}"
        media="(max-width: 991px)">
{% endif %}
```
The `media` attribute specifies the viewport size that triggers the preloading.
In the example above, we preload a different logo for desktop and mobile, with a fallback to the desktop logo if `logoUrlMobile` is not defined.

---

### Optimize Script Loading
- Use `async` for scripts that don’t require order.

```js
<script async src="{{ 'jquery-3.6.0.min.js' | asset_url }}"></script>
```

- Use `defer` for scripts that require order but should not block rendering:

```js
<script defer src="{{ 'jquery-3.6.0.min.js' | asset_url }}"></script> 
```

---

### Image Optimization
Use responsive images with `srcset` to serve the right size based on device:

```js
<img 
  src="{{ product.image | resize(800) }}" 
  srcset="{{ product.image | resize(400) }} 400w, {{ product.image | resize(800) }} 800w"
  alt="{{ product.name }}">

```
