Skip to main content

Preloads

What is a preload?

A preload is a script that is loaded into a window before the actual content of that window is loaded.

A preload runs every time the window reloads. This way, the component behaves the same way each time, and the users can have the same experience each time they switch to the window that has the preload. You can include multiple preloads for the same window. They will be loaded in the order in which they were defined.

Sometimes the same code can be used both as a preload and as an app. We provide a sample, the Bloomberg bridge client, that can be used both ways.

note

Finsemble includes some built in preloads.

Advantages

A preload provides added flexibility because it allows you to run additional code in the window without changing code for the app that the window belongs to.

Another advantage of a preload is that you can write it once and then push it to many apps without redeploying them. This code reuse saves time both in terms of coding and in terms of deployment.

Finally, there is one more advantage. You might have an app that several teams use, but each team interacts with it in different ways. In this situation, you can use preloads to customize the app interactions for each team without modifying the source code of the app.

Preloads are secure

If preloads make you nervous, it’s probably because the first thing that comes to mind is news reports about stealing credit card information or some other malicious use. While this is indeed an example of what a preload could do, there are countless legitimate examples of useful preloads that don’t intend to do harm and are safe to run.

The main problem with preloads in general occurs when there are no safeguards and anyone can run one. In the case of Finsemble, this doesn’t happen. That’s because the only people that can configure an app to run a preload are the people who control the desktop experience. Nobody else can come in and run a preload for any window on a smart desktop. So preloads in Finsemble present no added security risk. If you trust your desktop experience team, there is no reason for you to worry about the security of Finsemble preloads.

We take security seriously. For this reason, we have some restrictions on running preloads. Before you can run a preload, you need to make sure that the component is trusted. If your component is on the same domain as Finsemble, you don’t have to do anything because all components within the same domain are automatically trusted. If it isn’t, you can set the trust explicitly by specifying Window.webPreferences.preload = true. More about trusted policies.

Important

If neither of these conditions is met, Finsemble won’t apply your preload.

A preload isn’t always the answer

In principle, anything can be a preload. You could even manage your entire ecosystem this way, but we definitely don’t recommend it. Powerful as preloads are, you don’t want to overuse them. For example, there is no need for a preload if you have access to the source code that you can easily update. It makes more sense to modify that source code to behave exactly as you want instead of adding one more layer of complexity to your environment. Customizing your app directly is a cleaner approach to managing your ecosystem. It is a good practice to keep the code for an app in one place to avoid the code for the app and the code for the associated preload to diverge in undesirable ways.

On the other hand, when you update an app, you need to then redeploy it. If you don’t want to or can’t redeploy, you can use a preload instead. So deciding whether you want to use a preload or not is also about what’s easier. If redeploying is hard or disruptive, use preloads. But do so with the understanding that it’s a more complex solution than customizing directly.

You also need to consider how your enterprise is organized. Many companies divide responsibilities between the desktop team, which owns how apps talk to each other, and the dev team, which owns what the apps actually do. Because of this division of responsibility, a desktop team might choose to use a preload so that they can control the app interaction without involving the dev team. Alternatively, the dev team might decide to modify the app instead of using a preload. Usually, organizations figure out the approach that is the easier overall.

Preload examples

As we have seen, preloads are versatile and you can use them for many different tasks. You can add a preload that handles an event such as a button click. For example, a Web app component could listen for content and navigate to a new url. The preload could listen to messages and then navigate or display content.

Another example is to customize an external app, such as a financial page like the Web app Yahoo Finance. You can use a preload script to add the ability to listen for context. Your preload then could listen for stock symbols and navigate to information about that specific symbol.

One common usage is to override a built-in API. For example, you can use native overwrites in source preloads. nativeoverrides.js customizes window.open, which opens a component, and window.alert so that you can change the dialog box to a Finsemble message. This is one way to adapt a web app to work with Finsemble.

Some Finsemble customers add a layer between their code and Finsemble itself. This way, they expose their API to insulate from changes to Finsemble. Your own API makes calls to other APIs, and you can use preloads for that.

