Graphql-playground: Animating the first loading screen

Created on 23 Nov 2017  ยท  10Comments  ยท  Source: graphql/graphql-playground

What's up?

๐Ÿ‘‹ hey there!

Awesome job on the playground folks, this is awesome!!

I've come up with a new loading flow for the Playground, thanks @schickling & @julianbauer for the design reviews! ๐ŸŽฉ

It has been made with care to:

  • not add new dependencies to the project by using CSS animations with React & styled-components;
  • rendering well on all major browsers, there were some good challenges here! I didn't test Edge if someone can tell me how it looks? See link to the prototype below ๐Ÿ˜‡

Current state

Before opening a PR to potentially integrate it to the codebase, I'd like to see with you what should be done.

It appears that the approximately same loading screen has 3 different implementations at the moment:

  • a static React component on the web app (source)
  • an animated React component on the electron app, not used at the moment (source)
  • a static HTML landing repeated 5 times across the middleware as render-playground-page.ts ๐Ÿ˜„ (screenshot)

So...?

Should a PR about the Loading component be targeted only at the web app or include the other packages?

If it should include the other packages:

  • does the electron app need a Loading component? It doesn't rely on a loading state at the moment and uses directly the Playground component, not App.
  • should all render-playground-page.ts pages be unified somehow? if yes, should this page use an already bundled component to avoid loading react & react-dom from a cdn like graphiql?

Voilร , I'd love to help on that, and even other things! โœ‹

Prototype: https://codepen.io/xavcz/pen/bYReeM/left?editors=0010

screencast of the prototype

Most helpful comment

Yay, thanks @timsuchanek: excellent explanation of the whole thing, it makes a lot of sense! ๐Ÿ‘Œ

Agree with you! Let's implement the animation in the most straightforward way for the most efficiency: loader implemented in pure html/css/svg ๐Ÿš€

But it would be nice if the loading screen is still there while loading and initializing the schema.

Yeah definitely, I believe we can get rid of the Loading component, and get React (= the Playground component when mounted?) to communicate with the node where the HTML loader is hosted.

Thus we could avoid this behavior: HTML Loader -> React Loader -> Playground

ex

We should add a package graphql-playground-middleware that includes the render-playground-page.ts and is being required by the other packages.

Let's go for all that, I'll work on a PR!

All 10 comments

This is absolutely amazing @xavcz! Great work on the details. The last iteration has really improved it a lot!

does the electron app need a Loading component? It doesn't rely on a loading state at the moment and uses directly the Playground component, not App.

No, the loading component is just needed for the web version

should all render-playground-page.ts pages be unified somehow? if yes, should this page use an already bundled component to avoid loading react & react-dom from a cdn like graphiql?

@timsuchanek that's a question for you! :)

Hey @xavcz, thanks for this awesome work so far!
You correctly uncovered a big mess in the current loading components :D
I think the main use-case besides being an electron App for the Playground is being used as a middleware.

Then we have to understand, where the loading time is actually spent:

  1. Loading the js assets / starting React
  2. Loading the schema

Mostly time is spent on loading the assets.
But it would be nice if the loading screen is still there while loading and initializing the schema.
2 solutions to this: 1. only render when the schema is loader, this approach is implemented in apollo-client/server for server-side rendering. 2. first render the animation with html/css/svg only (everything served in the index.html), then continue with a React-based approach.

If the loader is implemented with styled-components, showing the loader before having the assets will be hard.
Because without having react ready, we can't render the styled components.
I currently see 2 ways to handle this:

  1. Use code splitting, send only what is needed for showing the animation
  2. Implementing the animation with pure html/css/svg
    I currently favor 2., because it's faster (we only send what is absolutely needed) and splitting code complicates the build process, that can be a huge time sink if it's broken.
    Implementing the html/css/svg only version, however, takes more time to implement.

We may want to load React + styled-components via cdn, that could also speed it up.

Regarding the loader mess: We should only have one place where this is implemented.
We should add a package graphql-playground-middleware that includes the render-playground-page.ts and is being required by the other packages.

What are your thoughts on this?

Looking forward to awesome animations :)

Yay, thanks @timsuchanek: excellent explanation of the whole thing, it makes a lot of sense! ๐Ÿ‘Œ

Agree with you! Let's implement the animation in the most straightforward way for the most efficiency: loader implemented in pure html/css/svg ๐Ÿš€

But it would be nice if the loading screen is still there while loading and initializing the schema.

Yeah definitely, I believe we can get rid of the Loading component, and get React (= the Playground component when mounted?) to communicate with the node where the HTML loader is hosted.

Thus we could avoid this behavior: HTML Loader -> React Loader -> Playground

ex

We should add a package graphql-playground-middleware that includes the render-playground-page.ts and is being required by the other packages.

Let's go for all that, I'll work on a PR!

We should add a package graphql-playground-middleware

What do you mean @timsuchanek?

Heads up, the _fancy_ part of the animation, dots scaling & lines drawing, is too long to actually be seen compared to the time to load the JS! (over-engineering? ๐Ÿ˜…)

Here is another GIF, ๐Ÿค“
meh

I got this working with static html/css/svg rendered from render-playground-page.ts. That's a good solution so far!

The goal is to have a good experience, without having users to wait too long: I'll get rid of the fancy part and spread over time a short period of time the apparition of the text, rectangle & graphql logo.

We should add a package graphql-playground-middleware

As far as I understand, an export of the render-playground-page.ts file that can be re-used by Express, Koa & cie, so it's just one file to maintain instead of 4 ๐Ÿ™‚

It could may be reused as the webapp html entrypoint too, somehow? ๐Ÿค”

@xavcz note that loading these resources over the internet takes quite a bit longer, so the loading times should be "bad enough" (we could even think of deactivating the loader for localhost).

Otherwise, I would slow the loading down in favor of the animation ๐Ÿ˜„ Form before function ๐Ÿ˜‰

@xavcz can you provide a demo link for the PR so we can try it out already?

So here is the PR https://github.com/graphcool/graphql-playground/pull/281 ๐Ÿ‘

For a demo link, I'm having trouble to test. Let's say I want to deploy the basic example of the Express middleware. The deploy will reach NPM to get the middleware, not my local build with "linked" dependencies.

How would you do? I'm genuinely interested in the process you are using to test such things!

Yeah, this is in general a tricky topic. Here are two (hacky) ways how you could handle this (maybe someone knows a better method?):

  1. Publish your fork on NPM as @xavcz/graphql-playground
  2. Deploy your local setup to AWS Lambda via Serverless (which uploads your actual node_modules)
Was this page helpful?
0 / 5 - 0 ratings