diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts
index 814aa9187a9ce0..ced27abf1529a1 100644
--- a/packages/vite/src/node/plugins/importAnalysis.ts
+++ b/packages/vite/src/node/plugins/importAnalysis.ts
@@ -278,7 +278,6 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
       let needQueryInjectHelper = false
       let s: MagicString | undefined
       const str = () => s || (s = new MagicString(source))
-      const importedUrls = new Set<string>()
       let isPartiallySelfAccepting = false
       const importedBindings = enablePartialAccept
         ? new Map<string, Set<string>>()
@@ -411,6 +410,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
         return [url, resolved.id]
       }
 
+      const orderedImportedUrls = new Array<string | undefined>(imports.length)
       const orderedAcceptedUrls = new Array<Set<UrlPosition> | undefined>(
         imports.length,
       )
@@ -640,7 +640,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
             const hmrUrl = unwrapId(stripBase(url, base))
             const isLocalImport = !isExternalUrl(hmrUrl) && !isDataUrl(hmrUrl)
             if (isLocalImport) {
-              importedUrls.add(hmrUrl)
+              orderedImportedUrls[index] = hmrUrl
             }
 
             if (enablePartialAccept && importedBindings) {
@@ -718,6 +718,9 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
         }),
       )
 
+      const importedUrls = new Set(
+        orderedImportedUrls.filter(Boolean) as string[],
+      )
       const acceptedUrls = mergeAcceptedUrls(orderedAcceptedUrls)
       const acceptedExports = mergeAcceptedUrls(orderedAcceptedExports)
 
diff --git a/playground/module-graph/__tests__/module-graph.spec.ts b/playground/module-graph/__tests__/module-graph.spec.ts
new file mode 100644
index 00000000000000..bfabd53f289724
--- /dev/null
+++ b/playground/module-graph/__tests__/module-graph.spec.ts
@@ -0,0 +1,12 @@
+import { expect, test } from 'vitest'
+import { isServe, page, viteServer } from '~utils'
+
+test.runIf(isServe)('importedUrls order is preserved', async () => {
+  const el = page.locator('.imported-urls-order')
+  expect(await el.textContent()).toBe('[success]')
+  const mod = await viteServer.moduleGraph.getModuleByUrl(
+    '/imported-urls-order.js',
+  )
+  const importedModuleIds = [...mod.importedModules].map((m) => m.url)
+  expect(importedModuleIds).toEqual(['\x00virtual:slow-module', '/empty.js'])
+})
diff --git a/playground/module-graph/empty.js b/playground/module-graph/empty.js
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/playground/module-graph/imported-urls-order.js b/playground/module-graph/imported-urls-order.js
new file mode 100644
index 00000000000000..9ccf4527e6665d
--- /dev/null
+++ b/playground/module-graph/imported-urls-order.js
@@ -0,0 +1,7 @@
+import { msg } from 'virtual:slow-module'
+import './empty.js'
+
+export default msg
+
+// This module tests that the import order is preserved in this module's `importedUrls` property
+// as the imports can be processed in parallel
diff --git a/playground/module-graph/index.html b/playground/module-graph/index.html
new file mode 100644
index 00000000000000..663a7d7ed0066a
--- /dev/null
+++ b/playground/module-graph/index.html
@@ -0,0 +1,10 @@
+<div class="imported-urls-order"></div>
+
+<script type="module">
+  import importedUrlsOrderSuccess from './imported-urls-order'
+  text('.imported-urls-order', importedUrlsOrderSuccess)
+
+  function text(el, text) {
+    document.querySelector(el).textContent = text
+  }
+</script>
diff --git a/playground/module-graph/package.json b/playground/module-graph/package.json
new file mode 100644
index 00000000000000..35e0799c262738
--- /dev/null
+++ b/playground/module-graph/package.json
@@ -0,0 +1,12 @@
+{
+  "name": "@vitejs/test-hmr",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "debug": "node --inspect-brk ../../packages/vite/bin/vite",
+    "preview": "vite preview"
+  }
+}
diff --git a/playground/module-graph/vite.config.ts b/playground/module-graph/vite.config.ts
new file mode 100644
index 00000000000000..53e07ff3bfd483
--- /dev/null
+++ b/playground/module-graph/vite.config.ts
@@ -0,0 +1,23 @@
+import { defineConfig } from 'vite'
+import type { Plugin } from 'vite'
+
+export default defineConfig({
+  plugins: [slowModulePlugin()],
+})
+
+function slowModulePlugin(): Plugin {
+  return {
+    name: 'slow-module',
+    resolveId(id) {
+      if (id === 'virtual:slow-module') {
+        return '\0virtual:slow-module'
+      }
+    },
+    async load(id) {
+      if (id === '\0virtual:slow-module') {
+        await new Promise((resolve) => setTimeout(resolve, 500))
+        return `export const msg = '[success]'`
+      }
+    },
+  }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f68bc2bd12eb42..83017836b874ba 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -740,6 +740,8 @@ importers:
 
   playground/minify/dir/module: {}
 
+  playground/module-graph: {}
+
   playground/multiple-entrypoints:
     devDependencies:
       fast-glob: