Methods of presenting an SPA container

In a Single Page Application, the container is the object in which the application is initially loaded and displayed to the user. This concept is different from that of a software container, which is an isolated environment that an application lives in, much like a virtual machine.

For a single page web application, the container could be the <body> element, or any element within the <body> element. For instance, you may have some static welcome text initially loaded on the page in a <p> element, and the SPA will then load dynamically below that element in a <div> element:

<!doctype html> 
<html> 
    <body> 
        <p>This is some welcome text.</p> 
        <div class="container"> 
            The application will be loaded here. 
        </div> 
    </body> 
</html> 

In a scenario like this, you will always have some fixed content on the page that doesn't need to change based on the user's interaction with the application. This is just a simple example, but the same could be done for a common <header>, <footer>, and <nav> element:

<!doctype html> 
<html> 
    <body> 
        <header>Static header content</header> 
        <div class="container"> 
            The application will be loaded here. 
        </div> 
        <footer>Static footer content</footer> 
    </body> 
</html> 

How to define your SPA container

There is no right way to define your SPA container; it really just depends on the type of application you are building and what your preference is. It can also depend on the server-side limitations of the system you are using to serve your layout - the HTML page used to house your app.

Partial page container

As shown in previous sections, you may want to show some static content in your SPA layout before the application loads. This is useful when you anticipate a long initial load time for an app, or if you require some user interaction to trigger the loading of your app.

Full page container

If your application can be completely controlled through API endpoints accessed by XMLHttpRequest, commonly known as Asynchronous JavaScript and XML (AJAX), then there is no need to load any static content in your SPA layout unless you want to. One reason you may load static content in your layout is to have something for the user to view or read while they are waiting for the application to load. This can be particularly useful when you anticipate long initial load times for your app and you want to help deter a user from leaving before the application's initial state is ready.

A state in a SPA refers to a particular version of the Document Object Model (DOM), at any point in time. A loading state is one you might show within your container element while waiting for it to load the next requested state. A loading indicator of some sort is often enough to let the user know that something is happening and the application will load soon, but when you have any excessive latency in your app, a user may think something has gone wrong and leave the app layout page before the process completes.

How to load your SPA container

The way you initially load your SPA is highly dependent upon the nature of your application. There could be any number of requirements that must be fulfilled before your app can be loaded.

Loading on user interaction

Many web applications require some type of user interaction before the full SPA is loaded. For example:

  • User authentication
  • User acceptance of an agreement to enter
  • Interstitial content that must be shown and either engaged or dismissed by the user, such as an advertisement

Scenarios like these are quite common in web applications, and they can often be challenging to solve in a fluid manner.

Login page transition

In many web applications, the login screen is loaded on a secure page and submitted using HTTP POST to another secure page to authenticate the user and load the actual SPA. This pattern is generally used due to limitations in the server-side framework that is being used to handle authentication.

If you think about a financial application for accessing your bank account that you log in to on your phone, you will likely not see much more than a login screen until you have authenticated with your username and password. This will typically bring you to a second page that loads the full single page application with your sensitive banking information that you would not otherwise want available to someone else who picks up your phone.

A login screen is arguably the most common use case requiring user interaction to load an application, and it is one that is often handled with little elegance. The most fluid way to handle this use case, if your REST framework allows for it, is to load a login screen as part of your SPA and request authentication via a REST endpoint from your login form. When you receive a properly authenticated response from your API request, you can then load the data you need into the existing SPA container and replace the login state with a new logged in state.

Loading based on the DOMContentLoaded event

If your SPA does not require user authentication or any other interaction for initial loading, or if you detect a user that is already authenticated at the time the page is loaded and you can skip that step, then you will want a way to automatically load your SPA upon initial page load, and as soon as possible.

The best time to load a single page application is generally as soon as the DOM is completely loaded and can be parsed by the browser. Modern browsers fire an event on the document object when this happens, called DOMContentLoaded, and that can be used for this purpose. To do this, you would simply add an EventListener on the document to detect when the event is fired, and then call a function to load your app:

<script> 
    document.addEventListener('DOMContentLoaded', function(event) { 
        loadMyApp(); 
    }); 
</script> 

Alternatively, if you are using jQuery, you can call the handy jQuery .ready() method to listen for the DOMContentLoaded event and trigger your custom application code within an anonymous function:

<script> 
    $(document).ready(function() { 
        loadMyApp(); 
    }); 
</script> 

Loading based on the document readystatechange event

