0

ReactJS S̶i̶n̶g̶l̶e̶ 带壳页面应用程序

  1. 没有服务器端渲染 (SSR),重现问题的要求:我在没有 SSR的情况下为aspnet core React项目
    ReactJS + WebPack + React-Router
    使用了 Yeoman 生成器,在 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包括 Home 和 Counter 组件(子页面)的所有内容/布局,以及其他子页面的所有内容和布局。
      这意味着我们正在加载应用程序的整个布局,即使我们只请求了一个子类别,例如 Counter
      停止网站后,您仍然可以在子页面之间切换,因为它们是通过 webpacked 加载的main-client.js

      在此处输入图像描述

      问题 1:是否可以仅加载您为当前页面请求的内容(应用程序外壳 + 当前子类别)?
      (然后对于另一部分,由于缓存的应用程序外壳,只有一个新的子类别)
      (可能使用另一个路由器和特殊的(web-)pack 设置)

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

    结果

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

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

    问题 2:是否可以为 React 提供有关静态部分的提示,因此只需要由服务器渲染一次并从客户端 java-script 中删除它,只留下动态计算/组件?

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

似乎没有多少人意识到这一点,因为这些问题存在于许多示例中,并且在教程中没有提及。

现在一种常见的方法是首先加载一个空的应用程序外壳布局,然后通过客户端 javascript 加载 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 */
4

1 回答 1

1

问题 1

您可以使用Webpack 代码拆分将您的应用程序分成几个捆绑包。

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

示例(来自 Webpack 文档):

//static imports
import _ from 'lodash'

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

问题2

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")
)
于 2016-10-17T22:02:42.877 回答