最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

next.js - NextJS pre-render per-page data in different parts of layout? - Stack Overflow

programmeradmin1浏览0评论

The high-level problem I'm trying to solve is, I have a hero component that has an "image" and some content:

<Hero>
    <ImagePart />
    <ContentPart />
</Hero>

The "image" part can kind of be anything (an image, a video, a slide-show carousel), but, significantly, a ThreeJS animation which needs to not re-render on page navigation, though some sub-components will need to update based on the page.

I have this working, by putting the whole Hero component in a layout instead of a page, and then using usePathname and context to grab the correct per-page info, but the thing I'd like to solve is that the ContentPart could/should be a server component / pre-rendered.

If someone can suggest an "architecture" change to my layout/page/data-fetching structure so I can accomplish this, it would be much appreciated.

Here's what I'm currently doing:

/app/layout.js // async; does CMS query to get all heroes for all pages
               // also includes ThreeProvider and HeroProvider
    (pages-no-hero) // route group for no hero at all
    (pages)
        layout.js // `Hero` component is here
        page.js

Then I have

<Hero> // parent div, grid layout
    <HeroThree>
        <Model /> // lazy loads client side, must be child of ThreeProvider, must not re-render on navigation
        // ... other components which use HeroProvider to update animation
    </HeroThree>
    <StaticHero> // *** this should be static / SSR, but is a child of layout, not page
        <StaticImagePart /> // different per page; sits on top and hides HeroThree if it exists
        <Content /> // different content per page
    </StaticHero>
</Hero>

where StaticHero is currently a client component that uses usePathname and the context from the HeroProvider to grab the correct content and images from the server / CMS / CDN.

How do I "fix"* it so that StaticHero, way down as a child of Layout but not Page is pre-rendered?

I'm hoping there's some "normal" way to do this, and I'm just not thinking through the normal client/server component interleaving options correctly.

* "Fix". I mean, the whole thing works now, but the StaticHero ends up being the LCP in Lighthouse even if it's just a single line of text; and it's not just a random benchmark, there's often a visible flash as it loads.

Ideas

I have some thoughts on how to do this, but none of them seem easy, so I thought I'd ask here before I engage in "hope coding".

First, I could just move StaticHero entirely out of the Hero container, and put it as a child of page. The big problem with this is that if StaticHero and HeroThree don't share the same immediate parent, then things like alignment, size, responsiveness, etc..., all get harder, and feel like they could become very fragile and subject to accidental breaking.

Second, maybe there's some way to use server actions instead of usePathname and context to get the content for StaticHero?

Third, maybe I can do something with parallel routes and handle the animation part somewhere entirely different?

If it seems like any of those, or something entirely different, can be used to solve my problem and you have a pointer to an example doing something similar, I'm happy to take it from there!

发布评论

评论列表(0)

  1. 暂无评论