组件和高阶组件区别

by Nitish Phanse

由Nitish Phanse

为什么要对高阶组件使用代码拆分 (Why you should use code splitting with higher order components)

Code splitting can offer some respite when it comes to loading massive client apps. We’re in an era where a user’s attention span is probably close to 10 seconds per page, and you’re definitely not going to get a conversion if 6 seconds are spent fetching and parsing your JavaScript.

在加载大量客户端应用程序时, 代码拆分可以提供一些喘息的机会。 我们正处于一个时代,用户的注意力跨度可能接近每页10秒,并且如果花费6秒来获取和解析您JavaScript,您肯定不会获得转化。

Webpack 3 offers brilliant support for dynamic imports. This allows you to load only the useful chunks to the client. Higher order components coupled with dynamic imports can split your JavaScript bundle into multiple tiny chunks. Recently, the React team added a sleek page on code splitting in their documentation.

Webpack 3为动态导入提供了出色的支持。 这允许您仅将有用的块加载到客户端。 高阶组件和动态导入可以将您JavaScript包分成多个小块。 最近,React团队在其文档中添加了关于代码拆分的漂亮页面。

Higher order components are functions which accept a component as an argument and return another component.

高阶组件是接受一个组件作为参数并返回另一个组件的函数。

Yes. That was the simplest definition I could think off, nothing fancy. Code splitting of your bundle has to be handled slightly differently when done on server side apps as compared to pure client apps.

是。 那是我能想到的最简单的定义,没什么好想的。 与纯客户端应用程序相比,在服务器端应用程序上进行捆绑处理时,代码拆分的处理方式必须稍有不同。

I have divided this article into two parts. The first part explains code splitting in pure client apps. The second part explains code splitting on server rendered apps. Both methods use higher order components.

我将本文分为 部分。 第一部分说明了纯客户端应用程序中的代码拆分。 第二部分介绍了服务器渲染应用程序上的代码拆分。 两种方法都使用高阶分量。

纯客户端应用 (Pure Client Apps)

These are apps which have a stripped down index.html. They’re usually used for authenticated routes (which need not utilize SEO benefits). They are built completely on the client side.

这些是删除了index.html应用程序。 它们通常用于经过身份验证的路由(无需利用SEO好处)。 它们完全在客户端构建。

Typically, any App.js will look like the one below:

通常,任何App.js都将如下所示:

For tiny apps, the above structure does work. But if we have 20 routes on our webpage, then we’re creating a bit of a monster. So we dynamically import only those routes needed once the user navigates to that page.

对于小型应用程序,上述结构确实有效。 但是,如果我们的网页上有20条路线,那么我们正在制造一些怪物。 因此,一旦用户导航到该页面,我们将仅动态导入所需的那些路线。

This should split up your code based on the routes. asyncComponent is a function which loads a component chunk asynchronously. The LoadingComponent is a placeholder which we can display while the request is being completed.

这应该根据路由拆分您的代码。 asyncComponent是一个异步加载组件块的函数。 LoadingComponent是一个占位符,我们可以在请求完成时显示它。

Whenever you call your ReactDOM.render method, the appropriate chunk will get loaded. This way you load only the routes needed on the page that the user is viewing. When navigating to a route, the appropriate bundle will get called for.

每当您调用ReactDOM时render方法,将加载适当的块。 这样,您仅加载用户正在查看的页面上所需的路由。 导航至路线时,将要求使用适当的捆绑包。

服务器渲染的应用 (Server Rendered Apps)

This section is definitely more interesting than the former. Server rendered apps create a markup string of the page in view and serve it to the client. Then we call the hydrate method. It first makes a diff check to see whether our server DOM tree is the same as the one made on the client. If its not the same, React will throw a warning saying there was a mismatch in your tree shape.

这部分肯定比前一部分更有趣。 服务器渲染的应用程序会在视图中创建页面的标记字符串,并将其提供给客户端。 然后我们称水合物法。 它首先进行差异检查,以查看我们的服务器DOM树是否与客户端上的相同。 如果不一样,React会发出警告,说您的树形不匹配。

If we follow the above method for server rendered apps, we will definitely get the error mentioned. Why?? Take a step back for a minute, and see what’s happening.

如果我们对服务器渲染的应用程序遵循上述方法,则肯定会提到错误。 为什么?? 退后一分钟,看看发生了什么。

The first request to the page returns the app string. But when the hydrate method kicks in, it tries to fetch the bundle for the page requested. Due to the async nature of the fetch, it loads the LoaderComponent for a brief moment of time. When the component is fetched, it re-renders the page. This gives a jittery / jagged effect to our UI and spits out the dreaded mismatch in DOM warning.

