sidecar_Sidecar用于代码拆分

2023-11-21 12:59
文章标签 代码 用于 拆分 sidecar

本文主要是介绍sidecar_Sidecar用于代码拆分,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

sidecar

Code splitting. Code splitting is everywhere. However, why? Just because there is too much of javascript nowadays, and not all are in use at the same point in time.

代码拆分。 代码拆分无处不在。 但是,为什么呢? 仅仅是因为现在的javascript太多了 ,并且并非所有JavaScript都在同一时间使用。

JS is a very heavy thing. Not for your iPhone Xs or brand new i9 laptop, but for millions(probably billions) of slower devices owners. Or, at least, for your watches.

JS是一件很沉重的事情。 不适用于您的iPhone Xs或全新的i9笔记本电脑,但适用于数百万(可能是数十亿) 速度较慢的设备所有者。 或者,至少对于您的手表。

So — JS is bad, but what would happen if we just disable it — the problem would be gone… for some sites, and be gone "with sites" for the React-based ones. But anyway — there are sites, which could work without JS… and there is something we should learn from them...

因此,JS很不好,但是如果我们禁用它 ,将会发生什么事情,问题将会消失……对于某些站点,对于基于React的站点来说,“与站点一起”就会消失。 但是无论如何-有些站点可以在没有JS的情况下运行...我们应该向他们学习一些东西...

代码拆分 (Code splitting)

Today we have two ways to go, two ways to make it better, or to not make it worse:

今天,我们有两种方法,可以使它变得更好或不使它变得更糟:

1.写更少的代码 (1. Write less code)

That's the best thing you can do. While React Hooks are letting you ship a bit less code, and solutions like Svelte let you generate just less code than usual, that's not so easy to do.

那是你最好的事情。 尽管React Hooks可以让您减少代码Svelte ,而Svelte解决方案却可以使您生成的代码比平时少,但这并不容易。

It's not only about the code, but also about functionality — to keep code "compact" you have to keep it "compact". There is no way to keep application bundle small if it's doing so many things (and got shipped in 20 languages).

这不仅与代码有关,而且与功能有关—要使代码“紧凑”,就必须使其“紧凑”。 如果应用程序包做很多事情(并以20种语言提供),则无法保持应用程序包很小。

There are ways to write short and sound code, and there are ways to write the opposite implementation — the bloody enterprise. And, you know, both are legit.

有写简短代码的方法,有写相反的实现的方法- 血腥的企业 。 而且,您都知道,两者都是合法的。

But the main issue — the code itself. A simple react application could easily bypass "recommended" 250kb. And you might spend a month optimizing it and make it smaller. "Small" optimizations are well documented and quite useful — just get bundle-analyzer with size-limit and get back in shape. There are many libraries, which fight for every byte, trying to keep you in your limits — preact and storeon, to name a few.

但主要问题是代码本身。 一个简单的react应用程序可以轻松绕过“推荐”的250kb。 您可能需要花费一个月的时间对其进行优化,然后使其变得更小。 “小”优化已得到充分证明,并且非常有用-只需使用具有size-limit bundle-analyzer并恢复其形状即可。 有许多图书馆,这对于每一个字节的战斗,试图让你在自己的极限- preact和storeon ,仅举几例。

But our application is a bit beyond 200kb. It's closer to 100Mb. Removing kilobytes makes no sense. Even removing megabytes makes no sense.

但是我们的应用程序超出了200kb。 接近100Mb 。 删除千字节毫无意义。 即使删除兆字节也没有任何意义。

After some moment it's impossible to keep your application small. It will grow bigger in time.
片刻之后,就不可能将应用程序缩小。 随着时间的推移,它将变得更大。

2.减少代码 (2. Ship less code)

Alternatively, code split. In other words — surrender. Take your 100mb bundle, and make twenty 5mb bundles from it. Honestly — that's the only possible way to handle your application if it got big — create a pack of smaller apps from it.

或者, code split 。 换句话说- 投降 。 拿起100mb的捆绑包,然后用它制作20个5mb的捆绑包。 老实说-这是处理您的应用程序的唯一可能的方法-如果应用程序很大,请从中创建一堆较小的应用程序。

But there is one thing you should know right now: whatever option you choose, it's an implementation detail, while we are looking for something more reliable.

但是,您现在应该知道一件事:无论选择什么选项,它都是实现细节,而我们正在寻找更可靠的东西。

关于代码拆分的真相 (The Truth about Code Splitting)

The truth about code splitting is that it's nature is TIME SEPARATION. You are not just splitting your code, you are splitting it in a way where you will use as little as possible in a single point of time.

关于代码拆分的真相是,它的本质是TIME SEPARATION 。 您不仅在拆分代码,还以一种在单个时间点使用尽可能少的方式拆分代码。

Just don't ship the code you don't need right now. Get rid of it.

只是不要立即发布您不需要的代码。 摆脱它。

Easy to say, hard to do. I have a few heavy, but not adequately split applications, where any page loads like 50% of everything. Sometimes code splitting becomes code separation, I mean — you may move the code to the different chunks, but still, use it all. Recal that "Just don't ship the code you don't need right now",– I needed 50% of the code, and that was the real problem.

说起来容易,很难做。 我有一些繁重但没有充分拆分的应用程序,其中任何页面加载的内容占所有内容的50%。 我的意思是,有时code splitting会变成code separation ,您可以将代码移动到不同的块中,但仍然可以全部使用。 Recal说: “现在就不要发布不需要的代码” ,我需要 50%的代码,这才是真正的问题。

import here and there is not enough. Till it is not import是不够的。 直到不是 time separation, but only 时间分隔,而只有 space separation — it does not matter at all. 空间分隔–完全没有关系。

There are 3 common ways to code split:

有3种常见的代码拆分方式:

  1. Just dynamic import. Barely used alone these days. It's more about issues with tracking a state.

    只是动态import 。 这些天很少使用。 更多有关跟踪状态的问题。

  2. Lazy Component, when you might postpone rendering and loading of a React Component. Probably 90% of "react code splitting" these days.

    Lazy组件,当您可以推迟渲染和加载React组件时。 这些天,大约90%的“React代码拆分”。

  3. Lazy Library, which is actually .1, but you will be given a library code via React render props. Implemented in react-imported-component and loadable-components. Quite useful, but not well known.

    惰性 Library ,实际上是.1 ,但是您将通过React渲染道具获得库代码。 在react-imported-component和loadable-components中实现 。 很有用,但并不广为人知。

组件级代码拆分 (Component Level Code Splitting)

This one is the most popular. As a per-route code splitting, or per-component code splitting. It's not so easy to do it and maintain good perceptual results as a result. It's death from Flash of Loading Content.

这是最受欢迎的。 作为按路由的代码拆分或按组件的代码拆分。 做到这一点并保持良好的感知结果并不是那么容易。 死于Flash of Loading Content

The good techniques are:

好的技术是:

  • load js chunk and data for a route in parallel.

    并行加载js chunk和路由data

  • use a skeleton to display something similar to the page before the page load (like Facebook).

    使用skeleton在页面加载之前显示类似于页面的内容(例如Facebook)。

  • prefetch chunks, you may even use guess-js for a better prediction.

    prefetch块,甚至可以使用guess-js进行更好的预测。

  • use some delays, loading indicators, animations and Suspense(in the future) to soften transitions.

    使用一些延迟,加载指示符, animationsSuspense (以供将来使用)来缓和过渡。

And, you know, that's all about perceptual performance.

而且,这一切都与感知性能有关。

Improved UX with Ghost Elements 具有Ghost Elements的改进UX的图像

