服务器端获取的数据出现,消失并在VUE 3 / NUXT 3生产上重新出现

发布于 2025-02-11 17:33:21 字数 2981 浏览 1 评论 0原文

更新 - 对Google Chrome的性能选项卡的额外见解

,我注意到每当网络请求资产时,元素的消失就会发生。

例如:

  1. 由于在服务器端
  2. 客户端加载了徽标徽标徽标
  3. 徽标消失的
  4. 客户端已完成徽标
  5. 徽标重新出现,

但徽标已在那里,尽管客户端启动是预期的行为,我仍然相信,我仍然相信应用程序足够聪明,可以理解徽标资产与服务器端相同。我有机会避免这种消失的内容吗?

在我的NUXT 3/VUE 3 SSR项目中介绍

,我有一个server/api/prismic.js文件,可以从Prismic(无头CMS)中获取我们的应用程序内容。

然后,在我们的页面/[... uid] .vue文件中,我获取数据并渲染切片。 这神奇地起作用;就像在网站中一样,加载迅速。

但是..问题在于,在我们的动态页面完成加载之前,我会立即出现故障。因此,我将获得以下内容:

  1. 页面加载
  2. 页面立即包含带有内容
  3. 页面的组件消失的
  4. 页面再次出现在相同的数据中出现,

不幸的是 没有工作:仅在服务器端获取数据。因为那时我最终有一个空白页。

该问题确实 localhost上发生:3000YARN BUILD& amp;测试。纱线开始,但仅在Heroku上的部署版本上。

我知道这个问题可能是因为客户正在开始,但是我仍然想知道是否有人可以帮助或指导我问题。这是NUXT 3问题吗?还是特定于vue-router的东西?

我在应用程序级别上发现的内容

,我还从api/prismic端点获取以获取导航和页脚内容。我注意到导航和页脚也出现,消失并重新出现。使用导航&页脚参考仍然包含相同的内容。

这消除了我的一些理论,例如将对象传递给我的动态组件的事实是罪魁祸首。

代码

app.vue

<template>
  <div id="wrapper">
    <Navigation :nav="navigation" />
    <main id="page">
      <NuxtPage :key="$route.path" />
    </main>
    <Footer :footer="footer" />
  </div>
</template>

<script setup>
const { data: navigation } = await useFetch(
  '/api/prismic?type=single&uid=header',
  { key: 'header' },
)
const { data: footer } = await useFetch(
  '/api/prismic?type=single&uid=footer', 
  { key: 'footer' },
)
</script>

server/api/prismic.js

export default defineEventHandler(async (event) => {
  const query = useQuery(event)
  const { repo, type, uid } = query
  const qTypes = {
    id: 'document.id',
    page: 'my.page.uid',
    single: 'document.type',
  }
  const { access_token, endpoint } = import.meta.env
  let params = { access_token }
  const prismicRef = await $fetch(endpoint, { params })
  params.ref = prismicRef.refs[0].ref
  params.q = `[[at(${qTypes[type] || 'document.id'}, "${uid}")]]`
  const document = await $fetch(`${endpoint}/documents/search`, { params })
  if (document.results && document.results.length > 0) {
    return document.results[0].data
  }
  return null
})

pages/[... uid] .vue

<template>
  <div id="slices">
    <component
      v-for="(slice, index) in page.body"
      :is="slice.slice_type"
      :key="`${$route.path}-${index}`"
      :slice="slice"
    />
  </div>
</template>

<script setup>
definePageMeta({ middleware: ['default'], pageTransition: { name: 'fade' } })
const route = useRoute()
const uid = ref(route.params.uid[0] || 'home')
const { data: page } = await useFetch(
  `/api/prismic?type=page&uid=${uid.value}`,
  { key: uid.value },
)
</script>

Update - extra insights

Looking into the performance tab of Google Chrome, I noticed that the disappearing of elements happen whenever the network is requesting an asset.

For example:

  1. The logo is there due to being loaded on server side
  2. Client side fetches the logo asset
  3. Logo disappears
  4. Client side has finished fetching the logo
  5. Logo re-appears

Although the client-side kicking in is expected behavior, I would still believe that the app would be smart enough to understand the logo asset is the same as the server side. Any chance I can avoid this disappearing of the content?