该页面的第一个请求返回应用程序字符串。 但是当hydrate方法启动时,它将尝试获取请求页面的包。 由于获取的异步性质,它会在很短的时间内加载LoaderComponent 。 提取组件后,它将重新呈现页面。 这给我们的UI带来了抖动/锯齿状的效果,并吐出了DOM警告中可怕的不匹配。

So we need a better approach to solve this problem.

因此,我们需要一种更好的方法来解决此问题。

  1. Split our code on the server side too在服务器端也拆分我们的代码
  2. Preload our components on the server side将组件预加载到服务器端
  3. Call the hydrate method only after the current bundle in context has been fetched.仅在获取上下文中的当前捆绑包后才调用hydrate方法。

React loadable is a pretty cool higher order component. It does all the above mentioned and is pretty simple to implement.

React可加载是一个非常酷的高阶组件。 它完成了上述所有工作,并且实现起来非常简单。

In your server.js:

在您的server.js中:

I am keeping the code to a minimum for the sake of simplicity.

为了简单起见,我将代码保持在最低限度。

Now let’s pick the bundle on the server side. We will use ReactLoadable’s Capture method, which will create a map of bundles needed for a that chunk.

现在,让我们在服务器端选择捆绑包。 我们将使用ReactLoadable的Capture方法,该方法将创建该块所需的束的映射。

const modules = [];
function fetchModuleName(moduleName: string) {  return modules.push(moduleName);}
const markup = ReactDOMServer.renderToString(  <Loadable.Capture report={fetchModuleName}>    <StaticRouter location={request.url} context={context}>      <App />    </StaticRouter>  </Loadable.Capture>);

Once that is done, let’s use ReactLoadable’s Webpack plugin to create chunks of the code. It maintains a stats file which will later be used by the server file to map which bundles to serve to the client.

完成后,让我们使用ReactLoadable的Webpack插件创建代码块。 它维护一个统计文件,该文件稍后将由服务器文件用来映射要向客户端提供的捆绑软件。

const ReactLoadablePlugin = require(‘reactloadable/webpack’).ReactLoadablePlugin;
In webpack config
plugins : [  //Other plugins,
new ReactLoadablePlugin({    filename: ‘./dist/build/react-loadable.json’,  })]

So our routes are split. We need to call the hydrate method only after the bundles have been fetched from the server, so let’s tackle that. We will use ReactLoadables’s preloadReady method.

所以我们的路线是分裂的。 仅在从服务器获取捆绑包之后,才需要调用hydrate方法,因此让我们解决这个问题。 我们将使用ReactLoadables的preloadReady方法。

window.main = () => {  Loadable.preloadReady().then(() => {    hydrate(      <BrowserRouter>        <ScrollHandler>          <App />        </ScrollHandler>      </BrowserRouter>,    document.getElementById(‘root’)    );  });};

We’ve attached a main function to the window object which will then get called in our server marked up file.

我们已经将主要功能附加到window对象,然后将在服务器的标记文件中调用该函数。

There are just a few steps left. We now need to tell our server file which appropriate bundle to fetch. After that is done, call the main function so that the client side app can take over.

仅剩几步了。 现在,我们需要告诉我们的服务器文件要提取哪个适当的捆绑软件。 完成之后,调用main函数,以便客户端应用程序可以接管。

So our final markup file will be like this:

因此,我们最终的标记文件将如下所示:

A few things one can optimize on:

可以优化的一些事项:

  1. Precache bundles for most frequently visited routes. For example, from the home page if the user is likely to navigate to the login or products page, you can use Loadable.preload() in the componentDidMount of the Home Page. A service worker can be handy here.

    最常访问的路线的预缓存捆绑包。 例如,如果用户可能从主页导航到登录页面或产品页面,则可以在主页的componentDidMount中使用Loadable.preload() 。 服务人员在这里很方便。

  2. If you don’t want to block the main thread, use a web worker. Use the window.postMessage API and fetch bundles in the background.

    如果您不想阻塞主线程,请使用Web Worker。 使用window.postMessage API 并在后台获取捆绑包。

  3. React Loadable can be used to chunk bundles in any apt way you please.您可以通过任何合适的方式使用React Loadable来打包捆绑包。
  4. To decide which chunks to pre-cache, read some data off your analytics library, mix panel / GA to see where users navigate from the home page.要确定要预缓存的块,请从您的分析库中读取一些数据,混合使用面板/ GA以查看用户从主页导航到的位置。

Feedback is always welcome!

随时欢迎反馈!

翻译自: https://www.freecodecamp.org/news/code-splitting-with-higher-order-components-4ac8f094b059/

组件和高阶组件区别

