Skip to content

Future RFC - Asynchronously import hidden components#19609

Merged
czearing merged 7 commits intomicrosoft:masterfrom
czearing:feat/async-import-hidden-elements
Sep 22, 2021
Merged

Future RFC - Asynchronously import hidden components#19609
czearing merged 7 commits intomicrosoft:masterfrom
czearing:feat/async-import-hidden-elements

Conversation

@czearing
Copy link
Copy Markdown
Collaborator

@czearing czearing commented Sep 1, 2021

This RFC proposes the idea of asynchronously importing hidden components such as Tooltip and ContextualMenu to assist in bundle size related issues.

@codesandbox-ci
Copy link
Copy Markdown

codesandbox-ci Bot commented Sep 1, 2021

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 644d551:

Sandbox Source
@fluentui/react 8 starter Configuration

@size-auditor
Copy link
Copy Markdown

size-auditor Bot commented Sep 1, 2021

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: ae43b3623e0cff41c6dc55bc17de546d4e138d63 (build)

@fabricteam
Copy link
Copy Markdown
Collaborator

fabricteam commented Sep 1, 2021

📊 Bundle size report

Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-accordion
Accordion (including children components)
55.248 kB
17.403 kB
react-avatar
Avatar
57.803 kB
16.148 kB
react-badge
Badge
23.939 kB
7.029 kB
react-badge
CounterBadge
26.929 kB
7.743 kB
react-badge
PresenseBadge
237 B
177 B
react-button
Button
22.932 kB
6.984 kB
react-button
CompoundButton
28.215 kB
7.834 kB
react-button
MenuButton
24.784 kB
7.569 kB
react-button
Button
30.589 kB
8.799 kB
react-button
ToggleButton
32.527 kB
7.601 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
164.296 kB
46.863 kB
react-components
react-components: FluentProvider & webLightTheme
35.754 kB
11.393 kB
react-divider
Divider
15.889 kB
5.747 kB
react-image
Image
9.804 kB
3.942 kB
react-input
Input
31.636 kB
11.312 kB
react-label
Label
9.397 kB
3.839 kB
react-link
Link
11.633 kB
4.582 kB
react-make-styles
makeStaticStyles (runtime)
7.59 kB
3.321 kB
react-make-styles
makeStyles + mergeClasses (runtime)
22.135 kB
8.356 kB
react-make-styles
makeStyles + mergeClasses (build time)
2.557 kB
1.202 kB
react-menu
Menu (including children components)
103.402 kB
31.415 kB
react-menu
Menu (including selectable components)
105.678 kB
31.769 kB
react-popover
Popover
100.411 kB
30.075 kB
react-portal
Portal
6.725 kB
2.237 kB
react-positioning
usePopper
23.145 kB
7.942 kB
react-provider
FluentProvider
15.748 kB
5.773 kB
react-slider
Slider
32.056 kB
10.087 kB
react-switch
Switch
18.816 kB
6.277 kB
react-text
Text - Default
11.722 kB
4.437 kB
react-text
Text - Wrappers
15.344 kB
4.733 kB
react-theme
Teams: all themes
32.945 kB
6.677 kB
react-theme
Teams: Light theme
20.251 kB
5.665 kB
react-tooltip
Tooltip
46.02 kB
15.663 kB
react-utilities
SSRProvider
213 B
170 B
🤖 This report was generated against ae43b3623e0cff41c6dc55bc17de546d4e138d63

@fabricteam
Copy link
Copy Markdown
Collaborator

fabricteam commented Sep 1, 2021

Perf Analysis (@fluentui/react)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 917 881 5000
BaseButton mount 905 921 5000
Breadcrumb mount 2682 2688 1000
ButtonNext mount 460 447 5000
Checkbox mount 1481 1506 5000
CheckboxBase mount 1259 1285 5000
ChoiceGroup mount 4784 4692 5000
ComboBox mount 998 971 1000
CommandBar mount 10343 10418 1000
ContextualMenu mount 6713 6657 1000
DefaultButton mount 1135 1147 5000
DetailsRow mount 3686 3699 5000
DetailsRowFast mount 3705 3777 5000
DetailsRowNoStyles mount 3579 3631 5000
Dialog mount 2465 2404 1000
DocumentCardTitle mount 147 146 1000
Dropdown mount 3213 3234 5000
FluentProviderNext mount 7479 7517 5000
FluentProviderWithTheme mount 358 316 10
FluentProviderWithTheme virtual-rerender 95 100 10
FluentProviderWithTheme virtual-rerender-with-unmount 479 483 10
FocusTrapZone mount 1776 1802 5000
FocusZone mount 1819 1808 5000
IconButton mount 1766 1761 5000
Label mount 333 350 5000
Layer mount 3050 3019 5000
Link mount 485 480 5000
MakeStyles mount 1816 1815 50000
MenuButton mount 1476 1485 5000
MessageBar mount 2023 2017 5000
Nav mount 3283 3227 1000
OverflowSet mount 1089 1095 5000
Panel mount 2365 2342 1000
Persona mount 826 840 1000
Pivot mount 1410 1409 1000
PrimaryButton mount 1277 1281 5000
Rating mount 7610 7739 5000
SearchBox mount 1330 1345 5000
Shimmer mount 2534 2533 5000
Slider mount 1953 1942 5000
SpinButton mount 4997 4930 5000
Spinner mount 425 414 5000
SplitButton mount 3208 3116 5000
Stack mount 489 505 5000
StackWithIntrinsicChildren mount 1564 1509 5000
StackWithTextChildren mount 4470 4518 5000
SwatchColorPicker mount 10255 10169 5000
Tabs mount 1433 1397 1000
TagPicker mount 2617 2574 5000
TeachingBubble mount 13391 13447 5000
Text mount 436 413 5000
TextField mount 1358 1389 5000
ThemeProvider mount 1192 1175 5000
ThemeProvider virtual-rerender 598 608 5000
ThemeProvider virtual-rerender-with-unmount 1919 1891 5000
Toggle mount 792 806 5000
buttonNative mount 107 114 5000

Perf Analysis (@fluentui/react-northstar)

Perf tests with no regressions
Scenario Current PR Ticks Baseline Ticks Ratio
ListMinimalPerf.default 536 487 1.1:1
LayoutMinimalPerf.default 372 351 1.06:1
ImageMinimalPerf.default 364 346 1.05:1
RefMinimalPerf.default 243 231 1.05:1
CardMinimalPerf.default 572 549 1.04:1
ChatWithPopoverPerf.default 370 356 1.04:1
GridMinimalPerf.default 345 332 1.04:1
HeaderMinimalPerf.default 366 352 1.04:1
TooltipMinimalPerf.default 1024 989 1.04:1
TreeWith60ListItems.default 175 168 1.04:1
AttachmentMinimalPerf.default 153 148 1.03:1
AvatarMinimalPerf.default 189 184 1.03:1
LabelMinimalPerf.default 377 367 1.03:1
MenuMinimalPerf.default 841 819 1.03:1
TextMinimalPerf.default 343 334 1.03:1
BoxMinimalPerf.default 366 360 1.02:1
ButtonSlotsPerf.default 547 535 1.02:1
CarouselMinimalPerf.default 460 451 1.02:1
CheckboxMinimalPerf.default 2733 2674 1.02:1
EmbedMinimalPerf.default 4148 4074 1.02:1
PortalMinimalPerf.default 179 176 1.02:1
RadioGroupMinimalPerf.default 453 445 1.02:1
SkeletonMinimalPerf.default 354 347 1.02:1
DatepickerMinimalPerf.default 5407 5335 1.01:1
DialogMinimalPerf.default 761 755 1.01:1
FlexMinimalPerf.default 278 276 1.01:1
FormMinimalPerf.default 401 397 1.01:1
HeaderSlotsPerf.default 758 750 1.01:1
ListCommonPerf.default 629 621 1.01:1
LoaderMinimalPerf.default 694 689 1.01:1
ProviderMergeThemesPerf.default 1721 1705 1.01:1
ReactionMinimalPerf.default 374 372 1.01:1
StatusMinimalPerf.default 664 657 1.01:1
TableManyItemsPerf.default 1899 1878 1.01:1
TreeMinimalPerf.default 791 784 1.01:1
AccordionMinimalPerf.default 139 139 1:1
ChatMinimalPerf.default 661 661 1:1
DropdownMinimalPerf.default 3088 3076 1:1
PopupMinimalPerf.default 598 596 1:1
SegmentMinimalPerf.default 347 346 1:1
SplitButtonMinimalPerf.default 4076 4078 1:1
TextAreaMinimalPerf.default 492 494 1:1
ToolbarMinimalPerf.default 926 922 1:1
VideoMinimalPerf.default 620 623 1:1
ButtonMinimalPerf.default 171 172 0.99:1
ButtonOverridesMissPerf.default 1676 1690 0.99:1
InputMinimalPerf.default 1225 1240 0.99:1
ItemLayoutMinimalPerf.default 1183 1189 0.99:1
MenuButtonMinimalPerf.default 1651 1664 0.99:1
RosterPerf.default 1157 1164 0.99:1
SliderMinimalPerf.default 1541 1550 0.99:1
TableMinimalPerf.default 397 401 0.99:1
CustomToolbarPrototype.default 3803 3831 0.99:1
AlertMinimalPerf.default 266 272 0.98:1
AnimationMinimalPerf.default 399 409 0.98:1
AttachmentSlotsPerf.default 1070 1089 0.98:1
ChatDuplicateMessagesPerf.default 289 294 0.98:1
DropdownManyItemsPerf.default 671 682 0.98:1
ListWith60ListItems.default 636 646 0.98:1
ProviderMinimalPerf.default 966 988 0.98:1
IconMinimalPerf.default 588 601 0.98:1
DividerMinimalPerf.default 339 348 0.97:1
ListNestedPerf.default 532 547 0.97:1

