Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NextJS Static Site Bundling A Bunch Of self.__next_f.push Instead Of Raw HTML #56180

Closed
1 task done
loganknecht opened this issue Sep 28, 2023 · 10 comments
Closed
1 task done
Labels
bug Issue was opened via the bug report template. linear: dx Confirmed issue that is tracked by the DX team.

Comments

@loganknecht
Copy link

loganknecht commented Sep 28, 2023

Link to the code that reproduces this issue

https://github.com/LoganKnechtMagicLeap/NextJS-Static-Example

To Reproduce

Summary

Hello. 👋

I'm in the process of working with the new NextJS 13 stuff, and to be honest - I'm not really enjoying it.

I'm trying to get a static artifact exported, and it kind of works, but it really doesn't.

What's driving me nuts is that the static artifacts it's generating are adding all these unnecessary self.__next_f.push lines, that are really unneeded. And, I'm super confused as to what they're there for.

Next Config

This is a barebones, vanilla NextJS 13 project.
To reproduce it I created the application by running

npx create-next-app@latest example_app

Here's my next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
    distDir: "build",
    output: "export"
};

module.exports = nextConfig;

Source

This is the source page

import Image from "next/image";

function Home() {
    // ---------------------------------------------------------------------------
    // Rendering
    // ---------------------------------------------------------------------------
    const final_render_element = (
        <main>
            <div>
                <p>
                    Get started by editing&nbsp;
                    <code>src/app/page.tsx</code>
                </p>
                <div>
                    <a
                        href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
                        target="_blank"
                        rel="noopener noreferrer"
                    >
                        By <Image src="/vercel.svg" alt="Vercel Logo" width={100} height={24} priority />
                    </a>
                </div>
            </div>

            <div>
                <Image src="/next.svg" alt="Next.js Logo" width={180} height={37} priority />
            </div>

            <div>
                <a
                    href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
                    target="_blank"
                    rel="noopener noreferrer"
                >
                    <h2>
                        Docs <span>-&gt;</span>
                    </h2>
                    <p>Find in-depth information about Next.js features and API.</p>
                </a>

                <a
                    href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
                    target="_blank"
                    rel="noopener noreferrer"
                >
                    <h2>
                        Learn <span>-&gt;</span>
                    </h2>
                    <p>Learn about Next.js in an interactive course with&nbsp;quizzes!</p>
                </a>

                <a
                    href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
                    target="_blank"
                    rel="noopener noreferrer"
                >
                    <h2>
                        Templates <span>-&gt;</span>
                    </h2>
                    <p>Explore the Next.js 13 playground.</p>
                </a>

                <a
                    href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
                    target="_blank"
                    rel="noopener noreferrer"
                >
                    <h2>
                        Deploy <span>-&gt;</span>
                    </h2>
                    <p>Instantly deploy your Next.js site to a shareable URL with Vercel.</p>
                </a>
            </div>
        </main>
    );

    return final_render_element;
}

export default Home;

Output

I'm using a default NextJS application, and this is what it's outputting

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link
            rel="preload"
            as="font"
            href="/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2"
            crossorigin=""
            type="font/woff2"
        />
        <link rel="preload" as="image" href="/vercel.svg" fetchPriority="high" />
        <link rel="preload" as="image" href="/next.svg" fetchPriority="high" />
        <link rel="stylesheet" href="/_next/static/css/ed4d508feb2dc8fd.css" data-precedence="next" />
        <link rel="preload" href="/_next/static/chunks/webpack-fece8402f682851f.js" as="script" fetchPriority="low" />
        <script src="/_next/static/chunks/fd9d1056-6b91f437b4d494b5.js" async=""></script>
        <script src="/_next/static/chunks/596-d618d193f52e19b7.js" async=""></script>
        <script src="/_next/static/chunks/main-app-e038a94c85256af1.js" async=""></script>
        <link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="16x16" />
        <meta name="next-size-adjust" />
        <script src="/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js" nomodule=""></script>
    </head>
    <body class="__className_e66fe9">
        <main>
            <div>
                <p>Get started by editing <code>src/app/page.tsx</code></p>
                <div>
                    <a
                        href="https://vercel.com?utm_source=create-next-app&amp;utm_medium=appdir-template&amp;utm_campaign=create-next-app"
                        target="_blank"
                        rel="noopener noreferrer"
                        >By
                        <img
                            alt="Vercel Logo"
                            fetchPriority="high"
                            width="100"
                            height="24"
                            decoding="async"
                            data-nimg="1"
                            style="color: transparent"
                            src="/vercel.svg"
                    /></a>
                </div>
            </div>
            <div>
                <img
                    alt="Next.js Logo"
                    fetchPriority="high"
                    width="180"
                    height="37"
                    decoding="async"
                    data-nimg="1"
                    style="color: transparent"
                    src="/next.svg"
                />
            </div>
            <div>
                <a
                    href="https://nextjs.org/docs?utm_source=create-next-app&amp;utm_medium=appdir-template&amp;utm_campaign=create-next-app"
                    target="_blank"
                    rel="noopener noreferrer"
                    ><h2>Docs <span>-&gt;</span></h2>
                    <p>Find in-depth information about Next.js features and API.</p></a
                ><a
                    href="https://nextjs.org/learn?utm_source=create-next-app&amp;utm_medium=appdir-template&amp;utm_campaign=create-next-app"
                    target="_blank"
                    rel="noopener noreferrer"
                    ><h2>Learn <span>-&gt;</span></h2>
                    <p>Learn about Next.js in an interactive course with quizzes!</p></a
                ><a
                    href="https://vercel.com/templates?framework=next.js&amp;utm_source=create-next-app&amp;utm_medium=appdir-template&amp;utm_campaign=create-next-app"
                    target="_blank"
                    rel="noopener noreferrer"
                    ><h2>Templates <span>-&gt;</span></h2>
                    <p>Explore the Next.js 13 playground.</p></a
                ><a
                    href="https://vercel.com/new?utm_source=create-next-app&amp;utm_medium=appdir-template&amp;utm_campaign=create-next-app"
                    target="_blank"
                    rel="noopener noreferrer"
                    ><h2>Deploy <span>-&gt;</span></h2>
                    <p>Instantly deploy your Next.js site to a shareable URL with Vercel.</p></a
                >
            </div>
        </main>
        <script src="/_next/static/chunks/webpack-fece8402f682851f.js" async=""></script>
        <script>
            (self.__next_f = self.__next_f || []).push([0]);
        </script>
        <script>
            self.__next_f.push([
                1,
                '1:HL["/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2",{"as":"font","type":"font/woff2"}]\n2:HL["/_next/static/css/ed4d508feb2dc8fd.css",{"as":"style"}]\n0:"$L3"\n'
            ]);
        </script>
        <script>
            self.__next_f.push([
                1,
                '4:I{"id":7948,"chunks":["272:static/chunks/webpack-fece8402f682851f.js","971:static/chunks/fd9d1056-6b91f437b4d494b5.js","596:static/chunks/596-d618d193f52e19b7.js"],"name":"default","async":false}\n6:I{"id":6628,"chunks":["272:static/chunks/webpack-fece8402f682851f.js","971:static/chunks/fd9d1056-6b91f437b4d494b5.js","596:static/chunks/596-d618d193f52e19b7.js"],"name":"","async":false}\n7:I{"id":5840,"chunks":["185:static/chunks/app/layout-fcfe5bad3e0d6a2f.js"],"name":"","async":false}\n8:I{"id":7767,"chunks"'
            ]);
        </script>
        <script>
            self.__next_f.push([
                1,
                ':["272:static/chunks/webpack-fece8402f682851f.js","971:static/chunks/fd9d1056-6b91f437b4d494b5.js","596:static/chunks/596-d618d193f52e19b7.js"],"name":"default","async":false}\n9:I{"id":7920,"chunks":["272:static/chunks/webpack-fece8402f682851f.js","971:static/chunks/fd9d1056-6b91f437b4d494b5.js","596:static/chunks/596-d618d193f52e19b7.js"],"name":"default","async":false}\nb:I{"id":3222,"chunks":["222:static/chunks/222-a1a53c3588663d0e.js","951:static/chunks/app/home/page-184a94689c89ce33.js"],"name":"Image",'
            ]);
        </script>
        <script>
            self.__next_f.push([1, '"async":false}\n']);
        </script>
        <script>
            self.__next_f.push([
                1,
                '3:[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/ed4d508feb2dc8fd.css","precedence":"next"}]],["$","$L4",null,{"buildId":"QBbY6GxvsI2ECPcpts1-Q","assetPrefix":"","initialCanonicalUrl":"/home","initialTree":["",{"children":["home",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],"initialHead":[false,"$L5"],"globalErrorComponent":"$6","children":[null,["$","$L7",null,{"children":["$","$L8",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","template":["$","$L9",null,{}],"templateStyles":"$undefined","notFound":["$","div",null,{"children":"TODO"}],"notFoundStyles":[],"childProp":{"current":["$","$L8",null,{"parallelRouterKey":"children","segmentPath":["children","home","children"],"loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","template":["$","$L9",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":["$La",["$","main",null,{"children":[["$","div",null,{"children":[["$","p",null,{"children":["Get started by editing ",["$","code",null,{"children":"src/app/page.tsx"}]]}],["$","div",null,{"children":["$","a",null,{"href":"https://vercel.com?utm_source=create-next-app\u0026utm_medium=appdir-template\u0026utm_campaign=create-next-app","target":"_blank","rel":"noopener noreferrer","children":["By ",["$","$Lb",null,{"src":"/vercel.svg","alt":"Vercel Logo","width":100,"height":24,"priority":true}]]}]}]]}],["$","div",null,{"children":["$","$Lb",null,{"src":"/next.svg","alt":"Next.js Logo","width":180,"height":37,"priority":true}]}],["$","div",null,{"children":[["$","a",null,{"href":"https://nextjs.org/docs?utm_source=create-next-app\u0026utm_medium=appdir-template\u0026utm_campaign=create-next-app","target":"_blank","rel":"noopener noreferrer","children":[["$","h2",null,{"children":["Docs ",["$","span",null,{"children":"-\u003e"}]]}],["$","p",null,{"children":"Find in-depth information about Next.js features and API."}]]}],["$","a",null,{"href":"https://nextjs.org/learn?utm_source=create-next-app\u0026utm_medium=appdir-template\u0026utm_campaign=create-next-app","target":"_blank","rel":"noopener noreferrer","children":[["$","h2",null,{"children":["Learn ",["$","span",null,{"children":"-\u003e"}]]}],["$","p",null,{"children":"Learn about Next.js in an interactive course with quizzes!"}]]}],["$","a",null,{"href":"https://vercel.com/templates?framework=next.js\u0026utm_source=create-next-app\u0026utm_medium=appdir-template\u0026utm_campaign=create-next-app","target":"_blank","rel":"noopener noreferrer","children":[["$","h2",null,{"children":["Templates ",["$","span",null,{"children":"-\u003e"}]]}],["$","p",null,{"children":"Explore the Next.js 13 playground."}]]}],["$","a",null,{"href":"https://vercel.com/new?utm_source=create-next-app\u0026utm_medium=appdir-template\u0026utm_campaign=create-next-app","target":"_blank","rel":"noopener noreferrer","children":[["$","h2",null,{"children":["Deploy ",["$","span",null,{"children":"-\u003e"}]]}],["$","p",null,{"children":"Instantly deploy your Next.js site to a shareable URL with Vercel."}]]}]]}]]}],null],"segment":"__PAGE__"},"styles":[]}],"segment":"home"},"styles":[]}],"params":{}}],null]}]]\n'
            ]);
        </script>
        <script>
            self.__next_f.push([
                1,
                '5:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","link","2",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","3",{"name":"next-size-adjust"}]]\na:null\n'
            ]);
        </script>
    </body>
