You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

问题分析与解决

核心原因

  1. 图片路径未经过构建工具处理:你直接用相对路径../../img/test.png引入图片,这种方式没有让Vite参与资源的版本化和缓存处理。在SSR模式下,浏览器每次跳转都会直接请求该路径,无法利用缓存机制。
  2. 资源缓存策略缺失:未对静态资源配置长期缓存头,导致浏览器无法缓存资源,每次都发起新请求。

解决步骤

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 13:20:01