组件和高阶组件区别_为什么要对高阶组件使用代码拆分相关推荐

  1. 高端物理学名词_什么是物理高端备课?

    邢红军 首都师范大学 物理系 教授 博士 物理教学论博士生导师 各位老师,大家晚上好!首先感谢杨德发老师的盛情邀请,让我有机会与老师们就物理高端备课进行交流,我欣然接受.同时感谢朱行建老师在他的群转播 ...

  2. python高阶函数心得_没有学不会的python--高阶函数

    没有学不会的python 函数式编程 到现在为止,我们的没有学不会python系列文章已经讲了很多知识点了,如果是第一次刷到这篇文章的朋友可以去我主页看一下以前写的文章.前面讲了很多知识点,每个知识点 ...

  3. 处理器博通还是高通比较好_苹果手机基带高通还是Intel好?iPhone查看基带生产商厂家方法...

    众所周知,从 iPhone7 - iPhone X系列的苹果手机均采用高通和英特尔基带混用,而从大多数果粉用户反馈来看,高通基带产品,信号表现似乎更好一些.究竟,苹果手机基带高通还是Intel好?如何 ...

  4. react-5 高阶函数 (HOC)(防抖节流) --- 高阶组件(HOF)(拖拽)

    高阶函数hoc:高阶函数是对其他函数进行操作的函数 高阶组件hof:高阶组件即接受一个或多个组件作为参数并且返回一个组件,本质也就是一个函数,并不是一个组件 .把通用的逻辑放在高阶组件中,对组件实现一 ...

  5. react中高阶函数与高阶组件的运用—(上)(案例详细解释高阶函数)

    前言 学习react的同学多多少少对高阶组件有所耳闻,想要学好高阶组件就必须先学好高阶函数的运行,本篇文章就先从高阶函数着手,带大家学习高阶函数和高阶组件的运用 高阶函数 高阶函数(High Orde ...

  6. uniapp 子组件 props拿不到数据_总结下React组件间的通讯

    这是个老话题了. 随着组件化开发成为主流,每个组件都有完善的生命周期,大家可以在生命周期内做一些事情,每个组件有自己的状态管理机制.同时,每个组件都是独立的.这能提高大家的开发效率,规范化开发. 今天 ...

  7. layui选项卡嵌套选项卡_在ProtoPie中使用嵌套组件构建选项卡栏

    layui选项卡嵌套选项卡 One of the powerful features of ProtoPie is the ability to build fully portable and in ...

  8. react 组件构建_为React构建星级评定组件

    react 组件构建 Who doesn't love beer? When you drink a great beer you want to tell someone. You definite ...

  9. 组件、子系统、包区别联系

    区别联系 组件是系统中遵循一组接口且提供实现的一个物理部件,通常指开发和运行时类的物理实现.组件一般表示实际存在的.物理的物件,组件可以是:程序源代码.子系统.动态链接库等,组件一般都包含很多类并实现 ...

最新文章

  1. 稳~阿里程序员常用的 15 款开发者工具
  2. 静态内部类和非静态内部类区别汇总
  3. PHP Fatal error: Class #39;DOMDocument#39; not found
  4. 统一沟通-技巧-12-Lync-CX600-3000-5000-配置-internet
  5. orm的理解_ORM仇恨者无法理解
  6. 了解和扩展Java ClassLoader
  7. 前端学习(360):svn操作前期连接工作
  8. 局域网中设备的管理之StackCluster
  9. 大数据每周分享第 008 期
  10. JavaScript进阶学习(二)—— 基于原型链继承的js工具库的实现方法
  11. mount挂载光盘media_Linux挂载光盘命令
  12. 使用python搭配pandoc实现html批量转word
  13. UML类图关系全面剖析[转]
  14. Directx教程(28) 简单的光照模型(7)
  15. windows自带的文件校验工具MD5,SHA1,SHA256
  16. android usb dwc3 gaget rndis 网卡异常断开问题。
  17. Windows 7 64 位操作系统安装 Ubuntu 17.10
  18. 域控服务器可以加几个辅域,如何搭建AD域控的辅域控(20200927213255).docx
  19. mathtype导致无法粘贴解决方法
  20. DateFormat 线程安全

热门文章

  1. 数组的操作与方法的操作 0303 2101
  2. c#winform演练 ktv项目 MediaPlayer控件播放音乐
  3. 草稿selenium显示等待
  4. 网络编程-关于get请求与post请求
  5. Python之HTML的解析(网页抓取一)
  6. 在Windows Server 2008上安装和配置Web和FTP服务
  7. 今天成功的将一个对1,000,000条记录的查询从30'提升到1'以下,庆祝一下
  8. 在 Nginx 上支持 HTTP/3
  9. HTTP 请求之性能优化:DNS预解析 dns-prefetch
  10. Java面试技巧—如何自我介绍