Should I stop using Meteor for part of my application?


#1

I’ve spent the last 1 year learning and prototyping my app in meteor. Similar to this article https://mixmax.com/blog/scaling-mixmax-front-end , I’m experiencing exactly what they are experiencing with Meteor.

Which is that it helps you prototype your app fast, this is often when you don’t consider things like performance when they aren’t so crucial to your application. However now that my prototype is ready and customers are using it, I’m finding that certain critical pages which should be loading fast are taking 8 seconds to render which I would say is unacceptable. On mobile devices that are a bit older, it can take up to 20+ seconds to process and render which is defintely unacceptable. This is a big concern especially when majority of my users will be coming on mobile devices.

I’m starting to feel that Meteor really only suits that admin dashboard for my application which clients can edit and manage all thier info and orders. All this is used to setup and manage the clients e-commerce store but generated site doesn’t need half of the features meteor brings to the table. I could use Angular or React and serve off a express server which would probably be way faster. How ever now that I’ve come this far I don’t want to try port everything over unless necessary.

Is there some way around this, right now SSR with react on meteor seems shaky, correct me if I’m wrong. Do you think it would just be better to use express instead of meteor for the client generated site?

The other headaches that come with not using meteor and galaxy hosting is now worrying about SSL’s via lets encrypt, load balancing, zero-down time deployments and so much more which is also making this decision hard.


#2

I really don’t know what to say here, except to be (perhaps unacceptably) blunt.

You do not use a prototype on your customers unless they know they are doing it purely to help in identifying issues. Your prototype helps you to understand the technology and refine the architectural design (how to address requirements through data, code and presentation). It sound like your prototype is now delivering real technical value by helping you understand where your coding and/or data architecture needs work.

Meteor (currently) downloads the entire application bundle up front. Once that’s out of the way, your pages will be rendered as efficiently as you have coded them. Rendering a page in 8-20 seconds certainly does not sound good, but maybe you should be looking at the relationships between your problem, data and code. For example, if you don’t need reactivity for some areas of your application why are you using it? You wouldn’t try to engineer livedata into an express application, so don’t use it in Meteor where it’s not necessary. That’s an example - I don’t know whether you’re using livedata or not.

It’s all too easy to blame the technology for poor design - especially when we’re talking about Meteor, which possibly makes it too easy to build a web application.

Finally, I don’t know anything about your application - it may be that Meteor is not the right choice - but can you categorically state that your design is as good as it can possibly be with Meteor?


#3

Hard to say before seeing your app and architecture. What do you have in that part of the application that loads for 8 seconds? That sounds like very long time. I know that Meteor can be much more taxating compared to some other frameworks when you take into account all Javascript code and websocket connection, but I’m wondering if you actually have things there that could be optimized like assets and code that could be optimized (or maybe you’d need to move to faster servers, move your database server to same private network etc…)

My personal experience when moving to production was that page load was around 6 seconds on first load (and also pretty much same on loads after that as meteor normally does not cache files). After moving to CDN and enabling caching on certain of my files in meteor public folder, serving my javascript / css code from CDN with ability for user to cache the files and moving to faster server (meteor server on same datacenter as my database for reduced connection time between those two) I got my initial page load speed to 1.9s (from 5s). This could however be faster as the datacenter is located in US and I am in Europe. Probably even faster on US. Application also works pretty quickly now that everything is nicely cached, so no need to reload assets when changing pages.


#4

No matter what technology stack you choose, it is extremely common to have performance problems once the system is put into production. This is basically built in to the most common development process: the priority early on is feature development and user experience, without any effort to understand what happens at scale. Part of the reason for this is that it is much easier to understand and solve feature development and user experience problems early on, and much harder to understand and accurately simulate problems at scale (not impossible, just harder).

You are actually in a great situation now, because it is no longer necessary to simulate problems at scale; you are actually experiencing them. That means it should be relatively easy to figure out the most important contributors to your performance problems by using a system like Kadira. It could be page reloads, it could be database lookups, it could be re-rendering, it could be other things that you would never suspect to be a problem, but the good news is that you should be able to monitor your application and track them down.

Once you do that, you can make an informed decision about whether to move away from Meteor.


#5

Thumbs up for Kadira, that has been my #1 tool for figuring out which methods are bottleneck in my system.


#6

