Dynamically loading an Ember component

Is there a way to lazy-load individual Ember components in my application?

I would like to exclude components from the original build and lazy-load them later as needed. I investigated Ember Engines, but it doesn’t seem suitable, as lazy-loading does not work with route-less engines. As I understand it, each of my components would have to be an individual engine, and then tied to a route in order to lazy-load.

Is there some alternative to this? I don’t want my components bundled up with broccoli, but loaded dynamically.

4 Likes

+1 - I also had been looking for this for a while. Can be easily achieved in React though.

I haven’t followed the latest development, but I would suggest to take a look into embroider, which should let you split your app based on routes. Personally, I haven’t been able to try it out so far, though.

ok. what about lazyloading with components? lets say I have 1000 components and on particular route i want just 4 componenes, so loading all 1000 component’s code on that route is inefficient.

We need lazyloading with both

  1. routes (seems like can be achieved via ember-engine or embroider)
  2. components

Is there any work/plugin available for components lazy loading?

You would be writing 1000 different components? may I ask why? Probably you can find a better to abstract things?

Just in case, you would be writing only a few components and reusing them for 1000 different data sets, lazy loading the components will not be of much help, as your are not going to load 1000 component anyway. You just will be rendering 1000 components. But I don’t think I would suggest to do something like that, because these days a lot of browsers detect pages that use extensive memory and show a warning or just close/reload the page without any prior notice (iOS is often pretty aggressive in that matter). And you will likely have a really hard time with low cost mobile devices.

Thanks for details @Hummingbird.

I just gave an example. My point is to don’t load the javascript/html which is not used on a particular route.

Components are also some code which gets compiled to one app.js, this app.js will keep increasing size as we create new components, so this will increase app size.

For mobiles as well, if our main app.js is minimum, it will be good experience on mobile as well.

I wish that our main app.js size never increases as we write more code. so first time someone loads app that should be pretty light and then as app is loaded it can load other required chunks.

Right now what code we right i.e routes+models+components, all that is compiled to one js file, which means this will always increase all the times irrespective of what is actually used etc.

Well, I don’t want to say too many things I am not certain of, but if you are able to separate your index route from all the other routes using embroider, that would likely make things work the way you want them to be.

However… Are you sure this really is your biggest issue performance wise? I have optimised a ton of things way too early myself, and it often turned out that I had put a lot of work into optimising things that in the end turn out to be unnecessary and just make things more complex.

@Hummingbird what you say makes sense and I agree with you. I was just trying to know whats the best. At early stages sometimes we ignore such things and later it bites and takes huge effort to fix it. But this can also lead to doing unnecessary things.

I will see how embroider works. Obviously i am not looking to find answer for performance at cost of complexity. I am just trying to explore if ember comes in default with those optimizations and I don’t have to manually configure myself.

I had been working on React projects as well and from React we used to optimize this thing from start where at component level we decide whether this will be lazyloaded or eagerloaded.

I have learnt alot of things so far by raising this question.

@Hummingbird I really appreciate your input, thanks for your help :slight_smile:

Agreed. In the pre-embroider world, package size definitely is an issue. I am using FastBoot as well, and the last time I tried embroider, it was not fastboot ready yet. So, I unfortunately can’t tell how things will go.

I think I have spent more time removing the consequences of premature optimisation than what it took to add stuff that I neglected earlier. Sure, there always is the thought: “I should have done this from the beginning”. But you only can do so many things when learning something new and you can migrate a lot of things bit by bit.

I don’t think there currently is anything which will let you lazy load components (but maybe I just haven’t heard about it). I faced that situation a few times in the past, but often lazy loading js dependencies using auto-import was good enough. Actually, usually all the js dependencies have been much more of an issue than the size of the components themselves.

1 Like