Inertia SSR + Vite + Laravel资源重复加载问题排查
问题描述
刚接触Inertia框架,在使用SSR模式时遇到一个问题:通过Link组件进行页面跳转时,浏览器会重新加载所有资源,包括布局中引入的图片也会每次都重新加载。已按照Inertia官方文档完成配置,整体功能正常,想请教这是否是资源版本控制导致的,或是其他原因?
相关代码
app.js
import { createSSRApp, h } from 'vue' import { createInertiaApp } from '@inertiajs/inertia-vue3' import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers' import Layout from './layouts/Layout.vue' createInertiaApp({ resolve: async name => { const page = await resolvePageComponent(`./pages/${name}.vue`, import.meta.glob('./pages/**/*.vue')) page.default.layout ??= Layout return page }, setup({ el, App, props, plugin }) { createSSRApp({ render: () => h(App, props) }) .use(plugin) .mount(el) }, })
ssr.js
import { createInertiaApp } from '@inertiajs/vue3' import createServer from '@inertiajs/vue3/server' import { renderToString } from '@vue/server-renderer' import { createSSRApp, h } from 'vue' import Layout from './layouts/Layout.vue' import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers' createServer(page => createInertiaApp({ page, render: renderToString, resolve: async name => { const page = await resolvePageComponent(`./pages/${name}.vue`, import.meta.glob('./pages/**/*.vue')) page.default.layout ??= Layout return page }, setup({ App, props, plugin }) { return createSSRApp({ render: () => h(App, props), }).use(plugin) }, }), )
Layout.vue
<template> <main> <header> <Link href="/">Home</Link> <Link href="/about">About</Link> <Link href="/contact">Contact</Link> </header> <img src="../../img/test.png" alt="test" style="width: 400px" /> <article> <slot /> </article> </main> </template> <script setup> import { Link } from '@inertiajs/vue3' </script>
问题分析与解决
核心原因
- 图片路径未经过构建工具处理:你直接用相对路径
../../img/test.png引入图片,这种方式没有让Vite参与资源的版本化和缓存处理。在SSR模式下,浏览器每次跳转都会直接请求该路径,无法利用缓存机制。 - 资源缓存策略缺失:未对静态资源配置长期缓存头,导致浏览器无法缓存资源,每次都发起新请求。
解决步骤
1. 改用Vite规范的资源引入方式
有两种可靠的方式处理图片资源:
- 方式一:通过import引入
修改Layout.vue,将图片作为模块导入,让Vite自动处理版本哈希:
<template> <main> <header> <Link href="/">Home</Link> <Link href="/about">About</Link> <Link href="/contact">Contact</Link> </header> <img :src="testImage" alt="test" style="width: 400px" /> <article> <slot /> </article> </main> </template> <script setup> import { Link } from '@inertiajs/vue3' import testImage from '../../img/test.png' </script>
- 方式二:使用public目录
将图片放到项目根目录的public/img文件夹下,然后用绝对路径引用:
<img src="/img/test.png" alt="test" style="width: 400px" />
2. 确认Vite资源版本化配置
Vite默认会为构建后的资源添加哈希后缀,确保只有资源更新时URL才会变化。可以在vite.config.js中确认配置:
export default defineConfig({ build: { rollupOptions: { output: { assetFileNames: 'assets/[name]-[hash][extname]', }, }, }, })
3. 配置服务器缓存头
在后端(如Laravel)或Web服务器(如Nginx)中为静态资源设置长期缓存策略:
- Laravel配置:在
config/filesystems.php中修改public磁盘配置:
'public' => [ 'driver' => 'local', 'root' => public_path(), 'url' => env('APP_URL').'/storage', 'visibility' => 'public', 'cache_control' => 'public, max-age=31536000, immutable', ],
- Nginx配置:在服务器配置中添加:
location ~* \.(png|jpg|jpeg|gif)$ { expires 1y; add_header Cache-Control "public, immutable"; }
4. 验证Inertia Link组件行为
打开浏览器开发者工具的Network标签,确认点击Link组件时,只有XHR请求而没有整页HTML请求。如果出现整页请求,说明Link组件未正确初始化,需检查SSR配置是否存在遗漏。
内容的提问来源于stack exchange,提问作者general666
相关产品推荐
相关产品推荐

