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

Nested Smart Components (SSR) #6456

Closed
romshark opened this issue Aug 26, 2017 · 2 comments
Closed

Nested Smart Components (SSR) #6456

romshark opened this issue Aug 26, 2017 · 2 comments

Comments

@romshark
Copy link

What problem does this feature solve?

Introduction

Separation of concerns is important, that's why we always try to encapsulate data and logic inside independent smart components reusable throughout the application. Smart Components usually perform asynchronous operations like data fetching and they can be nested inside each other.

Problem

Currently the SSR solution proposed by the vue-hackernews-2.0 example requires all asynchronous operations to be performed in the asyncData hook, which unfortunately is only available to route-components registered in the router. This makes route-components become "super-smart" as they take responsibility for all the data of all underlying "dumb" components and doesn't allow for any smart component to be placed beneath a route-component. During SSR the server-side renderer won't wait for any nested smart component to finish their asynchronous work.

Desired Behavior

The server-side renderer should wait for all root child components to resolve recursively, hence let every active* smart component attain its renderable state.

Benefits

Not only does this feature allow for better code structuring and seamless SSR support, it is also extremely helpful in this kind of situations where the layout of the application needs to be computed programmatically. Think of content management system were one would be able to compose the final layout of the single-page application by simply putting together independent arbitrary building blocks on top of a template.

Smart Components & APIs

Smart components are served best in combination with GraphQL. Every little smart component asks the GraphQL client for a small part of the graph the API server has to offer. It only fetches the data it needs, no more, no less. The GQL client will batch all those little queries into one big query every 10ms or so and fire them. This way smart components make modular architecture a piece of cake!

* We define components as "active" when they are in the actual context of execution. Inactive components are hidden due to certain application state conditions like the current route for example.

What does the proposed API look like?

API Proposal

We should be able to make any component smart, regardless of where it's placed in the application. Basically this means making the asyncData hook available to any component and not just the route-components.
Then it just becomes a classical dependency tree problem, where out of the tree of components we compose a flat dependency tree filtering out all of the dumb components resulting in an array of Promises the SSR needs to await before finally rendering the page.

Performance Considerations

Because traversing the component tree on every SSR request seems inefficient - this step should probably be done by Webpack at compile time.

@blocka
Copy link

blocka commented Aug 27, 2017

Seems this should be doable in "user land". Let's assume you're making a regular HTTP requests to a "REST-like" API.

You can make "smart components" with a global mixin, which looks for a given key on your component. At the same time it makes the request, it simply adds the request to array, and attaches that array to the SSRContext. Then you simply do Promise.all and you're done.

Moving to GraphQL, assuming you're using vue-apollo, it seems it already supports something like this with willPrefetch (check the docs)

@yyx990803
Copy link
Member

FYI this should be resolved by #9017. Closing to track in that PR.

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

3 participants