Intro

In my Nuxt 3 / Vue 3 SSR project, I have a server/api/prismic.js file that fetches our application content from Prismic (Headless CMS).

Then, in our pages/[...uid].vue file, I fetch that data and render the slices.
This works magically; as in the website loads blazing fast.

However.. the problem is that I'm getting a glitch right before our dynamic page is finished loading. So I get the following:

  1. Page loads
  2. Page immediately contains components loaded with content
  3. Page disappears
  4. Page appears again with the same data

What unfortunately doesn't work: only fetching the data on a server-side. Because then I end up having a blank page.

The issue does not happen on localhost:3000 tested with yarn build && yarn start, but only on the deployed version on Heroku.

I'm aware this issue is probably because the client is kicking in, but I was still wondering if anyone could help or guide me what the issue might be. Is this a Nuxt 3 issue? Or maybe something specific to vue-router?

What I discovered

On app level, I also fetch from my api/prismic endpoint to fetch the navigation and footer content. I noticed that the navigation and footer also appear, disappear and re-appear; with the navigation & footer ref both still containing the same content content.

This removes a few theories that I had, such as the fact that passing an object to my dynamic component is the culprit.

Code

app.vue

<template>
  <div id="wrapper">
    <Navigation :nav="navigation" />
    <main id="page">
      <NuxtPage :key="$route.path" />
    </main>
    <Footer :footer="footer" />
  </div>
</template>

<script setup>
const { data: navigation } = await useFetch(
  '/api/prismic?type=single&uid=header',
  { key: 'header' },
)
const { data: footer } = await useFetch(
  '/api/prismic?type=single&uid=footer', 
  { key: 'footer' },
)
</script>

server/api/prismic.js

export default defineEventHandler(async (event) => {
  const query = useQuery(event)
  const { repo, type, uid } = query
  const qTypes = {
    id: 'document.id',
    page: 'my.page.uid',
    single: 'document.type',
  }
  const { access_token, endpoint } = import.meta.env
  let params = { access_token }
  const prismicRef = await $fetch(endpoint, { params })
  params.ref = prismicRef.refs[0].ref
  params.q = `[[at(${qTypes[type] || 'document.id'}, "${uid}")]]`
  const document = await $fetch(`${endpoint}/documents/search`, { params })
  if (document.results && document.results.length > 0) {
    return document.results[0].data
  }
  return null
})

pages/[...uid].vue

<template>
  <div id="slices">
    <component
      v-for="(slice, index) in page.body"
      :is="slice.slice_type"
      :key="`${$route.path}-${index}`"
      :slice="slice"
    />
  </div>
</template>

<script setup>
definePageMeta({ middleware: ['default'], pageTransition: { name: 'fade' } })
const route = useRoute()
const uid = ref(route.params.uid[0] || 'home')
const { data: page } = await useFetch(
  `/api/prismic?type=page&uid=${uid.value}`,
  { key: uid.value },
)
</script>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一城柳絮吹成雪 2025-02-18 17:33:21

最终解决了这个问题;这里有一些背景:

在我最初的问题和此答案之间的时间里,我已经移至使用NUXT SSG而不是SSR,并遇到了完全相同的问题。

在与NUXT 3玩了很多时,我终于能够找到真正的罪魁祸首:Cloudflare。

最终是CF在HTML代码上的缩小。 CF正在删除Vue的评论片段,例如&lt;! - ] - &gt;,显然使Vue 3不需要单个根元素。

由于这些片段在缩小过程中被删除,因此该应用程序没有应有的反应。

在使用此解决方案之前,我已经发布了 nuxt 3的repo ,哪个问题包含有关该问题的完整解释。

Finally resolved the issue; here's some background:

In the time between my initial question and this answer, I already moved to using Nuxt SSG instead of SSR and encountered the exact same problem.

After a lot of playing around with Nuxt 3, I finally was able to find the real culprit: CloudFlare.

It ended up being CF's minification on the HTML code. CF was removing Vue's comment fragments such as <!--]-->, which apparently enables Vue 3 not to require a single root element.

Since those fragments got removed during minification, the app didn't react as it should've.

Before coming with this solution, I had already posted an issue on Nuxt 3's repo, which contains full explanation on the issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文