@ecraig12345 ecraig12345 requested a review from a team September 1, 2021 22:44
Copy link
Copy Markdown
Member

@ecraig12345 ecraig12345 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for driving this @czearing, and thanks @dzearing for providing the background! I think this makes sense but I'm curious to get input from people on @microsoft/teams-prg and/or anyone else who might be more familiar with partner scenarios to ensure we're not missing any potential issues.

Comment thread rfcs/convergence/async-import-hidden-components.md Outdated
Comment thread rfcs/convergence/async-import-hidden-components.md

Components such as `Tooltip` are split into 2 parts:

1. A synchronous tiny component
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get info about the actual size of the "tiny" part for something like Tooltip or Menu?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would dynamic imports might be most useful in the icon case to only bring in the component with the SVG when used?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tiny part is the trigger code required to "start" showing the menu/tooltip. likely less< 1k.

```jsx
<>
{state.children}
{state.shouldRenderTooltip && (...)}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please add to the example how we would apply aria-label / labelledby while the full tooltip component is not loaded?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it would ever work properly to use a tooltip as the target of aria-labelledby, regardless of whether it's synchronously or async loaded (unless I'm misunderstanding what you mean). @smhigley could confirm.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean the fucntionality of applying label/description based on triggerAriaAttribute prop on the trigger:

if (state.triggerAriaAttribute === 'labelledby' && !isServerSideRender) {

how would that work when there is only the minimal part loaded?


#### Cons

- Partners who use old bundlers would potentially be affected.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a user does not use something like create-react-app and uses a minimal webpack config, would that break their app until they add the approriate code splitting plugin ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Webpack should handle that automatically (no plugins needed) since import() is standard syntax now.

Copy link
Copy Markdown
Member

@ecraig12345 ecraig12345 Sep 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the semi-relevant section in the docs. It's not super explicit about this but from what's there and my experience I'm still pretty sure it will "just work." SplitChunksPlugin or whatever is only needed if you want to have highly customized splitting behavior. https://webpack.js.org/guides/code-splitting/#dynamic-imports

Copy link
Copy Markdown
Member

@khmakoto khmakoto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if this is an issue or not, but are there any concerns in using async imports on SSR scenarios?

@czearing
Copy link
Copy Markdown
Collaborator Author

czearing commented Sep 4, 2021

I don't know if this is an issue or not, but are there any concerns in using async imports on SSR scenarios?

Good question. Async imports work as long as you are using node 14 with modules however React.lazy is yet to support SSR. There are other code splitting tools such as Loadable Components (this is what React suggests using for SSR) that could support it. However I believe that some hidden components such as Tooltip would not function correctly in SSR since they require positioning logic and hover events to become visible.

<>
{state.children}
{state.shouldRenderTooltip && (
<React.Suspense fallback={null}>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • What happens when this fails to load/loads after .shouldRenderTooltip becomes true? Customers will see nothing?
  • SSR is not supported by .Suspense ➡ we can't rely on it currently

Please check for inspiration: https://github.com/theKashey/use-sidecar
I haven't checked how it works, but it's very close to our goal I guess

Copy link
Copy Markdown
Member

@dzearing dzearing Sep 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a javascript file fails to load on web app startup or on an async on demand bundle, this is essentially out of scope of fluent ui. Some webpack partners override the webpack async loading logic to have retries and fallbacks and ultimately a BSOD equivalent.


## Problem statement

We have several scenarios where async imports would be beneficial for minimizing bundle size impact on our partners apps, especially for initial page load.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Users with limited bandwidth or where the last mile is distant from origin, the cost of each JS download can be mostly the request resolution and server connection. Once the data starts downloading, the payload size doesn't cost as much relative to the connection. In other words, if there are lots of small requests it can be more expensive.

This is typically solved with CDNs or edge caching.

  • What the experience would be with devs wanting to use a CDN?
  • Would each dynamic import be able to be resolved to a CDN address?
  • Does having lots of code splits mean that there are more things being invalidated as fluent changes?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SplitChunksPlugin has options to help configure this on the consumer side, including without any knowledge of paths/filenames. Most nontrivial apps will already have async imports and multiple bundles, and probably have SplitChunksPlugin or a similar solution set up to customize it. So I don't think this is something we need to worry about directly.

@ecraig12345
Copy link
Copy Markdown
Member

Meeting notes:

  • Need to look at specific major partners, how they're handling bundling/splitting, what their priorities are/why they're splitting, and how they could customize if we're splitting
  • If we don't use async imports, how do we handle the problem that motivated this proposal? (want to have a tooltip or some other on-demand feature in a component without it getting included in PLT bundle)
  • Will this create issues for using apps offline? (pretty sure this is an app concern and something they'd configure, not that we'd configure)
  • Can we have a way to support both sync/async?
    • Ideally we would be able to support both options a Tooltip component as well as an async version such as AsyncTooltip. This way an end user won't be surprised when a presentational component suddenly behaves asyncronously behind the scenes but at the same time they have a way to opt-into this async behaviour provided by React natively without the need to code it themselves.
    • webpack or babel plugin for setting specific components to lazy? (might need to have goal of low config)
  • How to address SSR issue already commented on?

@ecraig12345
Copy link
Copy Markdown
Member

Discussed this again and the conclusion was that we should close it for now (and make a follow-up issue) since a lot more investigation is needed and it's not immediately blocking any critical scenarios. Thanks @czearing and @dzearing for starting the discussion though!

@dzearing
Copy link
Copy Markdown
Member

dzearing commented Sep 13, 2021

I think closing this prematurely without a clear plan of next steps should be clarified a little.

Essentially, designing for sync/async splits can change the design of a component significantly. You need to separate your logic into the "synchronous" inexpensive part from the "async" expensive part and ask/answer questions about this.

It doesn't have to be complicated, and it doesn't have to apply to every component. But we're working on tooltip and menu now, so really this should be considered as part of the design in those components.

But history has shown here that ignoring bundle size leads to customers being frustrated, and we've done this sort of thing in the past. I think in the past there weren't standard practices involved here. But there are now. So we should design for them.

IRT meeting notes:

Need to look at specific major partners, how they're handling bundling/splitting, what their priorities are/why they're splitting, and how they could customize if we're splitting

SHysom is a great resource here if you have questions on bundling/splitting in ooui.

But I think rather than assigning a dev who can help investigate specific major partners on their bundle strat, we could have something more outcome oriented. E.g. Importing Menu or Tooltip get split automatically, so your initial page render skips on the 30k of popper/focuszone/portal/etc code. This might be done in multiple ways if async imports has some sort of snag.

This RFC originated from conversations with him and others on his team working on Ribbon perf. It is really important that we avoid bundle penalties for using Tooltips and Menus. They are used frequently in Ribbon and other Office scenarios.

A couple years ago, one dev was evaluating Menus and worked closely with KChau on how to defer the menu loading code because it brought in a swarm of dependencies. It was painful because we didn't have tools and Ken wrote a webpack plugin specifically to support this scenario because there wasn't a great way on the app consumer side to know exactly where/how to split. It wasn't considered in the design.

We have an opportunity with converged components to design these limited scenarios correctly so that bundle size isn't penalized. Ignoring it will likely repeat history.

Will this create issues for using apps offline? (pretty sure this is an app concern and something they'd configure, not that we'd configure)

No more than any other async import in the bundle. Apps which support offline have a manifest of resources to be downloaded, so that they CAN load their app offline.

Can we have a way to support both sync/async?

You could certainly have an import like "useSyncTooltip" which synchronously includes both things. Partners could import/call it in their app code (so that it shows up in the app bundle and dependencies aren't tree shaken.) Then when the async imports in Tooltip kick off they resolve to things in the app bundle. But I would avoid this until there's a real use case.

How to address SSR issue already commented on?

I'm not really sure it's an issue for things which don't render on initial page load. SSR would only render the visible things and avoid calling lifetime operations. But honestly Tooltip/Menu devs should try rendering those components in SSR and figure out problems/solutions; we need devs to understand SSR scenarios.

webpack or babel plugin for setting specific components to lazy? (might need to have goal of low config)

Yep Ken did this. Nobody discovers it. The default should do the right thing with no config. You should have to work hard to do the weird thing like synchronously rendering tooltip.

While maybe the RFC doesn't need to be set in stone right now, I would strongly urge having the Menu/Tooltip devs drive a solution for the bundle problem that this is addressing, and really take over the RFC and drive it to completion. I'm afraid opening an issue without a driver will go to graveyard and lead to "let's just make everything synchronous, and let the app dev deal with it because that's easy."

We all need great empathy towards minimizing bundle bloat, and async imports are low hanging fruit imo.

@ecraig12345
Copy link
Copy Markdown
Member

@dzearing Ah okay, I wasn't aware that this was immediately impactful for Menu and Tooltip (I thought the motivating scenario was specifically the tooltip on Slider, which is definitely less urgent). cc @ling1726 and @behowell

The major blocker here is lack of support for async imports in Node without newer versions and/or experimental flags, causing issues in SSR and maybe tests (though tests have to use commonjs still for related reasons). Lack of support for React lazy/suspense in SSR is also an issue. Unless we can find a way around those things, we probably can't use async imports in our code directly.

So then the question becomes what we can do instead--there were some ideas, but all of them need further investigation.

  • For components which we'd want to load async, user must pass them in through slots/props (would have to figure out exact API)
    • This could be hard to mesh with our existing slot API: in some cases, to avoid requiring consumers to have knowledge of exactly what a given component's "built-in" tooltip ought to look like/contain, they'd need to pass the component itself not a rendered version
  • Use a provider/context to customize loading
    • potential issue: webpack requires use of string literals in imports for code splitting/tree shaking (can't pass a path name to a custom loader function)
  • Some other user-customizable loader for loading things either sync or async as desired (@varholak-peter had an idea about this)

Alternatively, it might be possible to say (and document) that SSR is an edge case where it's okay to require extra config, and provide or recommend a babel plugin or something to convert all async imports to sync. This would probably be okay with our major partner teams (since AFAIK none of them use SSR?) but seems a bit dismissive of the larger community.

(Another quick note on conversion plugins: writing all imports as sync and using a plugin to selectively convert to async is much more complicated and may not be feasible.)

Even if we find a way around the SSR issues and decide to start using async imports in our code, there are still quite a few outstanding questions about the implications in different scenarios:

  • What code splitting approach are partners using today (automatic, chunk count or size, specific filenames/entry points, other?) and would introducing async imports into our own code create issues for that?
  • Would this make it harder for partners to make their apps work offline?
    • My guess is no, because a nontrivial app would already be using async imports and multiple bundles internally, so extending that configuration to our code would probably not be an issue
    • More generally, it would be good to understand and document what would a partner need to do to make their app work offline (using webpack, other bundlers, and/or any other configuration required)
  • Basic create-react-app: does this result in multiplication of tiny chunks, what needs to be done for it to work offline, can either of the above be customized

Basically we need a lot more investigation, including demos of various approaches, and the consensus among those who were in the meeting this morning was that we just don't have time for that right now. However that consensus was not considering the general issues you raised about menu and tooltip triggers--we didn't discuss that at all since we weren't aware that was an immediate concern.

@dzearing
Copy link
Copy Markdown
Member

If in your typescript code you say:

export function getFoo() {
  import("./Foo").then((foo) => {
    console.log(foo);
  });
}

...and you compile to commonjs modules, it produces this:

"use strict";
exports.__esModule = true;
exports.getFoo = void 0;
function getFoo() {
    Promise.resolve().then(function () { return require("./Foo"); }).then(function (foo) {
        console.log(foo);
    });
}
exports.getFoo = getFoo;

Which I believe is compatible with node 12 and even older (wherever Promises were introduced.)

@ecraig12345
Copy link
Copy Markdown
Member

@dzearing Maybe a silly question (I'm not familiar with this area) but is it expected in general that SSR would have to use the commonjs version of the code?

@dzearing
Copy link
Copy Markdown
Member

pretty likely; I think when you import a .js file, even the latest node versions will assume commonjs unless you do one of the following:

  • You rename the extension to .mjs
  • You provide "type": "module" in your package.json to indicate that .js files should be parsed as ESM.

One thing I'm not totally sure on however is if it infers the module default if the initial resolution was due to module entry point. That is, you import @fluentui/react-tooltip, which has a module entry to index.js. That file then exports * from ./Tooltip.js. Will both files be treated as ESM because module was used to resolve the entry? I don't know that one, needs some experimentation. I can try this out and see what happens.

@dzearing
Copy link
Copy Markdown
Member

Also, I assume this edge case isn't an issue for older versions that don't support async imports (v12?) because likely they would also not try to load the entry from module if ESM isn't enabled, thus falling back to main which would point to the commonjs files.

@levithomason
Copy link
Copy Markdown
Member

levithomason commented Sep 14, 2021

One idea that comes to mind is that this might be a good candidate for a v10 change. My thoughts are that we're mid releasing beta and a stable 9.0.0 soon after and async, while valuable, is likely to be a significant departure from the current architecture.

We have many good things to provide in v9 as it stands and should continue with shipping that, but we should also continue this async proposal. I would second @dzearing's comments about bundle size issues for importing things that are not used on first load. It was one of the things we discussed in the very early days of convergence as both libs suffered from issues with sync interdependencies like this.

All said, this topic deserves a proper amount of time to think through it and test. I don't see that fitting on the 9.0 runway, especially given that we're currently cutting items to make the beta/major targets. But, why don't we continue this conversation and give ourselves some breathing room by considering it a v10 proposal?

@dzearing
Copy link
Copy Markdown
Member

For RFCs that are planning to be re-visited, is there an rfc folder for "v10" that this can be merged into (where all the v10 plans are), so that there's an easy way to come back to it?

@ecraig12345
Copy link
Copy Markdown
Member

We do have a rfcs/future folder, so maybe it could go there?

@czearing czearing changed the title RFC - Asynchronously import hidden components Future RFC - Asynchronously import hidden components Sep 16, 2021
@czearing
Copy link
Copy Markdown
Collaborator Author

I'm reopening the pull request to move the RFC into the future folder so it can be re-visited.

@czearing czearing reopened this Sep 16, 2021
Copy link
Copy Markdown
Member

@khmakoto khmakoto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving now that this is being moved into the future folder, although maybe we should make a note about how we are continuing this conversation later at the beginning or end of the RFC.

Copy link
Copy Markdown
Member

@ecraig12345 ecraig12345 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just pushed an update adding myself to the list of drivers (since you may not be around when this next comes up), switching the comparison to gzip sizes (this is preferred because it's what would actually be downloaded by end users' computers), and clarifying which section of the proposal is the original part that hasn't yet been updated from PR discussion. With that it LGTM. Thanks for working on this!

@czearing czearing merged commit 233bfe1 into microsoft:master Sep 22, 2021
mlp73 pushed a commit to mlp73/fluentui that referenced this pull request Jan 17, 2022
* Adding Future RFC

* Quick fix

* PR feedback

* Moving the async import RFC to the future folder

* Adding sections for "Continuing the discussion" and
"Previously discussed concerns".

* minor updates

Co-authored-by: Elizabeth Craig <elcraig@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: RFC Request for Feedback

Projects

None yet

Development

Successfully merging this pull request may close these issues.