Next.js 迷宫 — SSR 的一些坑

阅读时长 6 分钟读完

Next.js 是一个非常流行的 React 框架,它提供了服务端渲染(Server-Side Rendering,SSR)和静态网站生成(Static Site Generation,SSG)等功能,使得我们可以很方便地搭建高性能的 React 应用。但是,在 SSR 中很容易遇到一些奇怪的坑,本文将对这些坑进行详细介绍和解决方案。

问题 1:浏览器端渲染会导致闪烁

在 Next.js 中,我们可以使用 getServerSidePropsgetInitialProps 进行服务端渲染,但是它也支持浏览器端渲染。但是,当我们在浏览器端渲染页面时,可能会出现页面“闪烁”的问题。这是因为浏览器端渲染会先显示出没有样式的 HTML,这时用户会看到一个没有样式的页面,然后再稍稍等待,直到样式被加载并应用到页面上。

解决方案:

可以通过在 useEffect 中设置 document.body.style.display 属性来避免这个问题,在浏览器端渲染时,先将 bodydisplay 设置为 none,当样式加载完成后再设置为 block,这样用户就看不到页面“闪烁”了。

-- -------------------- ---- -------
------ - --------- - ---- -------

-------- ----------- -- -
  ------------ -- -
    --------------------------- - -------
  -- ---

  ------ --------- -----------
-

问题 2:页面组件没有 windowdocument 对象

在 SSR 中,组件是在服务器上渲染的,没有浏览器环境,因此在组件中不能使用 windowdocument 对象,否则会抛出异常。

解决方案:

可以将需要使用浏览器 API 的代码放在 useEffect 中,确保只有在浏览器端才会运行该代码。

-- -------------------- ---- -------
------ - --------- - ---- -------

-------- ----------- -- -
  ------------ -- -
    ----- -- - -------------------------------------
    -- ---------------
    ----------------------------
  -- ---

  ------ ---- --------------------- ------------
-

问题 3:window 对象大小和事件绑定不正确

在 SSR 中,如果使用 window.innerWidthwindow.innerHeight 获取窗口大小,会发现它们的值都是 0。而且,在使用 addEventListner 绑定事件时,事件不会被触发。

解决方案:

可以使用 useLayoutEffect 来获取窗口大小和绑定事件,useLayoutEffect 会在组件的渲染阶段结束后、浏览器布局和绘制之前同步执行,保证在浏览器端只执行一次。

-- -------------------- ---- -------
------ - ---------------- -------- - ---- -------

-------- ----------- -- -
  ----- ------ -------- - ----------
    ------ --
    ------- -
  --

  ------------------ -- -
    ---------
      ------ ------------------
      ------- ------------------
    --
    
    ----- ------------ - -- -- -
      ---------
        ------ ------------------
        ------- ------------------
      --
    -
    
    --------------------------------- -------------

    ------ -- -- -
      ------------------------------------ -------------
    -
  -- ---

  ------ -
    -----
      --------- ------ ----------------
      --------- ------- -----------------
    ------
  -
-

问题 4:styled-components 样式失效

在 SSR 中,使用 styled-components 可能会遇到样式失效的问题。这是由于 styled-components 会在浏览器端动态生成样式,在 SSR 中没有机会生成样式。因此,在浏览器端渲染时,我们会看到一个没有样式的页面,然后稍稍等待,直到样式被加载并应用到页面上。

解决方案:

可以通过在 getInitialProps 中使用 StyleSheetServer 来处理样式,在服务端预先生成 CSS,并在浏览器端直接使用预先生成的 CSS 文件。

-- -------------------- ---- -------
------ --------- - ----- ----- ----- ---------- - ---- ---------------
------ - ---------------- - ---- -------------------

----- ---------- ------- -------- -
  ------ ----- --------------- ----- -
    ----- ----- - --- ------------------
    ----- ------------------ - --------------

    --- -
      -------------- - -- --
        --------------------
          ----------- --- -- ----- -- ------------------------ ---------- ---
        --

      ----- ------------ - ----- -----------------------------

      ------ -
        ----------------
        ------- -
          --
            ---------------------
            -------------------------
          ---
        -
      -
    - ------- -
      ------------
    -
  -

  -------- -
    ------ -
      ------
        -------------
        ------
          ----- --
          ----------- --
        -------
      -------
    -
  -
-

------ ------- ----------

使用以上方法,即可在 SSR 中使用 styled-components 并避免样式失效问题。

总结

Next.js 的 SSR 功能是它的一大优点,可以让我们更好地优化 React 应用的性能和用户体验。但是,在 SSR 中会遇到一些奇怪的问题和坑,本文介绍了其中的一些,并提供了解决方案。希望本文可以帮助你更好地理解 Next.js 和 SSR,以及避免遇到这些问题。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f997bef6b2d6eab31118b6

纠错
反馈