I made a dark mode with vanilla extract on Nextjs, but it's too slow. What is the problem?

197 Views Asked by At

I use vanilla extract like this


/** layout.tsx */

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const cookieStore = cookies();
  const theme = cookieStore.get("theme");
  return (
    <html lang="ko-KR">
      <link rel="icon" href="/favicon.ico" sizes="any" />
      <body className={theme?.value === "light" ? ligthTheme : darkTheme}>
        <Topbar />
        <div className={styles.mainContentContainer}>
          <main className={styles.mainContent}>
            {children}
            <Footer />
          </main>
        </div>
        <BottomBar />
      </body>
    </html>
  );
}

And dark and light theme code is like this


/** theme.css.ts */

import {
  createGlobalTheme,
  createThemeContract,
  createTheme,
} from "@vanilla-extract/css";

import { white, grey } from "../colors.css";

const root = createGlobalTheme("#root", {});

const themeColor = createThemeContract({
  fontColor: {
    textColor: null,
    accentColor: null,
    subColor: null,
    accentSubColor: null,
    middleAccentColor: null,
  },
  buttonColor: {
    notActiveColor: null,
    activeColor: null,
  },
  backgroundColor: {
    bodyColor: null,
    accentColor: null,
    navbarColor: null,
    textBoxColor: null,
    glassGradientColorTop: null,
    glassGradientColorBottom: null,
  },
  boxColor: {
    notHoverColor: null,
    hoverColor: null,
  },
  borderColor: {
    notHoverColor: null,
    hoverColor: null,
  },
});

export const ligthTheme = createTheme(themeColor, {
  fontColor: {
    textColor: grey[300],
    subColor: white[500],
    accentSubColor: white[500],
    middleAccentColor: grey[200],
    accentColor: "black",
  },
  buttonColor: {
    notActiveColor: white[500],
    activeColor: "black",
  },
  backgroundColor: {
    bodyColor: white[100],
    accentColor: white[200],
    navbarColor: "rgba(" + white[100] + ", 0.8)",
    glassGradientColorTop: `linear-gradient(to top, rgba(245,245,245,0) 0%, rgba(245,245,245,1) 100%)`,
    glassGradientColorBottom: `linear-gradient(to top, rgba(245,245,245,1) 0%, rgba(245,245,245,0) 100%)`,
    textBoxColor: white[300],
  },
  boxColor: {
    notHoverColor: white[200],
    hoverColor: white[300],
  },
  borderColor: {
    notHoverColor: white[400],
    hoverColor: grey[100],
  },
});

export const darkTheme = createTheme(themeColor, {
  fontColor: {
    textColor: white[100],
    subColor: grey[300],
    accentColor: "white",
    accentSubColor: grey[200],
    middleAccentColor: white[200],
  },
  buttonColor: {
    notActiveColor: grey[100],
    activeColor: white[100],
  },
  backgroundColor: {
    bodyColor: grey[500],
    accentColor: grey[400],
    navbarColor: "rgba(" + grey[500] + ", 0.8)",
    glassGradientColorTop: `linear-gradient(to top, rgba(16,16,16,0) 0%, rgba(16,16,16, 1) 100%)`,
    glassGradientColorBottom: `linear-gradient(to top, rgba(16,16,16,1) 0%, rgba(16,16,16,0) 100%)`,
    textBoxColor: grey[300],
  },
  boxColor: {
    notHoverColor: grey[400],
    hoverColor: grey[100],
  },
  borderColor: {
    notHoverColor: grey[200],
    hoverColor: white[300],
  },
});

import { keyframes } from "@vanilla-extract/css";

export const blink = keyframes({
  "0%": {
    opacity: 0,
  },
  "50%": {
    opacity: 0.7,
  },
  "100%": {
    opacity: 0,
  },
});

export const vars = { ...root, themeColor, blink };

And I save the theme on cookie


/** ToggleBtn.tsx */

import { moon } from "../icon/moon";
import { sun } from "../icon/sun";
import { cookies } from "next/headers";
import { toggleBtn } from "./ToggleBtn.css";
import SVGmorph from "./SVGmorph";

export default function ToggleBtn() {
  const theme = cookies().get("theme");
  const handleTheme = async () => {
    "use server";
    if (theme?.value === "dark" || !theme?.value) {
      cookies().set("theme", "light");
    } else {
      cookies().set("theme", "dark");
    }
  };
  return (
    <form action={handleTheme}>
      <button className={toggleBtn}>
        <svg
          width="28"
          height="28"
          viewBox="0 0 24 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <SVGmorph paths={[sun, moon, sun]} theme={theme?.value || "dark"} />
        </svg>
      </button>
    </form>
  );
}

But it take 1.5 sec at least to change theme. And it is worse on the post page

Is the way I use it wrong?

What is the problem with my code?

github: https://github.com/22JH/blog published url : https://www.joo-dev.com/

I tried deleting svgMorph, but it's still slow...

0

There are 0 best solutions below