Here is another useful example: you can use a preload to make a web app FDC3-compliant without changing its source code. This example preload can be used with the web page "https://finance.yahoo.com/chart": Here is another useful example: you can use a preload to make a web app FDC3-compliant without changing its source code. You can use this example preload with the web page "https://finance.yahoo.com/chart":

const main = () => {
FSBL.Clients.Logger.log("Initializing context and intent listeners");

const contextHandler = (context) => {
const { ticker = null } = context.id;
if (ticker) {
FSBL.Clients.Logger.log("Received context: ", context);
window.location.href = `https://finance.yahoo.com/chart/${ticker}`;
} else {
FSBL.Clients.Logger.error("context does not have a ticker key");
}
};

fdc3.addIntentListener("ViewChart", contextHandler);
fdc3.addContextListener("fdc3.instrument", contextHandler);
}

//standard finsemble initialize pattern
if (window.FSBL && FSBL.addEventListener) {
FSBL.addEventListener("onReady", main);
} else {
window.addEventListener("FSBLReady", main);
}

In your app's AppD record set component.preload to the location of the preload script (for example "$applicationRoot/preloads/FDC3Client.js").

{
...
"apps": [
...
{
"appId": "FDC3 Yahoo Chart",
"name": "FDC3 Yahoo Chart",
"type": "web",
"details": {
"url": "https://finance.yahoo.com/chart/blank",
},
...
"hostManifests" : {
"Finsemble": {
...
"component": {
"preload": [ "$applicationRoot/preloads/FDC3Client.js" ]
}
...
}
}
}
]
}

How to add a preload

After you write your preload, you need to tell Finsemble to apply it. To do so, you need to add it to the config file. Keep in mind that the order in which you specify the preloads matters. The preloads are loaded in the same order in which they appear in the config file.

There are several ways to add preloads:

  • Single component - a preload applies only to the specific component
  • Multiple components - a preload is applied to several components
  • Launchable - applied only to components that can be launched
  • All components - a preload is applied to every component, including built-in components (global preload). These preloads can be very powerful.

What to watch out for

Preloads are powerful and provide flexibility, but there are some issues you need to be aware of: race conditions and caching. Let’s take a look at these.

Race conditions

Preloads run early, which means they can run before the javascript console is set up or before your component is loaded and elements are created. In some cases that’s fine. But in other cases, a preload needs some other object to be loaded before it can complete its tasks.

If your preload needs an element that doesn’t exist yet, this creates a problem that is often difficult to debug due to inconsistent results. Sometimes things will work as expected, and at other times they don’t. This is difficult to debug because when it works you might think everything is fine when in fact it isn’t. You just had a lucky run. This issue is due to race conditions. In other words, sometimes the component would be created before it’s needed, and at other times it wouldn’t be there yet.

To prevent race conditions, synchronize actions your preload performs with the window's content loading, with the Finsemble API clients initialization, or both. To ensure that items you need are loaded before your preload run, listen for the DOMContentLoaded and FSBLReady events.

To listen for FSBLReady:

if (window.FSBL && FSBL.addEventListener) {
FSBL.addEventListener("onReady", init);}
else {
window.addEventListener("FSBLReady", init);
}

To listen for DOMContentLoaded:

window.addEventListener('DOMContentLoaded', init);

To listen for both events:

let fsblReady = false, domReady =document.readyState === "loaded" || document.readyState === "completed";
let checkAndInit = () => { if (fsblReady && domReady) { init(); } }
let fsblIsReady = () => {fsblReady = true; checkAndInit(); }
let domIsReady = () => { domReady = true; checkAndInit(); }
if (window.FSBL && FSBL.addEventListener) {
FSBL.addEventListener("onReady", fsblIsReady);}
else {
window.addEventListener("FSBLReady", fsblIsReady);
}
window.addEventListener('DOMContentLoaded', domIsReady);

Caching

Finsemble caches preloads to increase efficiency. Caching works well as long as there are no changes to the preload. But while you’re debugging or updating your preload and trying to test its behavior, you need to be aware that the old version might still be cached. If it is, that old version will be used instead of the new one that you want to test. To verify that you’re using the correct version of your preload, make sure the server gives the appropriate cache headers.

If you’re still having trouble seeing changes in the preloads and suspect that it’s because of caching, you might want to restart Finsemble.

See also

Integrating HTML applications