Ideas For Faster Reloads

@jasongrishkoff What do you mean by properly? Can you describe in detail the changes you made? Thanks :slight_smile:

Sure, sorry for not explaining well enough before. The 30 second reload was most-frustrating to me when I’d change a minor thing like a SASS file or a line of Javascript. One problem was that my directory structure looked something like:

/ meteor
–/ functions
–/ sass
–/ front-end
–/ methods
–/ publish

Meteor seems to look for “client” and “server” folders, and treats chances in each differently. If you have a client folder, it only needs to refresh the client, and not rebuild the whole thing. So, my new setup looks more like:

/metor
–/client
–/client/sass
–/client/functions
–/client/front-end
–/server
–/server/methods
–/server/publish

Make sense?

2 Likes

You know that you can disable reloads, or disable reloads for a set of routes? We use this:

// Controlled by settings flag.
Meteor.startup(() => {
  if (Meteor.settings && Meteor.settings.public && Meteor.settings.public.DISABLE_AUTO_RELOAD) {
    Meteor._reload.onMigrate(() => [false]);
  }
});
8 Likes

Yes, thanks. Have you experimented with the Meteor Webpack by thereactivestack?

This point about separating client and server bundles to improve rebuild times was also suggested by a Qualia founder at his Meteor Night talk (starting around 9:30) - but now I’m confused because this question comes from a Qualia founder. Are the 20-30 second rebuilds there happening after adopting this strategy?

I have PC with a SSD & 16 GB ram… Moving from windows 10 to linux mint for dev. lowered the reload time from 30 to 3-5 seconds…

For large projects even when separating client and server code correctly rebuild times can still be slow. Our app uses the packages approach, where every feature is it’s own package, but am currently converting that over to the new 1.3 module approach, mainly so I can ditch the ecmascript package and try webpack. Running on a 2015 macbook pro I get ~25 second rebuild times. Converting to the module approach seems to have improved that down to ~19. Hoping webpack will improve that even further.

Edit: Because others are including the difference between server restarts and client refreshes - ours are both within 2 seconds of each other.

I gave the talk. This is indeed after applying those strategies (which did help significantly, and for a long time our rebuilds were a tolerable <10 seconds); we have a very large application with lots and lots of front-end code. I really feel deep in my bones that for 95% of code changes the reload times could be 1-3 seconds. Most changes are only modifying one source file, and if we directly modify the bundle, invalidate the cache, and reload… it should be really fast! I don’t think this is a deep structural issue with Meteor. Take a look at (I think this is the correct path…):

.meteor/local/build/programs/web.browser/{name_of_folder}/{name_of_folder}.js.

If you directly modify that file and do a hard reload (so you don’t get the cached version) on the client the changes show up instantly. Magic! Sure source maps are busted, but I think that’s fixable (and tbh I would be happy to temporarily enable/disable source maps for 1-3 second reloads).

Our 20-30 second reloads are only for full client+server reloads. Client-only is ~15 seconds and server-only is ~12 seconds. But unfortunately much of the code which changes the most frequently must run on both the client and the server, so we frequently get ~20-30 seconds.

I think for that most small-medium sized projects the optimizations that I mention in my talk will get people tolerable (if not optimal) reload times. And… if other people want to pitch in with me, I think we could get lightning fast reloads without anyone having to change the structure of their code (refactoring our codebase to work with Webpack would be… challenging to say the least).

Currently it’s costing about 97 cents every time I hit save and need to wait for the refresh. This is insane.

On average i’ve dropped clienside reloads from 50 (v 1.3.x) seconds to 0.7 - 1.5 seconds depending on the source map quality. Essentially you just need to cut out the slow parts of Meteor. With Apollo support becoming the norm this makes things easy. Just skip the Meteor bundle for the client all together.

With React, Apollo, and Redux you really dont even need the meteor bundle at all. Logins can be configured with the simple-rest packages (or even passport if you want flexible auth). This essentially turns Meteor into Express with Atmosphere support and fibers (which may go away for async await anyway).