听起来不好 (That doesn't sound good)

You know, I could call myself an expert in code splitting — but I have my own failures.

您知道,我可以称自己为代码拆分专家,但是我有自己的失败经历。

Sometimes I could fail to reduce the bundle size. Sometimes I could fail to improve resulting performance, as long as the _more_ code splitting you are introducing - the more you spatially split your page - the more time you need to _reassemble_ your page back*. It's called a loading waves.

有时我可能无法减小捆绑包的大小。 有时,只要the _more_ code splitting you are introducing - the more you spatially split your page - the more time you need to _reassemble_ your page back ,我就可能无法提高结果性能the _more_ code splitting you are introducing - the more you spatially split your page - the more time you need to _reassemble_ your page back *。 这就是所谓的波涛

  • without SSR or pre-rendering. Proper SSR is a game changer at this moment.

    无需SSR或预渲染。 目前,正确的SSR可以改变游戏规则。

Last week I've got two failures:

上周我遇到了两个失败:

  • I've lost in one library comparison, as long as my library was better, but MUCH bigger than another one. I have failed to "1. Write less code".

    我已经失去了一个库进行比较 ,只要我的图书馆是更好,但要比另一个大。 我未能执行“ 1.编写更少的代码”

  • optimize a small site, made in React by my wife. It was using route-based component splitting, but the header and footer were kept in the main bundle to make transitions more "acceptable". Just a few things, tightly coupled with each other skyrocketed bundle side up to 320kb(before gzip). There was nothing important, and nothing I could really remove. A death by a thousand cuts. I have failed to Ship less code.

    优化一个由我妻子在React中制作的小型网站。 它使用的是基于路由的组件拆分,但headerfooter保留在主包中,以使过渡更加“可以接受”。 仅有几件事,彼此紧紧耦合在一起,使捆绑包的一面飙升到320kb(在gzip之前)。 没有什么重要的事情,也没有什么我能真正去除的。 死亡减少一千 。 我未能交付更少的代码

React-Dom was 20%, core-js was 10%, react-router, jsLingui, react-powerplug… 20% of own code… We are already done.
React-Dom是20%,core-js是10%,react-router,jsLingui,react-powerplug ...自己代码的20%...我们已经完成了。

解决方案 (The solution)

I've started to think about how to solve my problem, and why common solutions are not working properly for my use case.

我已经开始考虑如何解决我的问题,以及为什么常见的解决方案在我的用例中无法正常工作。

What did I do? I've listed all crucial location, without which application would not work at all, and tried to understand why I have the rest.
我做了什么 我列出了所有关键位置,没有该位置根本无法使用任何应用程序,并试图理解为什么我拥有其余的位置。

It was a surprise. But my problem was in CSS. In vanilla CSS transition.

这真是一个惊喜。 但是我的问题是在CSS中。 在原始CSS过渡中。

Here is the code

这是代码

  • a control variable — componentControl, eventually would be set to something DisplayData should display.

    控制变量componentControl最终将设置为DisplayData应该显示的内容。

  • once value is set — DisplayData become visible, changing className, thus triggering fancy transition. Simultaneusly FocusLock become active making DisplayData a modal.

    设置值后DisplayData变为可见,更改className ,从而触发奇特的转换。 同时FocusLock激活,使DisplayData成为模态

    <FocusLock
    enabled={componentControl.value} 
    // ^ it's "disabled". When it's disabled - it's dead.
    >
    {componentControl.value && <PageTitle title={componentControl.value.title}/>}
    // ^ it's does not exists. Also dead
    <DisplayData
    data={componentControl.value}
    visible={componentControl.value !== null}
    // ^ would change a className basing on visible state
    />
    // ^ that is just not visible, but NOT dead
    </FocusLock>

I would like to code split this piece as a whole, but this is something I could not do, due to two reasons:

我想对这一部分进行整体编码,但是由于两个原因,我无法做到这一点:

  1. the information should be visible immediately, once required, without any delay. A business requirement.

    一旦需要,信息应该立即可见,没有任何延迟。 业务需求。
  2. the information "chrome" should exist before, to property handle transition.

    信息“ chrome”应该存在之前,才能进行属性句柄转换。

This problem could be partially solved using CSSTransitionGroup or recondition. But, you know, fixing one code adding another code sounds weird, even if actually enought. I mean adding more code could help in removing even more code. But… but...

使用CSSTransitionGroup或recondition可以部分解决此问题。 但是,您知道,固定一个代码加上另一个代码听起来很奇怪,即使实际上足够了 。 我的意思是添加更多代码可以帮助删除更多代码。 但是...但是...

There should be a better way!
应该有更好的方法!

TL;DR — there are two key points here:

TL; DR-这里有两个关键点:

  • DisplayData has to be mounted, and exists in the DOM prior.

    DisplayData必须被挂载 ,并且先于DOM存在。

  • FocusLock should also exist prior, not to cause DisplayData remount, but it's brains are not needed in the beginning.

    FocusLock也应该事先存在,以免引起DisplayData重新安装,但一开始就不需要动脑筋



So let's change our mental model

因此,让我们改变思维模式

蝙蝠侠和罗宾 (Batman and Robin)

Let assume that our code is Batman and Robin. Batman can handle most the bad guys, but when he can't, his sidekick Robin comes to the rescue..

假设我们的代码是蝙蝠侠和罗宾。 蝙蝠侠可以应付大多数坏人,但是当他无法应付时,他的搭档罗宾(Robin)便得以营救。

Once again Batman would engage the battle, Robin will arrive later.
蝙蝠侠再次参加战斗,罗宾将稍后到达。

This is Batman:

这是蝙蝠侠:

+<FocusLock
- enabled={componentControl.value} 
+>
-  {componentControl.value && <PageTitle title={componentControl.value.title}/>}
+  <DisplayData
+    data={componentControl.value}
+    visible={componentControl.value !== null}
+  />
+</FocusLock>

This is his sidekick, Robin::

这是他的搭档罗宾:

-<FocusLock
+ enabled={componentControl.value} 
->
+  {componentControl.value && <PageTitle title={componentControl.value.title}/>}
-  <DisplayData
-    data={componentControl.value}
-    visible={componentControl.value !== null}
-  />
-</FocusLock>

Batman and Robin could form a TEAM, but they actually, are two different persons.

蝙蝠侠和罗宾可以组队 ,但实际上他们是两个不同的人。

And don't forget — we are still talking about code splitting. And, in terms of code splitting, where is the sidekick? Where is Robin?

别忘了-我们仍在谈论代码拆分 。 而且,就代码拆分而言,搭档在哪里? 罗宾在哪里?

sidecar chunk. 杂物车里等待。

边车 (Sidecar)

  • Batman here is all visual stuff your customer must see as soon as possible. Ideally instantly.

    Batman是您的客户必须尽快看到的所有视觉材料。 理想的瞬间。

  • Robin here is all logic, and fancy interactive features, which may be available a second after, but not in the very beginning.

    Robin这里是所有逻辑和奇特的交互功能,可能在第二秒才可用,但不是一开始就可用。

It would be better to call this a vertical code splitting where code branches exist in a parallel, in opposite to a common horizontal code splitting where code branches are cut.

最好将这称为垂直代码拆分 ,其中代码分支并行存在,这与剪切代码分支的常见水平代码拆分相反。

In some lands, this trio was known as replace reducer or other ways to lazy load redux logic and side effects.

在某些地区 ,此三重奏被称为replace reducer或其他延迟加载Redux逻辑和副作用的方法。

In some other lands, it is known as "3 Phased" code splitting.

在其他一些国家 ,这称为"3 Phased" code splitting

It's just another separation of concerns, applicable only to cases, where you can defer loading some part of a component, but not another part.
这只是关注点的另一种分离,仅适用于您可以推迟加载组件的某些部分而不是另一部分的情况。
phase 3
Building the New facebook.com with React, GraphQL and Relay, where 使用React,GraphQL和Relay构建New facebook.com的图像,其中 importForInteractions, or importForInteractionsimportAfter importAfter sidecarsidecar

And there is an interesting observation — while Batman is more valuable for a customer, as long as it's something customer might see, he is always in shape… While Robin, you know, he might be a bit overweight, and require much more bytes for living.

而且有一个有趣的发现-尽管Batman对客户来说更有价值,但只要有客户看到的东西,他就始终处于健康状态……而Robin可能有点超重 ,并且需要更多字节活的。

As a result — Batman alone is something much be bearable for a customer — he provides more value at a lower cost. You are my hero Bat!

因此,对于客户而言,蝙蝠侠本身就是一件值得承受的事情,他以较低的成本提供了更多的价值。 你是我的英雄蝙蝠!

可以移动到边车上的东西: (What could be moved to a sidecar:)

  • majority of useEffect, componentDidMount and friends.

    大多数useEffectcomponentDidMount和朋友。

  • like all Modal effects. Ie focus and scroll locks. You might first display a modal, and only then make Modal modal, ie "lock" customer's attention.

    像所有模态效果一样 即focusscroll锁定。 您可能首先显示一个模态,然后使模成为模 ,即“锁定”客户的注意力。

  • Forms. Move all logic and validations to a sidecar, and block form submission until that logic is loaded. The customer could start filling the form, not knowing that it's only Batman.

    形式。 将所有逻辑和验证移到另一边,并阻止表单提交,直到加载该逻辑。 客户可能会开始填写表格,而不知道这只是Batman

  • Some animations. A whole react-spring in my case.

    一些动画。 就我而言,这是一个完整的react-spring

  • Some visual stuff. Like Custom scrollbars, which might display fancy scroll-bars a second later.

    一些视觉的东西。 类似于“ 自定义”滚动条 ,它可能会在一秒钟后显示精美的滚动条。

Also, don't forget — Every piece of code, offloaded to a sidecar, also offload things like core-js poly- and ponyfills, used by the removed code.

另外,请不要忘记-卸载到Sidecar上的每一段代码,也卸载了已删除的代码所使用的core-js poly-和ponyfills之类的东西。

Code Splitting can be smarter than it is in our apps today. We must realize there is 2 kinds of code to split: 1) visual aspects 2) interactive aspects. The latter can come a few moments later. Sidecar makes it seamless to split the two tasks, giving the perception that everything loaded faster. And it will.