Modern browsers also provide an event that is fired on the document object when you first load a page called readystatechange. This event can be used to determine three states of the DOM, which are returned as the following via the document.readyState property:

  • loading - This is when the document is still loading and has not been entirely parsed by the browser.
  • interactive - This is when all DOM elements have finished loading and can be accessed, but certain external resources may have not fully loaded, such as images and stylesheets. This state change also indicates that the DOMContentLoaded event has been fired.
  • complete - This is when all DOM elements and external resources have fully loaded.

To use the readystatechange event to load your application at the same time as the DOMContentLoaded event, you would assign a function to be called on the readystatechange event and then check whether the document.readyState property is set to interactive. If it is, then you can call your application code:

<script> 
    document.onreadystatechange = function() { 
        if (document.readyState === 'interactive') { 
            loadMyApp(); 
        } 
    }; 
</script> 

Using this method to detect the state of the document provides more flexibility in the event that you want to call custom application code for any of the three document states, and not just on the DOMContentLoaded event, or interactive state.

Loading directly from the document.body

The more traditional way of loading <script> tags is by placing them within the document <head> element. Adding the <script> tags to the <head> is fine for loading an SPA if you are using the document DOMContentLoaded or readystatechange events within your external JavaScript to initialize your application code at the appropriate time:

<!doctype html> 
<html> 
    <head> 
        <script src="app.js"></script> 
    </head> 
    <body> 
       <div class="container"> 
            The application will be loaded here. 
        </div> 
  </body> 
</html> 

If you want to avoid using these custom DOM events and trigger your application code precisely when you need it, however, a different and more direct approach can be taken.

A common technique for loading JavaScript into a web page today is by placing the <script> tag, which loads your external JavaScript file, directly within the <body> element of the page. The ability to do this lies in the way the DOM is parsed by a browser: from the top to the bottom.

Take this code, for example:

<!doctype html> 
<html> 
    <body> 
       <div class="container"> 
            The application will be loaded here. 
        </div> 
        <script src="app.js"></script> 
   </body> 
</html> 

Loading the external JavaScript app.js file from within the document.body and just above the closing </body> tag will ensure that all DOM elements above the <script> tag are parsed before it is loaded, and the app.js file is loaded precisely after the <div class="container"> element. If that element is where you will load your SPA, then this technique ensures that your application code within app.js will be executed immediately following the container element being parsed.

Another advantage to loading your <script> tags near the bottom of the DOM and below the elements that are required for loading your application is that the loading of those <script> tags will not block the loading of any content above them, due to the browser's top-down parsing of the DOM. Once the <script> tag is reached, there may be some blocking preventing the browser from being usable while it is being loaded, but the user will at least see everything on the page that has been loaded up until that point.

For this reason, loading a <script> tag within the <body> and near the bottom of the DOM is preferable to loading it with the traditional <head> tag insertion so that no blocking occurs before anything is visible on the page.

Using the script tag async attribute

One method for preventing a <script> tag from blocking the browser usability while it is loaded is the async attribute. This attribute can be added to ensure that your app.js file is loaded asynchronously once parsed, and so that the rest of the DOM continues to be parsed and loaded, regardless of when the loading of that script completes:

<!doctype html> 
<html> 
    <body> 
       <div class="container"> 
            The application will be loaded here. 
        </div> 
        <script src="app.js" async></script> 
   </body> 
</html> 

The advantage to this is, again, there is no blocking. The disadvantage to it, however, is that when you are loading multiple scripts asynchronously, there is no guarantee in what order they will finish loading and eventually execute. This is why it also a good practice to load only a single, compressed JavaScript file for your application as much as possible. The fewer <script> tags there are, the fewer external resources have to be parsed and downloaded, and in the case of using the async attribute, using only one <script> tag means waiting for only one asynchronous resource to load and not having to worry about the unpredictable sequence of loading multiples files, which could potentially break your application.

Using the script tag defer attribute

Another method for loading a <script> tag directly from the body and not causing the document parser to be blocked is the defer attribute. Unlike async, this attribute ensures that the <script> tag will not be loaded until the document parsing is complete, or upon the DOMContentLoaded event.

Using the defer attribute, your <script> tag can be placed anywhere within the <body> and always be guaranteed to load after the DOMContentLoaded event:

<!doctype html> 
<html> 
    <body> 
        <script src="app.js" defer></script> 
        <div class="container"> 
            The application will be loaded here. 
        </div> 
  </body> 
</html> 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.205.27