As a summary, RIA works as follows:
The browser loads a HTML file. This file is usually organized in like:
<head>section of the HTML contains all needed CSS code required to style the DOM elements of our application.
<body>tag contains almost no DOM elements (these elements are dynamically generated be JS code).
<script> tag is responsible to add or remove new DOM elements (like modal windows, menus, list items, ...), load data asynchronously from the server, authenticate, etc.
RIA have meant a significant step in the context of web based applications. I remember when GMail appeared and how its UX was much better than other competitors. In GMail the app was loaded once and any change or data loading was handled asynchronously, without the need to reload the page. This is, probably, the most important fact about RIA apps, their similarity with native applications.
But real life always teach us something and the truth is RIA apps has a problem. Lets examine what the flow of a RIA app:
As you can see, with this flow the user needs to wait double of time to get some initial content of the app.
Time ago, with the apparition of HTML5 many companies changed from developing native mobile apps to develop hybrid apps. They quickly found users do not like to wait much time until get some content. See How Loading Time Affects Your Bottom Line.
This is, for example, the way to work of ancient email clients where each action (click in a link or button) implied a call to a different URL on the server and the user must to wait until server resolves the new HTML code and returns it to the browser.
Time has passed and everybody can think on server side applications as a bad option to develop a web app, because of the need of waiting for a server response on each client action.
That's right, but the truth is server side applications are great in one aspect: they can return pages with content, that is, when you request some URL you get the page with the content you expect.
This fact is what makes important server side processing when building universal apps. We need to speed up the app and improve the UX returning as much content as possible when user access some URL.
An universal app is a mix between client side and server side app. The idea is the first time we access a website the server responds with all the code and content user expects, for example, in an e-commerce site the first access could include the initial twenty items and later let the user continue loading more asynchronously.
Ok, I have described how universal apps works but a picture is worth a thousand words.
Process and render: The server handles the request. The server must retrieve the route the user is requesting for (main page, about section, item detail, ...), must query for the needed data to render the HTML page elements.
Interaction: The client has all the needed code to work as a RIA application. The initial content of the page has been rendered by the server, bringing better UX to the user, and from now the app is responsible to request new content asynchronously, without the need to reload the web page.
Remember the code you made must works both on client and server side, some examples are:
Code needed to get the current route and render the right section. Given an app with three tabs: main, help and about, if we can write the absolute URL to the about section in the browser we expect to get the app with the about section enabled. Later, once the app is loaded in the browser, if we change to the help section the components must change. In both cases the code that detects the visited route and renders the page elements must be the same.
Code needed to retrieve data. Because data can be retrieved by the server but also from the client once the app is loaded in the browser, the code you use to get data must work in the two sides. Because of this, usually, universal apps requests data to an API server.
To improve UX the first time we access the server to load the app, the HTML should contain all the expected DOM elements of the page. This way we reduce the time user must wait until have the first content of the page.
Great !! Now you know the basis of how universal applications works. From here, there is a long, but awesome, way until implement a real application.