8 Likes

I think that this is probably the way to go, but for people who have existing projects in Meteor or who want the functionality that Meteor classic supports, this is not an option (AFAIK). Do you know of any way of adapting existing projects to Webpack without massive refactoring?

this #needsmoreattentionfrom @everyone

1 Like

100% agree. Here is the issue that is one of the most commented but there’s been no response of MDG that at this point seems not to care too much/at all.

I’ve spend a lot of time experimenting with webpack/webpack (and here is a backbone project that showcase the result of my experiments) Happy to answer questions you may have on that.

I found it great at the beginning but it ended up eating quite a lot of my time still. And there are issues that are quite serious for productions apps. The one blocking me from using it is https://github.com/thereactivestack/meteor-webpack/issues/213 (related to script caching) And there are other drawbacks like not having meteor shell among others, or it being a package not super actively maintained since its core contributor has another job and life :slight_smile:
I think this package goes 100% in the right direction that is that webpack is an amazing build tool and it makes sense that Meteor would use it instead of its in house bundler. This approach is eating MDG bandwidth or suffering from lack of support/efficient results because MDG is busy doing other cool things.

As a more useful piece of advice, I’d reiterate on the fact that it’s very important to have all the client only files under **/client/** and server only files under **/server/** since this will reduce the number of files Meteor uselessly looks at while rebuilding , and will not trigger server rebuild when you’re only modifying a client file for instance.
Of course, this is not compatible with server side rendering that requires the client files to be accessible from the server. So I ended up enabling server side rendering in production only, and having a script that moves ./client to ./app when pushing in production. Yeah this got me crazy…

Finally, if server and client are well separated, gadicc’s package does a very good job at live reloading React components on file change. But I think that you’re on Blaze at Qualia right @veered ?

I strongly agree that there’s no need for a large rebuild when you know which file has been changed and the current approach sounds particularly inefficient, especially since it’s going through tons of npm code that we dont need to rebuild live. But that would require MDG paying attention to this issue that has been killing developers productivity for a while…

1 Like

Yep, we’re using Blaze and we also haven’t migrated most of our application to use ES6 modules yet.

Honestly if you’re using Webpack, Redux, Apollo, and separating your client and server code (which kinda goes against the whole point of using Meteor in the first place), then I don’t know if you can still call that a Meteor app anymore.

Don’t get me wrong, I think this is the right approach if you can adopt it, but it’s just not a very practical solution for most Meteor codebases.

10 Likes

I second that. Cool if you’re starting from scratch. Not at all practical when you have a huge amount of legacy code.

@veered totally feel your pain on this one.

Speaking to people about it, getting webpack-style incremental build times is probably not possible without a major rewrite of the build tool, principally for the reason that webpack doesn’t write/serve from disk, it instead keeps everything in memory (i.e. there is no .meteor/local/build equivalent).

I have thought a bit about the “fast past for single file change” idea. I asked people who know more about the build tool than I do about it and they didn’t raise any obvious objections to it. It would be a far reaching change though, so not a simple project.

If you are interested in working on this, perhaps we can coordinate on a GitHub issue?

7 Likes

I am definitely interested in working on this (as a collaboration)! And I bet you that a lot of other people are as well; this is a really big deal.

1 Like

I’d be interested as well :slight_smile:

2 Likes

I totally agree. Although i’m not really sure what a Meteor app is these days.

It’s also do-able for current apps but takes some thought to migrate the yourapp/client folder and into webpack. If you have ES6 imports it’s really not that bad. Though to be honest the time spent migrating will likely be more than the time wasted on reloads (took me a good solid weekend to migrate one with a few hundred files).

1 Like

Would you mind writing a short tutorial on how would you migrate from existing project? My app is React + Redux + Apollo so it definitely fits to the category you mention. I’m very much intrigued!

How would you see Galaxy deploys there? Would that still be a Meteor app?