代码拆分比今天的应用程序更智能。 我们必须意识到有两种代码可以拆分:1)视觉方面2)交互方面。 稍后可能会出现后者。 Sidecar可以无缝地拆分这两个任务,从而使您感觉到所有内容的加载速度都更快 。 而且会的。

最早的代码拆分方法 (The oldest way to code split)

While it may still not be quite clear when and what a sidecar is, I'll give a simple explanation:

虽然尚不清楚何时以及什么是sidecar ,但我将给出一个简单的解释:

Sidecar is SidecarALL YOUR SCRIPTS. Sidecar is the way we 您的全部脚本 。 Sidecar是我们在今天得到的所有前端东西之前进行 codesplit before all that frontend stuff we got today. 代码拆分的方式。

I am talking about Server Side Rendering(SSR), or just plain HTML, we all were used to just yesterday. Sidecar makes things as easy as they used to be when pages contained HTML and logic lived separately in embeddable external scripts (separation of concerns).

我说的是服务器端渲染( SSR )或只是纯HTML ,我们都习惯了昨天。 当包含HTML和逻辑的页面分别存在于可嵌入的外部脚本中(关注点分离)时, Sidecar使事情变得像以前一样容易。

We had HTML, plus CSS, plus some scripts inlined, plus the rest of the scripts extracted to a .js files.

我们有HTML,CSS 加上一些脚本内联, 再加上提取到一个脚本的其余部分.js文件。

HTML+CSS+inlined-js were Batman, while external scripts were Robin, and the site was able to function without Robin, and, honestly, partially without Batman (he will continue the fight with both legs(inlined scripts) broken). That was just yesterday, and many "non modern and cool" sites are the same today.

HTML + CSS + inlined-jsBatman ,而外部脚本是Robin ,并且该网站能够在没有Robin的情况下正常运行,并且说实话,在没有Batman的情况下(他会在双腿断断续续的情况下继续战斗)。 那只是昨天,许多“非现代而酷”的网站今天都一样。



If your application supports SSR — try to disable js and make it work without it. Then it would be clear what could be moved to a sidecar. If your application is a client-side only SPA — try to imagine how it would work, if SSR existed.

如果您的应用程序支持SSR,请尝试禁用js并使其在没有它的情况下正常工作。 然后,很明显可以将什么移动到边车上。 如果您的应用程序是仅客户端SPA,请尝试想象一下,如果存在SSR,它将如何工作。

theurge.com, written in React, is fully functional theurge.com功能全面, without any js enabled. 无需启用任何js

There is a lot of things you may offload to a sidecar. For example:

您可能需要将很多事情转移到边车上。 例如:

  • comments. You might ship code to display comments, but not answer, as long as it might require more code(including WYSIWYG editor), which is not required initially. It's better to delay a commenting box, or even just hide code loading behind animation, than delay a whole page.

    注释。 只要可能需要更多的代码(包括所见即所得的编辑器),您可能会附带display注释的代码,而不display answer ,但最初不需要。 最好延迟一个注释框 ,甚至只是将代码隐藏在动画后面,而不是延迟整个页面。

  • video player. Ship "video" without "controls". Load them a second later, them customer might try to interact with it.

    视频播放器。 投放没有“控件”的“视频”。 一秒钟后加载它们,他们的客户可能会尝试与之交互。
  • image gallery, like slick. It's not a big deal to draw it, but much harder to animate and manage. It's clear what could be moved to a sidecar.

    图片库,如slick绘制它并不是什么大问题,但是要赋予动画和管理难度就更大了。 很明显,什么可以转移到边车上。

Just think what is essential for your application, and what is not quite...
只需考虑对您的应用程序必不可少的内容,而对于您的应用程序则不足够...

实施细节 (Implementation details)

(DI)组件代码拆分 ((DI) Component code splitting)

The simplest form of sidecar is easy to implement — just move everything to a sub component, you may code split using an "old" ways. It's almost a separation between Smart and Dumb components, but this time Smart is not contaniting a Dumb one — it's opposite.

sidecar的最简单形式很容易实现-只需将所有内容移动到子组件,您就可以使用“旧的”方式对代码进行拆分。 这几乎是Smart和Dumb组件之间的分离,但是这次Smart并不是在一个Dumb组件-相反。

const SmartComponent = React.lazy( () => import('./SmartComponent'));class DumbComponent extends React.Component {render() {return (<React.Fragment><SmartComponent ref={this} /> // <-- move smart one inside<TheActualMarkup />           // <-- the "real" stuff is here</React.Fragment>} 
}

That also requires moving initialization code to a Dumb one, but you are still able to code-split the heaviest part of a code.

这也需要将初始化代码移至哑巴代码,但是您仍然可以对代码中最重的部分进行代码拆分。

parallel or parallelvertical code splitting pattern now? vertical代码拆分模式吗?

使用Sidecar (useSidecar)

Building the New facebook.com with React, GraphQL and Relay, I've already mentioned here, had a concept of loadAfter or importForInteractivity, which is quite alike sidecar concept.

我已经在这里提到过, 使用React,GraphQL和Relay构建New facebook.com的概念是loadAfterimportForInteractivity ,这与sidecar概念非常相似。

In the same time, I would not recommend creating something like useSidecar as long you might intentionally try to use hooks inside, but code splitting in this form would break rule of hooks.

同时,我不建议您创建诸如useSidecar类的useSidecar ,只要您可能有意尝试在其中使用hooks ,但是以这种形式进行代码拆分会破坏钩子规则

Please prefer a more declarative component way. And you might use hooks inside SideCar component.

请选择一种更具声明性的组件方式。 而且,您可以在SideCar组件内使用hooks

const Controller = React.lazy( () => import('./Controller'));
const DumbComponent = () => {const ref = useRef();const state = useState();return (<><Controller componentRef={ref} state={state} /><TheRealStuff ref={ref} state={state[0]} /></>)
}

预取 (Prefetching)

Dont forget — you might use loading priority hinting to preload or prefetch sidecar and make it shipping more transparent and invisible.

不要忘记-您可以使用加载优先级提示来预加载或预取sidecar ,并使它的运输更加透明和不可见。

Important stuff — prefetching scripts would load it via network, but not execute (and spend CPU) unless it actually required.

重要事项-预取脚本将通过网络加载它,但除非实际需要,否则不执行(并花费CPU)。

固态继电器 (SSR)

Unlike normal code splitting, no special action is required for SSR. Sidecar might not be a part of the SSR process and not required before hydration step. It's could be postponed "by design".

常规代码拆分不同,SSR不需要采取特殊操作。 Sidecar可能不是SSR流程的一部分,并且在hydration步骤之前不需要。 可以“按设计”将其推迟。

Thus — feel free to use React.lazy(ideally something without Suspense, you don't need any failback(loading) indicators here), or any other library, with, but better without SSR support to skip sidecar chunks during SSR process.

因此,可以随意使用React.lazy (理想情况下没有 Suspense ,这里不需要任何故障回复(加载)指示符)或任何其他库,但最好没有SSR支持,以便在SSR过程中跳过边车块。

不良零件 (The bad parts)

But there are a few bad parts of this idea

但是这个想法有一些坏处

蝙蝠侠不是产品名称 (Batman is not a production name)

While Batman/Robin might be a good mind concept, and sidecar is a perfect match for the technology itself — there is no "good" name for the maincar. There is no such thing as a maincar, and obviously Batman, Lonely Wolf, Solitude, Driver and Solo shall not be used to name a non-a-sidecar part.

尽管Batman / Robin Batman / Robin可能是个好主意,而maincar本身就是该技术的完美搭档-这款主sidecar并没有“好”的名字。 有一个这样的东西maincar ,显然BatmanLonely WolfSolitudeDriverSolo不得用来命名一个非A-三轮一部分。

Facebook have used display and interactivity, and that might be the best option for all of us.

Facebook已经使用了displayinteractivity ,这对于我们所有人来说可能是最好的选择。

If you have a good name for me — leave it in the comments
如果您对我有个好名字,请在评论中保留

摇树 (Tree shaking)

It's more about the separation of concerns from bundler point of view. Let's imagine you have Batman and Robin. And stuff.js

捆绑器的角度来看,更多的是关注点的分离。 假设您有BatmanRobin 。 还有stuff.js

  • stuff.js

    stuff.js

    export * from `./batman.js`
    export * from `./robin.js`

Then you might try component based code splitting to implement a sidecar

然后,您可以尝试基于组件的代码拆分以实现Sidecar

  • main.js

    main.js

    import {batman} from './stuff.js'
    const Robin = React.lazy( () => import('./sidecar.js'));
    export const Component = () => (
    <>
    <Robin />  // sidecar
    <Batman /> // main content
    </>
    )
  • sidecar.js

    sidecar.js

    // and sidecar.js... that's another chunk as long as we `import` it
    import {robin} from './stuff.js'
    .....

In short — the code above would work, but will not do "the job".

简而言之-上面的代码可以工作,但不能做“工作”。

  • if you are using only batman from stuff.js — tree shaking would keep only it.

    如果您仅使用stuff.js batman -摇树只会保留它。

  • if you are using only robin from stuff.js — tree shaking would keep only it.

    如果您仅使用stuff.js robin -摇树只会保留它。

  • but if you are using both, even in different chunks — both will be bundled in a first occurrence of stuff.js, ie the main bundle.

    但是,如果您同时使用这两者,即使它们使用的是不同的块,则两者都将捆绑在第一次出现的stuff.js ,即main bundle

Tree shaking is not code-splitting friendly. You have to separate concerns by files.
树摇不是代码拆分友好的。 您必须按文件分开关注点。

取消导入 (Un-import)

Another thing, forgotten by everybody, is the cost of javascript. It was quite common in the jQuery era, the era of jsonp payload to load the script(with json payload), get the payload, and remove the script.

每个人都忘记的另一件事是javascript的成本。 在jQuery时代( jsonp有效负载时代)非常普遍,它用于加载脚本(带有json有效负载),获取有效负载并删除脚本。

import script, and it will be forever imported, even if no longer needed. import脚本,即使不再需要它也将永远被导入。

As I said before — there is too much JS, and sooner or later, with continuous navigation you will load all of it. We should find a way to un-import no longer need chunk, clearing all internal caches and freeing memory to make web more reliable, and not to crush application with out of memory exceptions.

正如我之前所说的那样-JS太多了,迟早要进行连续导航,您将全部加载。 我们应该找到一种方法,取消导入不再需要的块,清除所有内部缓存并释放内存以使Web更加可靠,并且不使用内存不足异常破坏应用程序。

Probably the ability to un-import (webpack could do it) is one of the reasons we should stick with component-based API, as long as it gives us an ability to handle unmount.

un-import的能力(webpack 可以做到 ) 也许是我们坚持使用基于组件的 API的原因之一,只要它使我们能够处理unmount

So far — ESM modules standards have nothing about stuff like this — nor about cache control, nor about reversing import action.

到目前为止,ESM模块标准与此类东西无关,与缓存控制无关,也与反向导入操作无关。

创建支持sidecar的库 (Creating a sidecar-enabled Library)

By today there is only one way to create a sidecar-enabled library:

到目前为止,只有一种方法可以创建启用了sidecar库:

  • split your component into parts

    将您的组件分成几部分
  • expose a main part and connected part(not to break API) via index

    通过index公开main部分和connected部分(不破坏API)

  • expose a sidecar via a separated entry point.

    通过单独的入口点暴露sidecar

  • in the target code — import the main part and the sidecar — tree shaking should cut a connected part.

    在目标代码中-导入main零件和sidecar -摇树摇树应该切断connected零件。

This time tree shaking should work properly, and the only problem — is how to name the main part.

这次摇晃树应该可以正常工作,唯一的问题是如何命名main部分。

  • main.js

    main.js

export const Main = ({sidecar, ...props}) => (<div>{sidecar} ....</div>
);
  • connected.js

    connected.js

import Main from './Component';
import Sidecar from './Sidecar';export const Connected = props => (<Mainsidecar={<Sidecar />}{...props}/>
);
  • index.js

    index.js

export * from './Main';
export * from './Connected';
  • sidecar.js

    sidecar.js

import * from './Sidecar';

In short, the change could be represented via a small comparison

简而言之,可以通过较小的比较来表示更改

//your app BEFORE
import {Connected} from 'library'; //// -------------------------//your app AFTER, compare this core to `connected.js`
import {Main} from 'library';
const Sidecar = React.lazy(import( () => import('library/sidecar')));
// ^ all the difference ^export SideConnected = props => (<Mainsidecar={<Sidecar />}{...props}/>
);// ^ you will load only Main, Sidecar will arrive later.

Theoretically dynamic import could be used inside node_modules, making assemble process more transparent.

理论上, dynamic import可以在node_modules中使用,从而使组装过程更加透明。

children/ children / slot pattern, so common in React. slot模式,在React中很常见。

未来 (The future)

Facebook proved that the idea is right. If you haven't seen that video — do it right now. I've just explained the same idea from a bit different angle (and started writing this article a week before F8 conference).

Facebook证明了这个想法是正确的。 如果您还没有看过该视频,请立即进行操作。 我只是从不同的角度解释了相同的想法(并在F8会议召开的一周前开始撰写本文)。

Right now it requires some code changes to be applied to your code base. It requires a more explicit separation of concerns to actually separate them, and let of codesplit not horizontally, but vertically, shipping lesser code for a bigger user experience.

现在,它需要对您的代码库进行一些代码更改。 它需要更明确地分离关注点才能真正将它们分离,并且让代码不是水平而是垂直拆分,以交付更少的代码以提供更大的用户体验。

Sidecar, probably, is the only way, except old school SSR, to handle BIG code bases. Last chance to ship a minimal amount of code, when you have a lot of it.

除了老式SSR之外, Sidecar可能是处理BIG代码库的唯一方法。 当您拥有大量代码时,这是最后机会发布少量代码。

It could make a BIG application smaller, and a SMALL application even more smaller.
它可以使BIG应用程序更小,而SMALL应用程序更小。

10 years ago the medium website was "ready" in 300ms, and was really ready a few milliseconds after. Today seconds and even more than 10 seconds are the common numbers. What a shame.

10年前,中型网站已在300毫秒内“准备就绪”,并在几毫秒后才真正准备就绪。 今天,秒数甚至超过10秒是常见数字。 多可惜。

Let's take a pause, and think — how we could solve the problem, and make UX great again...

让我们暂停一下,思考一下-我们如何解决问题,并使UX再次出色...

总体 (Overall)

  • Component code splitting is a most powerful tool, giving you the ability to completely split something, but it comes with a cost — you might not display anything except a blank page, or a skeleton for a while. That's a horizontal separation.

    组件代码分裂是一个最有力的工具,让你的能力完全分裂的东西,但它是有代价-你可能不只是一个空白页,或者一会儿的骨架显示任何内容。 那是一个水平的分离。

  • Library code splitting could help when component splitting would not. That's a horizontal separation.

    库代码拆分可能会在组件拆分不起作用时提供帮助。 那是一个水平的分离。
  • Code, offloaded to a sidecar would complete the picture, and may let you provide a far better user experience. But would also require some engineering effort. That's a vertical separation.

    卸载到Sidecar上的代码将使图片更完整,并可以使您提供更好的用户体验。 但是还需要一些工程上的努力。 这是垂直分隔。

Let's have a conversation about this.

让我们来讨论一下

停止! 那么您尝试解决的问题呢? (Stop! So what about the problems you tried to solve?)

Well, that was only the first part. We are in the endgame now, it would take a few more weeks to write down the second part of this proposal. Meanwhile… get in the sidecar!

好吧,那只是第一部分。 我们现在正处于最后阶段 ,写下该提议的第二部分还需要几个星期。 同时…进入侧车!

翻译自: https://habr.com/en/post/450942/

sidecar

这篇关于sidecar_Sidecar用于代码拆分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/402499

相关文章

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1

html css jquery选项卡 代码练习小项目

在学习 html 和 css jquery 结合使用的时候 做好是能尝试做一些简单的小功能,来提高自己的 逻辑能力,熟悉代码的编写语法 下面分享一段代码 使用html css jquery选项卡 代码练习 <div class="box"><dl class="tab"><dd class="active">手机</dd><dd>家电</dd><dd>服装</dd><dd>数码</dd><dd

生信代码入门:从零开始掌握生物信息学编程技能

少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 介绍 生物信息学是一个高度跨学科的领域,结合了生物学、计算机科学和统计学。随着高通量测序技术的发展,海量的生物数据需要通过编程来进行处理和分析。因此,掌握生信编程技能,成为每一个生物信息学研究者的必备能力。 生信代码入门,旨在帮助初学者从零开始学习生物信息学中的编程基础。通过学习常用

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所

Unity3D自带Mouse Look鼠标视角代码解析。

Unity3D自带Mouse Look鼠标视角代码解析。 代码块 代码块语法遵循标准markdown代码,例如: using UnityEngine;using System.Collections;/// MouseLook rotates the transform based on the mouse delta./// Minimum and Maximum values can