7

在将服务器端渲染React应用程序迁移到可加载组件以进行代码拆分和延迟加载后,初始包大小及其下载时间按预期减少。然而,在将经典的React渲染方法替换为可加载组件后,在其余应用程序代码不变的情况下,我在PageSpeed / LightHouse中的 Cumulative Layout Shift 得分从 0.05 上升到 1 或更多。我的意思是即使没有动态加载任何组件,否则情况会更糟。

我做错了什么?

可加载组件之前的 SSR 代码(良好的 CLS 分数):

服务器端 :

...
import React from 'react'
import { renderToString } from 'react-dom/server'
import { StaticRouter } from 'react-router-dom'
...
const ssrApp = renderToString(
  <StaticRouter location={`/${this.requestedPage.uri}`} context={{}}>
    <App />
  </StaticRouter>
)

客户端 :

...
import React from 'react'
import { BrowserRouter } from 'react-router-dom'
import { hydrate } from 'react-dom'
...
hydrate(<BrowserRouter><App /></BrowserRouter>, appRoot)
...

可加载组件后的 SSR (糟糕的 CLS 分数):

服务器端 :

...
import React from 'react'
import { renderToString } from 'react-dom/server'
import { StaticRouter } from 'react-router-dom'
import { ChunkExtractor } from '@loadable/server'
import path from 'path'
...
const statsFile = path.resolve(`${process.env.APP_ROOT}${path.sep}public${path.sep}js${path.sep}loadable-stats.json`)
const extractor = new ChunkExtractor({ statsFile, publicPath: '/js' })
const jsx = extractor.collectChunks(
  <StaticRouter location={`/${this.requestedPage.uri}`} context={{}}>
    <App user={currentUser} requestedPage={this.requestedPage} />
  </StaticRouter>
)
const scriptTags = extractor.getScriptTags()
const ssrApp = renderToString(jsx)
...

客户端 :

...
import React from 'react'
import { BrowserRouter } from 'react-router-dom'
import { hydrate } from 'react-dom'
import { loadableReady } from '@loadable/component'
...
loadableReady(() => { hydrate(<BrowserRouter><App /></BrowserRouter>, appRoot) })
...

备注:

  • 根据PageSpeedLightHouse的说法,它是代码的整个 HTML<main>部分(填充了用 路由的组件React Router),就好像 SSR 页面被完全重新渲染,尽管使用hydrate.
  • 如果没有Loadable Components,完全相同的代码不会导致布局转移。
4

0 回答 0