Thank you for your thoughtful response rob, I’ve spent a lot of time trying to understand how Meteor works and how to better optimize it. I’ve done what you’ve suggested already including disabling reactivity in parts that are not needed. I’ve been very careful about how I code to make sure I’m not introducing unnecessary inefficiencies, using javascript over jquery where possible, I’ve already split my application into multiple smaller apps, I’ve got Kadira performance monitoring running to see where my bottle necks are. I’ve genuinely tried to do a lot to optimize the app.

But as you said theres no getting around downloading the intial meteor package. This seems to be what causes the real hiccup in load times along with the page rendering and then pulling the data as opposed to the data being send down directly with the template (i know fast render can do that but it also causes some issues).

Also, you are indeed correct, my prototype has now finally settled into a point where its providing real value for customers and the final base architecture that we want to build on has been nearly achieved.

I don’t want to come across as bashing meteor, I think its fantastic for certain applications and I love the work the team has done.


#7

Have you tried opening up the Chrome performance tools and seeing what is taking so long? 8 seconds is pretty unreasonable, so there must be something going on. I really doubt it’s a problem in Meteor.


#8

That actually sounds really good. I’ve done most of that already, moving off all static assets to a CDN. After using chrome timeline quite a bit, the load time seems to be an initial about 1-2 seconds for meteor to bootup, then getting the data takes about 3 seconds and processing the data and rendering it takes about another 3 seconds.

The initial round trip to load the meteor application and get the data is killing me. The data needs to be sent down with the inital template because it doesnt need to be reactive here. I understand fast render can do this but its causing me other issues which is why i decided to stop using it. Ideally if the data was sent down at the start that would save lots of time.

Next up is the 3 seconds for processing, which made up of lots of data transformation and also generating a custom stylesheet that is resonably sized. Ideally this could be done on the server a well. Not on the client which would save quite a bit of time.

I know the solutions but the issue is I’m struggling to implement the solutions properly with meteor. I think if Meteor has proper SSR support, lots of these concerns would be alleivated.


#9

You’re absolutely right its not “Meteor’s” problem necessarly, I’ve used chromes performance tools to see whats happening, its mainly the round-trip of data where my app is loading up and then once it loads now it needs to fetch the data. I understand fast render solves this but its implementation is causing many issues for me. Then is the issue that I’m doing quite a bit of processing with the data before the view is displayed. Ideally this can be done on the server before sending the data to the client.

Unforunately, the data needs to be dynimcally generated as part of it is dependent on the users request headers.

I geuss it’s more so that this part of my application is probably not a good use case for meteor given its requirements


#10

I hope you don’t write off the platform that quickly (meteor)

We have an app that dynamically builds the branding, probably 100 collections, thousands of fields/schemas all from customized code per tenant, configurations stored in MongoDB. It builds everything and launches in 1-2 seconds, and that is not even optimized. There are a several optimizations/tricks with meteor that you have to be aware of to take advantage of the power. Hopefully we can assist in resolving if you need assistance.


#11

Hey, I really appreciate everyones willingness to help. My application doesn’t sound nearly as complex as what others have done. I’ve decided to share more about my app to get some better feedback. Truth be told I’m probably doing a lot wrong even though I don’t realise it. You can have a look at my demo store here. Essentially users can create their on online ordering system for their restaurants, heres a demo store created by my system. www.thebestexample.xyz . My app works really well for the most part, it’s just the store pages are loading so slowly especially on my mobile which takes 20 seconds to load it with cache cleared.

Here’s what I’ve done / tried so far.

-Split the app into smaller apps, the entire store app simply just looks at what domain a user is coming to it from and see’s if there is a restaurant stored for that domain or subdomin value and then renders that store if there is one available. There are only a few template files and a few JS files, the overall store app is actually very small.

-Disbaled reacitvity as its not necessary.

-Currently the data is just being gotten by a method that runs after seeing what the domain is in the users request headers. I can use a pub and sub but I’m not seeing any reason to, I’ve tried it and it doesn’t seem any faster.

-I tried to add fast render but it always throws this error no matter how I configure it and ends up crashing my server so I’ve just given up on it. I’ve tried configuring my access control allow origin value using the webapp package but it aint working.