</html>

This is mostly fine, except it's doing this crazy thing with the self.__next_f.push and that's not helping me with my artifacts.

Question

How the heck do I get these self.__next_f.push to stop being generated and remove them entirely?

Current vs. Expected behavior

It injects a bunch of self.__next_f.push, when I expect raw HTML

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:27 PDT 2021; root:xnu-7195.141.2~5/RELEASE_ARM64_T8101
    Binaries:
      Node: 16.15.1
      npm: 8.11.0
      Yarn: 1.22.19
      pnpm: N/A
    Relevant Packages:
      next: 13.4.19
      eslint-config-next: 13.4.19
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.2.2
    Next.js Config:
      output: export

Which area(s) are affected? (Select all that apply)

Static HTML Export (output: "export")

Additional context

I have tried modifying webpack to not use chunking. I have tried forcing client only.

I have my layout.tsx file prepended with "use client"; so that every page is supposedly client side only, even though that shouldn't matter.

I have tried many solutions, but I just cannot figure out what's going here. This is the default application from NextJS. Why does it need to inject so much with JavaScript??

DX-2261

@loganknecht loganknecht added the bug Issue was opened via the bug report template. label Sep 28, 2023
@gnoff
Copy link
Contributor

gnoff commented Sep 29, 2023

Hi @loganknecht those scripts are the initialization of the router state on the client. When next navigates from one page to another it does a client side transition (with a fetch to the server to get whatever new markup is required). Unlike in pages router App Router has shared layouts and the client is aware of these layouts and only fetches the part of the page that is not shared. The scripts you see here are the initialization of the client router state so that it can do these navigations. effectively. This includes preserving scroll position when hitting the back button and other aspects of the Router behavior.

@loganknecht
Copy link
Author

@gnoff - I understand.

The goal for my usage of NextJS and its static site generation feature, is that I want pretty simple html artifacts.
I also do not want to use server side rendering to return the pages. I have added use client to my layout.tsx to hopefully indicate this across the project.

Additionally I do not want to rely on the client router once this artifact has been created. I want to rely on html anchor tags for navigation instead of a client side router.

Is there any way to achieve this?

@frontimin
Copy link

We have the same problem, our pages are getting too heavy

@irmakcosarsahna

This comment has been minimized.

@mwmwmw
Copy link

mwmwmw commented Nov 2, 2023

I'm linking this discussion here. #42170

With React 14, there are now hundreds of injected script tags on relatively small pages.

@oalexdoda
Copy link

I was pretty surprised to realize that "server-side generated HTML" doesn't simply render static HTML, but rather tons of inline script. Especially concerning if you use the app directory on a marketing site where HTML source size can mess up your SEO / page load speed. Is there any fix or workaround for this?

@MISRV001
Copy link

MISRV001 commented Dec 9, 2023

Similar to #42170

@apiel
Copy link

apiel commented Dec 14, 2023

The goal for my usage of NextJS and its static site generation feature, is that I want pretty simple html artifacts.

Nextjs is far from being optimal to do SSG. If you only want to do SSG, there is great tool out there like Astro.

The main problem is how React is design and the way it does the hydration, it need pure JavaScript object to be able to achieve this. Would be great if they could do it base on the HTML element instead of JavaScript, but I don't think they will change the hydration logic of React (at least soon).
However, they could change the way they load the hydration component. Instead to make it part of the rendered page, they could load it on demand on a separate call, only if necessary...

@delbaoliveira delbaoliveira added the linear: dx Confirmed issue that is tracked by the DX team. label Dec 14, 2023
@thaophamvan
Copy link

I can see both App router and page router have same issue about double document size

@leerob
Copy link
Member

leerob commented Jan 15, 2024

Let's continue on the discussion: #42170 (comment)

@leerob leerob closed this as completed Jan 15, 2024
@vercel vercel locked as resolved and limited conversation to collaborators Jan 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. linear: dx Confirmed issue that is tracked by the DX team.
Projects
None yet
Development

No branches or pull requests