jackyzha0 / quartz

🌱 a fast, batteries-included static-site generator that transforms Markdown content into fully functional websites
https://quartz.jzhao.xyz
MIT License
7.35k stars 2.54k forks source link

Large Build Size #1607

Open sonigeez opened 2 days ago

sonigeez commented 2 days ago

Each HTML file currently averages a size of 2.5MB, likely due to repetitive inclusion of CSS/JS files. Could we explore separating these resources to reduce redundancy?

saberzero1 commented 2 days ago

The reason every shared CSS and JS is included in every page, is because users can start navigating the site starting from any arbitrary page on the website.

Despite this, most CSS and JS are cached, so only the first page loads ~2.5mb over the network, afterwards it uses the cache.

Another potentially large contributer might be a large explorer list (so many pages). These are also cached however.

If you want to reduce the bundle size, disable feature you don't use. For example, Katex uses about ~800kb (or 1/3 of the bundle size.) If you don't use this, it will save you a bit of bundle size.

Can you please verify that navigating between pages uses the cache? If it doesn't, that would require a change or fix to the caching policy.

sonigeez commented 1 day ago

Despite this, most CSS and JS are cached, so only the first page loads ~2.5mb over the network, afterwards it uses the cache.

I'm a bit confused about how that works. If the content (HTML, JS) is bundled into a single file(except fonts, css and few js scripts), how does caching would work only some of the data inside that file? And whenever i navigate between file it does fetch entire content including duplication of many js bundles.

Additionally, regarding unused features: I already disabled KaTeX, but this didn't affect the overall bundle size. On inspecting the HTML, I noticed the KaTeX library's code is still bundled into every HTML file.

saberzero1 commented 1 day ago

Despite this, most CSS and JS are cached, so only the first page loads ~2.5mb over the network, afterwards it uses the cache.

I'm a bit confused about how that works. If the content (HTML, JS) is bundled into a single file(except fonts, css and few js scripts), how does caching would work only some of the data inside that file? And whenever i navigate between file it does fetch entire content including duplication of many js bundles.

Additionally, regarding unused features: I already disabled KaTeX, but this didn't affect the overall bundle size. On inspecting the HTML, I noticed the KaTeX library's code is still bundled into every HTML file.

There is very few inlined JS/CSS. And yes, the other files (index.css, prescript.js, postscript.js, a few static icons, etc.) are indeed fetched on page load (or more accurately, nav event). These are cached. So after an initial network fetch, these are cached in your browser. They are once again fetched on nav, but from the browser cache instead, which is significantly faster than the network.

As for the KaTeX part, do you mind sharing your quartz.config.ts file? Or preferable link your repo if public, so I can do some investigation?

sonigeez commented 1 day ago

this is my config and it's deployed on https://logs.anokha.me. and it fetch 700kb(compressed version of 2.5mb) of html on every page load which is a lot i think

import type { QuartzConfig } from "./quartz/cfg";
import * as Plugin from "./quartz/plugins";

/**
 * Quartz 4.0 Configuration
 *
 * See https://quartz.jzhao.xyz/configuration for more information.
 */
const config: QuartzConfig = {
    configuration: {
        pageTitle: "Anokha Logs",
        pageTitleSuffix: "",
        enableSPA: true,
        enablePopovers: true,
        analytics: {
            provider: "plausible",
        },
        locale: "en-US",
        baseUrl: "logs.anokha.me",
        ignorePatterns: ["private", "templates", ".obsidian"],
        defaultDateType: "created",
        generateSocialImages: false,
        theme: {
            fontOrigin: "googleFonts",
            cdnCaching: true,
            typography: {
                header: "Sour Gummy",
                body: "Merriweather",
                code: "JetBrains Mono",
            },
            colors: {
                lightMode: {
                    light: "#fefefe",
                    lightgray: "#f4f6fa",
                    gray: "#94a3b8",
                    darkgray: "#334155",
                    dark: "#0f172a",
                    secondary: "#6366f1",
                    tertiary: "#8b5cf6",
                    highlight: "rgba(99, 102, 241, 0.08)",
                    textHighlight: "#f9a8d488",
                },
                darkMode: {
                    light: "#0f172a",
                    lightgray: "#1e293b",
                    gray: "#94a3b8",
                    darkgray: "#e2e8f0",
                    dark: "#f8fafc",
                    secondary: "#818cf8",
                    tertiary: "#a78bfa",
                    highlight: "rgba(99, 102, 241, 0.12)",
                    textHighlight: "#f9a8d444",
                },
            },
        },
    },
    plugins: {
        transformers: [
            Plugin.FrontMatter(),
            Plugin.SyntaxHighlighting({
                theme: {
                    light: "github-light",
                    dark: "github-dark",
                },
                keepBackground: false,
            }),
            Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }),
            Plugin.GitHubFlavoredMarkdown(),
            Plugin.TableOfContents(),
            Plugin.Description(),
        ],
        filters: [Plugin.RemoveDrafts()],
        emitters: [
            Plugin.AliasRedirects(),
            Plugin.ComponentResources(),
            Plugin.ContentPage(),
            Plugin.FolderPage(),
            Plugin.TagPage(),
            Plugin.Assets(),
            Plugin.Static(),
        ],
    },
};

export default config;
aarnphm commented 1 day ago

ah the increase in bundle size is due to the recent support for mermaid (in which we dump the JS onto the final HTML files https://github.com/jackyzha0/quartz/pull/1575)

we can probably update the emitter to dump mermaid.run to reduce bundle size

you can check with --bundleInfo

fwiw you can use rehypeMermaid, but it involves setting up playwright, in which I think probably not good for default Quartz.

Best solution is to have a plugin system (Eh I will get to it sometime this holiday szn lol) so we can done all of this beforehand, eliminating any sort of need for inline JS bundling.

sonigeez commented 1 day ago

thanks for the insight, @aarnphm removing mermaid did the trick—my build size has dropped back to normal. appreciate the suggestion, and looking forward to this in plugin system when you get around to it