This is part 2 of 'How does Ember Boot?'. If you haven't read 'How does Ember Boot?' part 1 you might consider reading it first.

In the last article our main focus was Ember.Application which is sort of static part of Ember boot process. Now we will look into didBecomeReady() and Ember.ApplicationInstance. Which deals with initialization and creation of instances. Ember.Application is called only once but Ember.ApplicationInstance can be n number of times based on number of requests for the instance.

In Ember each app instance maintains their own registry/container, so they will run in complete isolation by default.
Now that we know how _bootSync() works its time deal with this.didBecomeReady().

Ember.Application{
  //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
}

In didBecomeReady(), we check this.autoboot . It is used to check whether the application should automatically start routing and render templates to the rootElement on DOM ready. While default by true, other environments such as FastBoot or a testing harness can set this property to false and control the precise timing and behavior of the boot process.
FastBoot is the special environment that is usually used for Server-Side Rendering. This setup allows you to run your Ember app in a server environment using Node.js and render its content into static HTML for SEO purposes.

  • Autoboot

this.autoboot is also handy when we want to wait for some resource to fetch before the rendering process starts. Just as advanceReadiness() is used to control the routing , in the same way this.autoboot is used to control rendering.

  • Ember.ApplicationInstance initialization

Once this.autoboot is set to true the next thing that happens is this.buildInstance() . It is used to initialize Ember.ApplicationInstance . Unlike Ember.Application which run only once during the boot process, Ember.AppplicationInstance is created multiple times. Just as we have constructors which gets called every time we create an instance, in the same way Ember.ApplicationInstance gets called many times. It ensures that all the registries have been loaded and all the instance variables are initialized. They are created and destroyed on per request basis. So this is the place where we might want to keep the sensitive data associated with our application as it might get exposed if kept in registry and will be accessible to all the instances unnecessarily.

  • instance._bootSync()

Just like it Ember.Application , we have _bootSync() method to setup the instance of Ember.ApplicationInstance. It has following code:

Ember.ApplicationInstance{
  //other methods and variables
  
  _bootSync(){
    this.setupRegistry();
    //define root element
    //define location
    this.runInstanceIntializers(){
      if(isInteractive){
        this.setupEventDispatcher();
      }
    }
  }
  
  //other methods and variables
  
  startRouting() {
    let initialURL = get(this, 'initialURL');
    if (this.setupRouter()) {
      if (initialURL === undefined) {
        initialURL = get(this, 'location').getURL();
      }
      let initialTransition = this.handleURL(initialURL);
    }
  }
  
  //other methods and variables
}

this.setupRegistry() ensures that all the factories required by the instance is properly registered. If any of the required factories aren’t registered then it gets registered in this process.
this.runInstanceInitializers() is used to define root element and where the instance will be rendered. We can also specify what type of events to listen to detect navigation. Once the location of render and root element is known, instance initializers are used to initialize the instance.
isInteractive is a phase where the application is ready to listen to events mentioned in Event Delegation. If the application is still working on some fetching some resources its isInteractive is set to false thus no event dispatcher is working. When our application is ready to listen to events its isInteractive is set to true and event dispatcher is setup using setupEventDispatcher() . It sets up global event dispatcher which is capable of listening to all the events.
With this _bootSycn() is complete and the next thing that happens is routing.

  • startRouting()

Here, the routing of urls starts. The things that were set up for Routing during Ember.Application initialization is actually visible on the browser in this phase. Application is able to change the urls based on the application states (router.js).
It initializes the current router instance and sets up the change handling event listeners used by the instances location implementation. A property named initialURL will be used to determine the initial URL. If no value is found / will be used. On any state change, get(this, ‘location’).getURL() fetches the new url to which the browser needs to point and this.handleURL(initialURL) updates the url.

A copy of this article also exists on medium.com. To read it on medium click "How does Ember Boot?" .

That’s all folks, hope this made understanding of Ember boot better.
Thanks for reading.