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

blitz console is slow to load - switch to esbuild loader #1098

Closed
flybayer opened this issue Sep 17, 2020 · 12 comments · Fixed by #3863
Closed

blitz console is slow to load - switch to esbuild loader #1098

flybayer opened this issue Sep 17, 2020 · 12 comments · Fixed by #3863

Comments

@flybayer
Copy link
Member

flybayer commented Sep 17, 2020

What is the problem?

Starting blitz console has a long hangup time after "Loading your Code" is finished and before you can start typing.

It gets much worse as you add more queries and mutations.

Steps to Reproduce

  1. blitz new myapp
  2. cd myapp
  3. blitz g resource project
  4. blitz g resource task
  5. blitz g resource comment
  6. blitz db migrate
  7. blitz console
  8. Try to start typing immediately once the > prompt appears. Notice that you can't type for a bit of time.

Other

The main problem is loadBlitz, which for some reason is super slow on first start. Running .reload after initial start (which re-runs loadBlitz) is quite fast.

You can add a log statement here and see how slow it is for each module.

We are already using a lazy require loader which apparently isn't working here.

Probably we need to add a proxy object for each dependency, that only loads the module when it's accessed. But maybe there's a better way.

Update April 2021

See #1098 (comment)

@flybayer flybayer added kind/bug Something isn't working status/ready-to-work-on This issue is up for grabs priority/high good second issue labels Sep 17, 2020
@JoseRFelix
Copy link

JoseRFelix commented Sep 25, 2020

Tried replicating this on Mac OS Catalina 10.15.6, but it worked without any perceivable delay.

Here is sc of the time taken for each module:

image

I know these times would vary between PCs and OS. Maybe it would be good to add a loading indicator when it is loading these modules. Let me know what you think @flybayer.

@flybayer
Copy link
Member Author

@JoseRFelix thanks for investigating! This is definitely WAY better in the latest blitz canary. That said, I'm still noticing a 1-3s delay on my project which has a good bit more modules than what you listed here.

I still think we should lazy load these, because as apps get bigger, this will get worse, no matter how optimized it is.

@JoseRFelix
Copy link

So, I've been thinking about some possible solutions:

  1. Have a loading indicator while all the modules are loading, and show input when done. This will make the user have to wait before he can use the console. It is not probably the best solution, but it is the fastest to develop.
  2. Have a command that lists the files' names of all available mutations, queries, jobs, integrations, and utils file names. Then, the user will require what he needs just like in javascript, using another command. This would solve the problem but it would increase the learning curve and have the user requiring the files every time.
  3. Read the user's input and try to import the files automatically with the same function name as provided in the input. In an ideal world, the user will name the function the same as the default export, otherwise, a wrong import would be made. Also, utils can house a file with several functions whose name won't share the file name.
  4. Require files by domain. The user with a command will be able to import all queries and mutations from a specific domain like tasks or projects.

In my opinion, I would prefer to have the first option since all modules will be available on the get-go.

@flybayer
Copy link
Member Author

Isn't it possible to keep what we have no (load everything), but set proxy objects in the repl context and when the proxy is accessed, load the requested module at that time.

So by default getProjects for example is set on the repl context just like now, but instead of having a references to the actual module, it's a proxy object that when accessed will load the module.

Make sense?

@JoseRFelix
Copy link

Yes, it is possible! The only thing to think about is how the script will know which file to import. This can work fine if we had the same file name and a single function per file. However, users can change the function name or have several functions that won't match the file name.

Maybe, we could store every function name and validate it in the proxy.

@flybayer
Copy link
Member Author

Yeah, but we have that same issue already, right? (you are right that we need to resolve that somehow)

@JoseRFelix
Copy link

I'd say it could be a little bit faster than our current approach since we wouldn't be doing a full import. However, we still would have read the file to get every function name and search our object if it contains the function.

@flybayer
Copy link
Member Author

Ok, if you want you can work on this and just figure out what makes the most sense to do.

@JoseRFelix
Copy link

Sure! 🚀

@blitzjs-bot blitzjs-bot bot added status/assigned and removed status/ready-to-work-on This issue is up for grabs labels Sep 29, 2020
@flybayer
Copy link
Member Author

flybayer commented Oct 2, 2020

@JoseRFelix I discovered that the console is quite fast when running the local blitz dev version, but it's still extremely slow when using off npm

@flybayer
Copy link
Member Author

flybayer commented Apr 20, 2021

So I think a good solution is to use esbuild. Perhaps with https://github.com/egoist/esbuild-register or https://github.com/folke/esbuild-runner.

I tried doing setting that up briefly. It certainly has potential but we need ability to provide custom esbuild options for things like setting externals. So we need to PR this ability to one of the above projects or use a custom fork.

Adding the "register" statement in our code is simple, same as we are currently doing with ts-node: https://github.com/blitz-js/blitz/blob/canary/packages/cli/src/utils/setup-ts-node.ts#L8

Note: one thing that's important is that this uses baseUrl and path aliases from both tsconfig.json and jsconfig.json

@flybayer flybayer changed the title blitz console is very slow to load - need to lazy load app code blitz console is slow to load - switch to esbuild loader Apr 20, 2021
@redbar0n
Copy link

redbar0n commented Jun 17, 2021

So I gather that these are examples of runners/watchers for development mode. For using a bit of esbuild to build in production, to get ~2x build speedup with NextJS, try esbuild-loader-examples.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants