通过服务器端渲染反应海量内容和重复

React massive content and duplication with server side rendering

ReactJS S̶i̶n̶g̶l̶e̶ Shelled 页面应用

  1. 没有服务器端呈现 (SSR),重现问题的要求:
    ReactJS + WebPack + React-Router
    我将 Yeoman 生成器用于 aspnet core React 项目 没有 SSR,在 Startup.cs 中禁用了 HotReloading(或者可以 运行 生产模式)

    <Route component={ Layout }>
       <Route path='/' components={{ body: Home }} />
       <Route path='/counter' components={{ body: Counter }} />      
    </Route>;
    /* project includes Home.tsx, Counter.tsx and other components/subpages */
    

    Home.tsx的一部分:

    class Home extends React.Component<any, void> {
      public render() {
        return <div>
            <h1>Hello, world!</h1>
            <p>Welcome to your new single-page application, built with:</p>
    

    结果

    • main-client.js 包括主页和计数器组件(子页面)的所有 content/layout,以及其他子页面的所有内容和布局。
      这意味着我们正在加载 应用程序的整个布局,即使我们只请求了一个子类别,例如计数器
      停止网站后,您仍然可以在子页面之间切换,因为它们是通过 webpacked main-client.js 加载的。

      问题 1:是否可以仅加载您为当前页面请求的内容(应用程序 shell + 当前子类别)?
      (然后对于另一部分只有一个新的子类别由于缓存应用 shell)
      (也许有另一个路由器和特殊的(网络)包设置)

  2. 服务器端呈现 (SSR),重现问题的要求:
    ReactJS + WebPack + React-Router + SSR
    我将 Yeoman 生成器用于带有 Redux 和 SSRaspnet core React 项目,还在 Startup.cs 中禁用了 HotReloading(或者可以 运行 生产模式)

    结果

    • 现在更糟,因为我们要加载整个网站布局两次:首先是在完全呈现的 html 中,然后是在 main-client.js

    这表明对于 React 默认情况下,静态内容(控件内的静态文本)和动态内容(一些条件 html 输出)之间没有区别,因此它将所有信息放在巨大的 JS 文件中。

    问题2: 是否可以给React关于静态部分的提示,只需要服务端渲染一次,从客户端剔除java-脚本只留下动态computations/components?

============================================= ===========

看来没有这么多人知道,因为这些问题在很多示例中,教程中没有提到。

现在一种常见的方法是首先加载一个空的应用程序 shell 布局,然后通过客户端 java 脚本加载 JSON 内容数据。然而,它并没有解决这些问题,例如对于第一个问题,我们仍然为 hole 应用程序加载一个 shell,对于丰富的布局,它可能是一个非常大的 JS 文件,其中有很多空 DOM 元素:

<h1 id="react-hint-for-element-9997">/* here will be header*/</h1>
    <h2 id="react-hint-for-element-9998">/* here will be subheader*/</h2>
        /*and so on and on */

问题 1

您可以使用 Webpack code splitting 将您的应用分成几个包。

它提供 require.ensure 以在需要时延迟加载包(例如,当用户点击新路线时):

示例(来自 Webpack 文档):

//static imports
import _ from 'lodash'

// dynamic imports
require.ensure([], function(require) {
  let contacts = require('./contacts')
})

问题二

React(还)不区分静态内容和动态内容。 Inferno 是一个类似 React 的库,它通过这种区分来提高渲染性能。它可能比 React 更适合您的用例。

示例(来自 Inferno 文档):

import Inferno from 'inferno';
import InfernoDOM from 'inferno-dom';

const message = "Hello world";

InfernoDOM.render(
  <MyComponent message={ message } />,
  document.getElementById("app")
)