简体   繁体   English

React:可加载组件增加 Cumulative Layout Shift (CLS)

[英]React: Loadable Components increase Cumulative Layout Shift (CLS)

After migrating a server side rendering React application to Loadable Components for code splitting and lazy loading, the initial bundle size, thus its download time, reduced as expected.在将服务器端渲染React应用程序迁移到可加载组件以进行代码拆分和延迟加载后,初始包大小及其下载时间按预期减少。 However after replacing the classical React rendering method by the Loadable Components one, with the rest of the application code unchanged, my Cumulative Layout Shift score in PageSpeed / LightHouse raised to the sky, from 0.05 to 1 or more.然而,在将经典的React渲染方法替换为Loadable Components渲染方法后,在应用程序代码 rest 不变的情况下,我在PageSpeed / LightHouse中的 Cumulative Layout Shift 分数从 0.05 上升到 1 或更高。 I mean even without dynamically loading any component, things are worst otherwise.我的意思是即使没有动态加载任何组件,否则情况会更糟。

What I am doing wrong?我做错了什么?

SSR code before Loadable Components (good CLS score): Loadable Components之前的 SSR 代码(良好的 CLS 分数):

Server-side:服务器端:

...
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>
)

Client-side:客户端:

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

SSR after Loadable Components (bad CLS score):可加载组件后的 SSR(CLS 分数不佳):

Server-side:服务器端:

...
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)
...

Client-side:客户端:

...
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) })
...

Notes:笔记:

  • According to PageSpeed and LightHouse , it's the whole HTML <main> section of the code (filled with components routed with React Router ) that is shifted, as if the SSR page was fully rerendered dispite using hydrate .根据PageSpeedLightHouse的说法,移动的是代码的整个 HTML <main>部分(充满了使用React Router路由的组件),就好像 SSR 页面完全重新渲染一样,尽管使用了hydrate
  • The exact same code doesn't lead to layout shift without Loadable Components .如果没有Loadable Components ,完全相同的代码不会导致布局偏移。

If you know the height and width of the lazy div, set the minimum height and width for container of lazy div.如果知道lazy div的高度和宽度,设置lazy div容器的最小高度和宽度。 So user will not see any shift in their layouts.所以用户不会看到他们的布局有任何变化。 In the centre of the div you can place loading or spinner icon.在 div 的中心,您可以放置加载或微调图标。

This way user will not see and shift in their layouts and indeed results in better user experience.这样用户就不会看到和改变他们的布局,确实会带来更好的用户体验。

Note - If size of the lazy div is varies, use average values so the shift will be less and reduce CLS impact score.注意 - 如果惰性 div 的大小不同,请使用平均值,这样偏移会更小并降低 CLS 影响分数。

.container{
  min-height: 500px;
  min-width: 800px;
}

<div class="container">
  <LazyDiv />
</div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM