跳到主要内容
+

暗黑模式优化

Joy UI 使用 CSS 变量以确保服务端渲染的应用在首次渲染时可以加载为暗黑模式。

Joy UI 经过优化,确保选择暗黑模式作为首选配色方案的最终用户在应用首次渲染时永远不会看到浅色模式的闪烁。这对于服务端渲染 (SSR) 应用和使用静态站点生成器 (SSG) 构建的站点来说是一个常见问题。

为了解决这个问题,Joy UI 使用 CSS 变量在构建时渲染所有配色方案,以便在首次加载时为用户提供其首选模式。

问题:首次加载时闪烁

在服务端渲染的上下文中,应用在到达客户端之前很久就已构建完成——这意味着它在首次加载时无法考虑用户的首选配色方案。

因此,如果您加载这样的应用,切换到暗黑模式,然后刷新,您会看到在客户端 hydration 启动并将其切换回暗黑模式之前,默认浅色模式会闪烁一下。实际上,只要您的浏览器记住您偏好暗黑模式,这种浅色模式的“闪烁”在您将来每次加载应用时都会发生。

这可能会在弱光环境下引起眼睛疲劳,更不用说对用户体验的令人沮丧的打断——特别是对于那些在模式切换期间与应用交互的用户。

下面的 GIF 演示了这个问题

An example video that shows a page that initially loads correctly in dark mode but quickly flickers to light mode.

解决方案:CSS 变量

解决这个问题需要我们对样式和主题采取一种新颖的方法。(请参阅此 关于 CSS 变量支持的 RFC 以了解有关此功能实现的更多信息。)

得益于 Joy UI 内置的对 CSS 变量的支持,您的应用可以在构建时渲染其所有配色方案,以便在 DOM 在浏览器中渲染*之前*注入用户的偏好设置。

Joy UI 提供了 InitColorSchemeScript 组件,以便在使用 React 框架(如 Next.js 或 Remix)时实现无闪烁的暗黑模式。此函数必须放置在主脚本之前,以便它可以在组件渲染之前应用正确的样式表。

下面的代码片段展示了这在 Next.js Pages Router 中是如何工作的

import Document, { Html, Head, Main, NextScript } from 'next/document';
import InitColorSchemeScript from '@mui/joy/InitColorSchemeScript';

export default class MyDocument extends Document {
  render() {
    return (
      <Html data-color-scheme="light">
        <Head>...</Head>
        <body>
          <InitColorSchemeScript />
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

请参阅 应用暗黑模式 页面,了解有关与其他框架一起使用的更多详细信息。