I will be showing the steps Ember takes to startup before you start seeing your page rendered in the browser. There is a lot of steps and packages involved in this process but I'll try to make it as simple and compact as possible. Following snippet shows the steps in brief which I will be explaining in detail as we proceed.

Ember has evolved from being the SproutCore 2.0 framework to a modern trusted Javascript framework used by major tech companies like Apple, LinkedIn and Vine, ever since it was born. It was developed by a Rails developer Yehuda Katz, so it believes in Convention over Configuration. Ember community not only is very supportive but also follows six-week release cycle ensuring security and features which keep making it best framework to consider. It tries to stay as much backward compatible as it can so that with every new major release you don’t have to waste a lot of time learning new ground breaking things and syntax.

I was working on my Ember project and it was taking a lot of time to boot which wasn’t a usual thing and before digging for its cause, this question hit me “How does Ember boot ?”. Though the reason for this extra time was a debugger on my API. It was enlightening to know how did ember boot.

I did some research, mainly looking at Ember git repository to find my answers. Knowing the Ember boot process, not only made my roots strong but also changed the way I looked at it.

It is beyond the scope of any article to cover the whole Ember boot process, to do that there needs to be a book but I can definitely brief things that made sense to me and were important mentioning. So let's start …

The first thing that happens when you start any Ember application is the creation of Ember.Application instance, which is done by
window.App = Ember.Application.create();
The object that holds this instance is a global object and is created only once. Any method or variables in this class have global namespace as Ember.Application. While you can think of your Ember.Application as a container that holds the other classes in your application, there are several other responsibilities going on under-the-hood like Initialization, Event Delegation, and Routing.

The first method that is called when the instance is created is _bootSync() . It is called when domReady() is fired which happens after all the resources required for Ember to execute is downloaded and parsed.

Following code lists all the methods involved in Ember.Application boot process.

Ember.Application{
  //other methods and variables
  ....
  _bootSync(){
    this.runInitializers();
    this.advanceReadiness(){
      this.didBecomeReady();
    }
  }
  ....
  //other methods and variables
  ....
  didBecomeReady(){
    if(this.autoboot){
    //instantiate Ember.ApplicationInstance
      let instance = this.buildInstance();
      instance._bootSync();
      intance.startRouting();
      //or instance.handleURL(url)
    }
  }
  ....
  //other methods and variables
}

Ember.Application has following responsibilities :

  1. Initialization
    The goal of initializers is to register dependencies and injections. They provide access to the internal registry, which organizes the different components of an Ember application.Additionally they provide a chance to access the instantiated application.
    It runs only once. Because these initializers may load code, they are allowed to defer application readiness and advance it. When some asynchronous task needs to be performed before some initializer then deferReadiness() can be used which is used to control advanceReadiness() which is called only if deferReadiness() counter is set to zero. When we call deferReadiness(),the counter is set to decremented and becomes -1. Routing halts till deferReadiness() counter become zero. Once the asynchronous task finishes execution it, makes counter increment by 1 and if counter =0 then advanceReadiness() is called.
    It is possible to add custom initializers on top of Ember , like so:

    Ember.Application.initializer({
    name: ‘api-adapter’,
    initialize: function(application) {
    application.register(‘api-adapter:main’, ApiAdapter);
    }
    });

  2. Event Delegation
    Ember uses a technique called event delegation. This allows the framework to set up a global, shared event listener instead of requiring each view to do it manually.
    For example, instead of each view registering its own mousedown listener on its associated element, Ember sets up a mousedown listener on the . If a mousedown event occurs, Ember will look at the target of the event and start walking up the DOM node tree, finding corresponding views and invoking their mouseDown method as it goes.
    Ember.Application has a number of default events that it listens for, as well as a mapping from lowercase events to camel-cased view method names. For example, the keypress event causes the keyPress method on the view to be called, the dblclick event causes doubleClick to be called, and so on.
    If there is a bubbling browser event that Ember does not listen for by default, you can specify custom events and their corresponding view method names by setting the application’s customEvents property:

    let App = Ember.Application.create({
    customEvents: {
    // add support for the paste event
    paste: 'paste'
    }
    });

To prevent Ember from setting up a listener for a default event, specify the event name with a null value in the customEvents property:

let App = Ember.Application.create({
    customEvents: {
      // prevent listeners for mouseenter/mouseleave events
      mouseenter: null,
      mouseleave: null
    }
});

By default, the application sets up these event listeners on the document body. However, in cases where you are embedding an Ember application inside an existing page, you may want it to set up the listeners on an element inside the body.
For example, if only events inside a DOM element with the ID of ember-app should be delegated, set your application’s rootElement property:

let App = Ember.Application.create({
    rootElement: '#ember-app'
});

The rootElement can be either a DOM element or a jQuery-compatible selector string. The Ember.EventDispatcher is responsible for delegating events to application’s views. The event dispatcher is created by the application at initialization time and sets up event listeners on the DOM element described by the application’s rootElement property.
Note that views appended to the DOM outside the root element will not receive events. If you specify a custom root element, make sure you only append views inside it!

  1. Routing
    Ember.Application not only creates your application routers but it also controls routing. By default, the router will begin trying to translate the current URL into application state once the browser emits the DOMContentReady event. If you need to defer routing, you can call the application’s deferReadiness() method. Once routing can begin, call the advanceReadiness() method. If there is any setup required before routing begins, you can implement a ready() method on your app that will be invoked immediately before routing begins.
    These are the major tasks performed by Ember.Application initialization.
    Once this is done and our application is in advanceReadiness() state , the next method which is called is didBecomeReady() . This leads us to next important thing which is Ember.ApplicationInstance initialization.

You can also read this on medium.com

In part 2 of Ember Boot I will dive deep into didBecomeReady()' and Ember.ApplicationInstance'. Stay tuned.