TypeError: Cannot read property 'access-control-allow-origin' of null
ztpm
2016-12-03 07:08:40+08:00 at ServerResponse.res.write (packages/meteorhacks_inject-data.js:108:22)
ztpm
2016-12-03 07:08:40+08:00 at ServerResponse.OutgoingMessage.end (_http_outgoing.js:588:10)
ztpm
2016-12-03 07:08:40+08:00 at /app/bundle/programs/server/npm/node_modules/meteor/dfischer_prerenderio/node_modules/prerender-node/index.js:29:20
ztpm
2016-12-03 07:08:40+08:00 at Gunzip.<anonymous> (/app/bundle/programs/server/npm/node_modules/meteor/dfischer_prerenderio/node_modules/prerender-node/index.js:201:5)
ztpm
2016-12-03 07:08:40+08:00 at emitNone (events.js:72:20)
ztpm
2016-12-03 07:08:40+08:00 at Gunzip.emit (events.js:166:7)
ztpm
2016-12-03 07:08:40+08:00 at endReadableNT (_stream_readable.js:921:12)
ztpm
2016-12-03 07:08:40+08:00 at nextTickCallbackWith2Args (node.js:442:9)
ztpm
2016-12-03 07:08:40+08:00 at process._tickCallback (node.js:356:17)`Preformatted text`

-Images are being served from amazon S3 and progressively loaded with base64 versions coming in first

-Admittedly there is about 1 second of probable fade transition happening in the total load time which can be unnecessary

-Currently hosted using galaxy

To help get the timing of when things are happening, when the loading spinner comes initially is when the initial template is rendered. Then when the loading background changes color is when the data is loaded and the new css is applied and finally the page displays once the menus are calculated based on the customers timings and a few other tasks happen.

I might be misunderstanding some concepts so if I am, please do correct me.

I hope that gives everyone something to go off. I’d love to hear any suggestions


#12

Thanks, reviewing now…


#13

why not just use Shopify?


#14

Well, I’m building a saas online ordering system for restaurants. My primary reason for picking Meteor was that I needed the admin dashboard for restaurants to work in real-time as restaurant owners will be setting up their tablets or computers in-store to receive orders placed online via their generated online-store. They can’t be sitting by the device refreshing the page, it’s just gotta show new orders as they come through so they can view it on the fly. Why would someone use my product instead of shopify? Our business is specific to the food industry so there are many features that these businesses need that traditional e-commerce solutions like shopify don’t provide.


#15

That demo site was up and rendered for me in well under 5 seconds on a clear cache in China. Nice work, by the way!


#16

Thanks, glad to hear it worked fast for you! Desktops don’t seem to have a problem with it. It’s mainly mobile phones which struggle. My cousins iPhone 7 takes about 10-13 seconds. I think a large part of that is the client-side processing of the data, most notably the styles. Ideally all this should be moved to the server espically since none of it needs to be reactive really. That way phones don’t need to work everything out before displaying the site,


#17

Are you using cloudfront in front of your static assets? URLs seem to be s3 instead of cloudfront. If you are just using s3, I would recommend serving your S3 assets through cloudfront for much better performance (and cheaper pricing). You could also serve your meteor cs & jss file from cloudfront for improved speed (you need to enable CDN support in Meteor for that).

Are you using compact galaxy container? Is your database hosted in same datacenter? It looks like that in 2.3 seconds most things are loaded, meteor css/ js is loaded etc. Then loading pauses for around 3 seconds and after that it continues loading assets and renders the page after that. The final load time is around 8-9 seconds until everything is loaded but the initial DOM load is there in 2 seconds. How much is the load time in your local environment and how does the chrome timeline differ in production and development environment for you?

It also feels to be like your loading screen is there until the whole page is loaded, maybe you could try experimenting on removing the loading screen before and keep loading assets for the user to make it seem like the site is already loaded. That loading screen is also pretty obstructive, you could render your page template there and render static loading blocks where content gets loaded as it’s done (something to make the page seem to load snappier even though it would take few seconds).

Just some random notes here and there… :slight_smile:


#18

Nice work, I like the concept, it loaded under 5 seconds for me on a desktop machine. I enjoyed the front-end design and I’m wondering did you custom made this or you used some front library like bootstrap etc.?


#19

Fantastic notes I might add, I’ll definitely try what you suggested. I think the CDN will defininitely help. My app is running off a compact galaxy container and the db is located in the same region using mongolab. The app loads much faster during development, even when using a remote database instead of a local one.

I agree with you on the loading, I should render the basic layout without the loading icon and then fade the data in on top of that, That should give a much faster loading feel. I am waiting till the whole page is loaded which is probably a bad idea. I think if I do that, that should provide a decent improvement,

Thanks for the suggestions!


#20

Thanks, good to hear its fast on yours as well, it works great on most desktops. The design is custom made, framework feels way too bloated for this, I personally prefer just writing my own css.