Open zhangyx1998 opened 10 months ago
I am happy to work on a PR regarding this if someone could provide me an idea of where to look at.
Try setting metaChunk: true
in your vitepress config. It won't skip SSR but will be better than having the data on each page.
Try setting
metaChunk: true
in your vitepress config. It won't skip SSR but will be better than having the data on each page.
It did reduce the overall size from 1.7GB
to 1.2GB
.
I compared the results with and without the flag. Sidebar and nav items did NOT go away as you told me.
I noticed the following changes to a specific html file as an example:
--- before/xorg-docs/README.html
+++ after/xorg-docs/README.html
@@ -7,7 +7,7 @@
<meta name="description" content="Modern looking documentation for X. Content ported from X.org (version 11, release 7.7).">
<meta name="generator" content="VitePress v1.0.0-rc.32">
<link rel="preload stylesheet" href="/assets/style.a3MijG5e.css" as="style">
+ <script type="module" src="/assets/chunks/metadata.8c95dd74.js"></script>
<script type="module" src="/assets/app.h1QJGMyB.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.bvIUbFQP.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/framework.7MjZCsaf.js">
@@ -155,7 +155,7 @@
</p></div></div></div></div></main><footer class="VPDocFooter" data-v-29e741fd data-v-604f3077> (omitted) </footer>
- <script>window.__VP_HASH_MAP__=JSON.parse(/* 347440 Characters Omitted */);</script>
</body>
</html>
Would you think it helpful to have an option that leaves the sidebar and nav items for client side rendering?
Can you try patching node_modules/vitepress/dist/client/theme-default/Layout.vue
directly to wrap the VPNav
and VPSidebar
components with <ClientOnly>
? If the results are promising, we can try making their client side rendering configurable.
There is another potential optimization that can be done for space - an option to ditch the SPA routing - if the whole side is re-rendered every time one opens a page or clicks a link to open a page, we don't need JS files other *.lean.js
(except few chunks like theme/framework/app). This could theoretically reduce the size by nearly half. But might not seem good experience for end users 🤔
Can you try patching
node_modules/vitepress/dist/client/theme-default/Layout.vue
directly to wrap theVPNav
andVPSidebar
components with<ClientOnly>
? If the results are promising, we can try making their client side rendering configurable.There is another potential optimization that can be done for space - an option to ditch the SPA routing - if the whole side is re-rendered every time one opens a page or clicks a link to open a page, we don't need JS files other
*.lean.js
(except few chunks like theme/framework/app). This could theoretically reduce the size by nearly half. But might not seem good experience for end users 🤔
Description | Size | Inflate |
---|---|---|
No config, using official config template | 1.7GB | $\times~69.6$ |
Enable metaChunk config option |
1.2GB | $\times~49.2$ |
Enable metaChunk , and ClientOnly for VPNav, VPLocalNav and VPSidebar |
91MB | $\times~~~3.6$ |
Raw content (before converting to VitePress) | 25MB | $\times~~~1.0\$ |
import { defineConfig } from 'vitepress';
defineConfig({
defaultTheme: {
// Navbar does not change between routes,
// so we only need a switch between SSR and CSR
nav: "nav.json",
// option 1: pass a `json` file path as string
// so the entire component will be client only
sidebar: "docs/index.sidebar.json",
// option 2 and 3: pass an object, with EACH entry configurable
sidebar: {
// Compatible with the original config
"/a/": {
text: "I want full SSR",
items: ["/a/page-1", /* ... */]
},
// option 2: Server side render the skeleton,
// and lazy fetch items
"/b/": {
text: "I want partial SSR, items shall be fetched when uncollapsed",
items: "docs/b/items.json",
collapsed: true,
},
// option 3: Client side render on **route match**,
// smaller chunks than option 1
"/c/": "docs/c/sidebar.json",
},
}
})
markRaw
in Vue:import { defineConfig, clientOnly } from 'vitepress';
defineConfig({
defaultTheme: {
nav: clientOnly([/* ... */]),
// Options similar to above
sidebar: clientOnly({ /* ... */ }),
}
})
clientOnly
markers:// Trick to mark an object by extending its prototype chain
export class ClientOnlyObject extends Object { };
// The marker function
export function
clientOnly<T extends ClientOnlyObject>(obj: T) : T & ClientOnlyObject {
return Object.assign(new ClientOnlyObject(), obj);
}
// Utility to check if an object is marked as client-only
export function
isClientOnly(obj: any) : boolean {
return obj instanceof ClientOnlyObject;
}
Is your feature request related to a problem? Please describe.
After addressing the problem of memory overflow (issue #3362, pr #3366), I ended up producing a bundle that, although worked fine, turned out to be very large in size. Especially when compared to the original content size.
I investigated the produced html source tree and found each of them contains a copy of their corresponding navbar and sidebar, parsed into html template.
Describe the solution you'd like
Instead of hard-coding the sidebar (and maybe the navbar) as html templates into each entry file, provide a configuration switch to fall back to client side rendering with their data chunked separately as JSON files.
Describe alternatives you've considered
Not applicable
Additional context
To provide an idea of the scale of size, here is a summary of related objects in my project:
nav
objectsidebar
objectAnd here is a link of the deployed site: x.z-yx.cc
Validations