Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experimental] KendoReact Server Components #1795

Open
kspeyanski opened this issue Dec 12, 2023 · 0 comments
Open

[Experimental] KendoReact Server Components #1795

kspeyanski opened this issue Dec 12, 2023 · 0 comments

Comments

@kspeyanski
Copy link
Contributor

kspeyanski commented Dec 12, 2023

This issue aims to combine all information, discussion and feedback related to KendoReact Server Components (practically the Grid as it's currently the only server-component), and provide a little bit more in-depth technical details which were not covered in the Server Components Documentation.

Consider this entire effort under an experimental flag. The Component is not intended for production use. It's API might change at any moment without introducing a major version. Some of it's features might not work as expected and are prune to change.

The "Why"?

Since the announcement of RSC (React Server Component) we were activelly following the topic, and experimenting internally how we can incorporate the technology in our existing offerrings or explore it through a separate project. With the large adoption of Next.js app router we've felt it's enought of us to push beyond the "hackaton" phase and share our experimental project to the public as soon as possible, and try to gather as much feedback as we can.

Since currently server components are practically supported by a single framework in the face of Next.js and require a running server, we've felt that it's more appropriate to distribute it as a separate package with v0 to avoid confusion with our existing components, and enable us to experiment freely without affecting existing customers of the client-only Grid.

While we're shipping 100+ components, we've always felt that the Grid is the highlight of our offering, and it was deffinitely the place where we wanted to start experimenting. The data story is a main feature discussed in the Server Components RFC and we've definitelly put 2 and 2 together.

The bundle size of 3rd party libraries seems to be one of the major showstopper for adoption. The issue is that vendors are trying rightfully to cover as many scenarios with as little configuration, which oftens comes at the cost of pre-loading everything and hiding in behind a boolean property (e.g. filtering={true}). RSC gives us the right tooling to load only a fraction of the javascript on the client, but also enable our users to execute additional calculations without worrying about final bundle size (e.g. code-highlighting).

The "What"?

TL;DR:

  • An experimental, server-first Grid, with a meaningful client-side code to enhance the UX.

From the begining we were experimenting with a server counterpart of our existing Grid component. We initially wanted ot make it server-only and provide near-zero client-side javascript, however, we latter felt that a more practical approach to this would be somewhat of a hybrid component which is carefully combining server and client parts wherever they made sense.

In addition to this separation, we still wanted to enable developers to configure the component according to their specific application requirements. we've often refered to the following illustration when discussion what scenarios our component should be able to achieve.

image

While this proved to be quite challenging, we're happy with the capabilities of the v0.1 Grid, but still remains a core concept which we will continue to shape once we've gathered enought real-world scenarios.

Usage

The usage we believe hope would be intuitive. Like any other UI Component it recevives props, with the important addition that it can now accept a Promise for data. The RSC platform allows us to take full advantage of this async resolution, and pre-render the entire shell of the component before having the data, and outsource the entire handling of the async operations to the framework itself, which proved to be really convenient.

 <!-- no need to `await` the data  -->
 <Grid data={fetch('...')} />

To cover up for the missing data, a major concept of our Server Components is a first-level API for Loaders. While on a framework level you can define loading.jsx file, we wanted to bring the concept to a component-level by providing a built-in loaders for each constructual part of a component. In the context of a Grid, we're providing loading indicators for whenever data bellow the Container, Row and Cell needs to await a promise.

While this might sounds a bit complicated, we're taking full advantage of RSC and bring it down to passing a fallback prop to a React.Suspense at the right place...at the right time!

<Grid>
  <Header />

  <React.Suspense fallback={<DataRowsLoading />}>
    {await data.map(() => (
      <DataRow />
    ))}
  <React.Suspense>
 
   <Footer />
<Grid>

The How?

Since this is v0 of the project, we expect a lot of things to change, but some major concepts will remain. For example we're really keen to keep most of the tree on the server, and push the use client directive only on the leaf components. This seemed impossible at first sight, as early one we tried to spike specific features (like 'Row selection') which inevitably would force us to bring the row to the client (and subsequentially all the Virtual DOM under it).

You may have seen the following code-snippet, acompanied by the illustration bellow, for composing server components inside client components:

<ClientComponent>
  <ServerComponent>
</ClientComponent>

Credit to the Next.js team for producing such an outstanding documentation!

image

This "Composition" pattern was not really applicable to our scenario, as we were still unsure which components should go to the server, and which to the client — it's up to the developer to decide. Additionally some of the Grid's functionality is working with DOM events from rows and cells which covers 90% of the DOM - so 90% of the component being a client one was not really the desired outcome.

So we've came with the followign concept which helped us build a pattern around providing both a server and client part of a single component, allowing the developer to jump between environments according to their individual application requirements.

image

This is a doodle illustration which we hope would help you visualize the underneath structure. Where the .server part of a component expose and entry point for data-fetching, and it's .client counterpart covers interactiviry to enchance the UX, provide optimistic updates and opens up the component for visual and behavior customization.

The "Whats next"?

We're looking to get a better understanding of the entire server-components feature through sharing our technical preview of an experimental Server Grid Component. We'll be taking every piece of feedback of what you are looking for in a server component, what are you looking forward to build with it and what roadblock are you encountering when trying to adopt a server-first 3rd party library.

@kspeyanski kspeyanski changed the title [placeholder] RSC [Experimental] KendoReact Server Components Dec 13, 2023
@bptodorova bptodorova pinned this issue Dec 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants