Repository: sveltejs/svelte (JavaScript)

Issue:
img with loading attribute will lead to "read properties of undefined (reading 'loading')"
### Describe the bug

When navigate to a page that has img element with loading attribute, the page crashed and showing "read properties of undefined (reading 'loading')" in console.

### Reproduction

https://svelte.dev/playground/fd9fd756b9c942f18f5c9364a8c46454?version=5.1.13

### Logs

```shell
Uncaught TypeError: Cannot read properties of undefined (reading 'loading')

	in +layout.svelte
	in root.svelte

    at Module.handle_lazy_img (chunk-5S7XBGTN.js?v=925f45c9:1586:30)
    at _page (+page.svelte:34:23)
    at chunk-5S7XBGTN.js?v=925f45c9:222:58
    at update_reaction (chunk-GFV2NITQ.js?v=925f45c9:889:23)
    at update_effect (chunk-GFV2NITQ.js?v=925f45c9:980:21)
    at create_effect (chunk-GFV2NITQ.js?v=925f45c9:1992:7)
    at branch (chunk-GFV2NITQ.js?v=925f45c9:2124:10)
    at chunk-5S7XBGTN.js?v=925f45c9:216:17
    at update_reaction (chunk-GFV2NITQ.js?v=925f45c9:889:23)
    at update_effect (:5173/node_modules/.vite/deps/chunk-GFV2NITQ.js?v=925f45c9:980:21)TypeError: Cannot read properties of undefined (reading 'loading')
    at Module.handle_lazy_img (chunk-5S7XBGTN.js?v=925f45c9:1586:30)
    at _page (+page.svelte:34:23)
    at chunk-5S7XBGTN.js?v=925f45c9:222:58
    at update_reaction (chunk-GFV2NITQ.js?v=925f45c9:889:23)
    at update_effect (chunk-GFV2NITQ.js?v=925f45c9:980:21)
    at create_effect (chunk-GFV2NITQ.js?v=925f45c9:1992:7)
    at branch (chunk-GFV2NITQ.js?v=925f45c9:2124:10)
    at chunk-5S7XBGTN.js?v=925f45c9:216:17
    at update_reaction (chunk-GFV2NITQ.js?v=925f45c9:889:23)
    at update_effect (chunk-GFV2NITQ.js?v=925f45c9:980:21)
```


### System Info

```shell
System:
    OS: Windows 11 10.0.22631
    CPU: (12) x64 12th Gen Intel(R) Core(TM) i5-12400
    Memory: 13.51 GB / 31.85 GB
  Binaries:
    Node: 20.18.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.22 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 10.9.0 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.12.3 - ~\AppData\Roaming\npm\pnpm.CMD
  Browsers:
    Edge: Chromium (127.0.2651.74)
    Internet Explorer: 11.0.22621.3527
  npmPackages:
    svelte: ^5.1.9 => 5.1.9
```


### Severity

annoyance


Discussion:
If there is just the image, it works; the generated code passes the element correctly:
```js
var img = root();

$.handle_lazy_img(img);
```

With an additional element, no variable for the image is generated and the call becomes empty 🤔
```js
var fragment = root();

$.next(2);
$.handle_lazy_img();
```

I guess a check is missing to get an element reference in case there isn't one yet. E.g. [passing in a `src` attribute](https://svelte.dev/playground/fd9fd756b9c942f18f5c9364a8c46454?version=5.1.13#H4sIAAAAAAAACm2PwUrEMBRFfyW-zSh0Gmdb24LMxp3gQhAjkiZvpnHSJOS96TiW_ruUUVduD-dwuRMEPSBU8IDeR3GK2VtxjdYx2hsoYOc8ElSvE_A5Ld4CoPit7lMqaUTPC-s04X_cxMAYmKCCmkx2iVsVFJsYiAVlIxqx6pkTVVJeotLiKN91StINw5F151FqImT6EdaDNr0LuLZIB46p3D4-v3w8xdvyhF1a3alQy7-put-0l3tXtew3C3HDXkyUzSy050aBiSNmBcJHbV3YNwq8_joraFWAAhg_GSrOR5zf5m-ZkALKMgEAAA==) from code or binding the image element will also make it work, so it just breaks in the completely static case since nothing else generates the variable.



Patch:
diff --git a/.changeset/nice-chicken-wonder.md b/.changeset/nice-chicken-wonder.md
new file mode 100644
index 000000000000..b9f6e39fb858
--- /dev/null
+++ b/.changeset/nice-chicken-wonder.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: consider img with loading attribute not static
diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js
index 022b8574d974..98272817df7d 100644
--- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js
+++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js
@@ -150,6 +150,11 @@ function is_static_element(node) {
 			return false;
 		}
 
+		// We need to apply src and loading after appending the img to the DOM for lazy loading to work
+		if (node.name === 'img' && attribute.name === 'loading') {
+			return false;
+		}
+
 		if (node.name.includes('-')) {
 			return false; // we're setting all attributes on custom elements through properties
 		}


Test patch:
diff --git a/packages/svelte/tests/runtime-runes/samples/img-loading-lazy-no-static/_config.js b/packages/svelte/tests/runtime-runes/samples/img-loading-lazy-no-static/_config.js
new file mode 100644
index 000000000000..673ff2d75465
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/img-loading-lazy-no-static/_config.js
@@ -0,0 +1,5 @@
+import { test } from '../../test';
+
+export default test({
+	html: `<h1></h1><img src="..." loading="lazy" />`
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/img-loading-lazy-no-static/main.svelte b/packages/svelte/tests/runtime-runes/samples/img-loading-lazy-no-static/main.svelte
new file mode 100644
index 000000000000..15425d905158
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/img-loading-lazy-no-static/main.svelte
@@ -0,0 +1,2 @@
+<h1></h1>
+<img src="..." loading="lazy">
\ No newline at end of file