Caching Resources
Cache Recommendations
OpenFin handles caching in the same manner as commercial-based browsers (Chrome, Edge). This enables OpenFin application development teams to leverage common web-based best practices in an OpenFin environment.
In this document, OpenFin highlights some undesirable behavior with regard to cached resources and common web practices that can be leveraged to address them.
Below, we touch on some approaches, strategies to consider and tools available in the OpenFin API.
Note: There are some subtle nuances in an OpenFin environment which are not incorporated with traditional web-based browsers but these are a narrow scope. These are touched on below.
Caching challenges
Unlike a traditional website, and the browser it runs inside of, end-users of a web-based OpenFin application do not enter a URL (or reload) to access their web content. Their web content is predetermined and served up to them based on a set of application business rules. So the experience is somewhat similar to running in Chrome but the actions taken to load that content are slightly different. This leaves the responsibility to the application provider to accommodate instances where cached assets have been modified or updated.
Sometimes challenges are seen after a software or asset update. These scenarios are traditionally confined to UI expectations but do also encompass feature and functional changes where the assets or logic remain cached. For example, in some cases, end-users will see newly updated icons or the like, while others continue to see the existing ones. Below, we will outline how to plan and overcome these challenges.
Benefits of a cache strategy
Caching is a good thing and is leveraged effectively by many web applications; by planning how you will cache, you can avoid some of the challenges posed above. Caching improves the experience for end-users but also has net benefits for developers who maintain these web applications. These benefits include:
End-users
-
Faster load times
-
Reduced data usage
-
Improved responsiveness
-
Offline availability
Developers
-
Reduced server load
-
Improved application performance
-
Simplified development
-
Reduced costs
When relying on caching for a web application, there are some recommended patterns from the greater web community.
Here are some areas to consider when determining your purpose-based caching approach:
Strategy
Identify appropriate assets |
Not all assets benefit equally from caching. Focus on static resources like images, CSS files, and JavaScript libraries that change infrequently. |
Cache levels |
Different levels of caching serve different purposes. Utilize browser caching for frequently accessed assets, but consider a Content Delivery Network (CDN) or server-side caching for heavier resources or geographically distributed users. |
Cache expiration times |
Do not cache everything forever! Define expiration times for cached assets based on their update frequency. Short expirations ensure users get the latest version, while longer ones maximize performance gains. |
Implementation
Leverage HTTP caching headers |
HTTP provides powerful caching directives like Cache-Control and Expires to instruct caches on how to handle content. |
Utilize caching libraries |
Many frameworks and libraries offer built-in caching functionalities, making implementation easier and more efficient. |
Monitor performance |
Regularly evaluate your caching strategy and monitor its impact on performance. Adjust expiration times and cache levels as needed for optimal results. |
Additional techniques
Cache invalidation |
Implement mechanisms to invalidate cached content when it changes on the origin server. This ensures users always see the latest version. |
Cache busting |
For assets with very granular updates, use versioning or unique file names to force browsers to fetch the latest version even if the underlying content hasn't changed significantly. This can be a powerful tool to use for high risk times like software upgrades as described above. |
Progressive caching |
Deliver critical portions of content quickly while asynchronously loading heavier resources behind the scenes, providing a smooth user experience even before all elements are fully loaded. |
It's important to emphasise that caching is a dynamic tool and determined by a web application provider’s strategy. It's recommended that web application teams are continuously evaluating and adapting their approach to their implementations. All of these concepts are supported in OpenFin.
Caching Recommendations
OpenFin highly recommends the use of cache headers. This is a common tool in a web application team’s toolbox. Cache headers are widely leveraged to address common caching scenarios that require dependable outcomes.
Consider traditional web applications we use in our everyday personal and commercial use; X (formerly Twitter), Instagram, Netflix, MS Teams, LinkedIn, commercial banking applications (checking accounts), Charles Schwab, E-trade and so on. These web applications (and mobile apps), have a wide distribution model and rely on standard web practices to achieve their caching strategies to ensure a consistent and reliable web experience for their end-users.
What are Cache Headers?
Cache headers are part of the HTTP response sent by a web server to a client (like a general purpose browser i.e. Chrome). The headers instruct the browser on how to cache resources such as HTML pages, images, and other files. A cache header provides a specific set of instructions embedded within HTTP communication that dictates how web browsers and intermediary servers should cache and handle web content. Headers act as the gatekeepers of caching, ensuring that resources are stored and retrieved efficiently to optimize performance and user experience through reduced load times of web pages by storing copies of resources locally on the end-user's device.
Common Cache Headers and Functions:
-
Cache-Control: This is the primary header for controlling caching behaviors. It includes directives like max-age (how long to store the resource), no-cache (forces revalidation with the server before using the cached copy), and no-store (prevents caching altogether).
-
Expires: Specifies an exact date/time after which the resource is considered stale.
-
ETag: A unique identifier for a resource. It helps in validating cache entries and understanding if the content has changed since the last fetch.
-
Last-Modified: Indicates the last time the resource was modified. It's used in conjunction with the If-Modified-Since request header for cache validation.
Impact on Users Seeing Up-to-Date Content:
-
Freshness vs. Speed: Cache headers balance between delivering the freshest content and reducing load times. For instance, setting a longer max-age improves load times but might serve outdated content.
-
Dynamic Content: For websites with frequently updating content (like news sites), aggressive caching might result in users not seeing the most recent updates. This is often mitigated by using no-cache or short max-age values.
-
Browser and Server Interactions: If a resource is cached with a max-age directive, the browser won't request it from the server until it expires. With no-cache, the browser will check with the server for updates before serving the cached version, ensuring users see updated content if it's available.
Differences between Chrome and OpenFin Workspace
The OpenFin Runtime leverages the Chromium open source project and as such OpenFin honors cache-control headers with the same semantics as Chrome with a few exceptions.
The following OpenFin resources are not ordinary web content, and are cached outside of the normal process in a way that cannot be controlled with cache-control headers:
-
Taskbar icons
-
Tray icons
-
Preload scripts
-
Application manifests
Note: Icons displayed in the OS are registered against the Operating System and thus the rules are different, icons used by the Store, Home, Search components will respect standard cache-control headers.
Migration of cache
Changing the manifest would result in a new cache as it is considered a new application.
More to read about cache migration is stated below: https://resources.here.io/docs/core/develop/manifests/cache-migration/
OpenFin Cache APIs
With a good cache header strategy most of your common cache related experiences will be addressed. More importantly, future inconsistencies will be avoided based on your strategy standards. In addition, OpenFin provides APIs that can act on the cache.
fin.System.clearCache
Clears the cached data, parameters can be used to control what sections of the cache to clear (cookies, local storage) but not on what domains are affected. Meaning when you clear the cache using this API all domains sharing your Browser process are affected.
fin.System.clearCacheOnExit
This API behaves similar to fin.System.clearCache but will execute the action when the OpenFin Runtime exits.
These API’s are blunt instruments and will negatively impact the overall startup time of your Platform as well as the start time of every application deployed. If you find leveraging these APIs resolves a particular scenario, it's worth revisiting your cache strategy.
Server Side Cache-Control
OpenFin supports standard HTTP Cache-Control methods implemented in Chromium. Therefore you could control the cache on the server side. Further information on controlling the cache via HTTP headers can be found here.
Developer Tools
Open the chrome developer tools and select disable cache under the network tab. This is useful when developing your application. (your application manifest needs to have the "contextMenu" property set to true to access the chrome developer tools).
OpenFin Cache Management
OpenFin includes a few API calls you could use to control the cache:
System.clearCache - This API call will clear the contents of the cache, cookies, localStorage and appcache when all are set to true. This could look something like below:
const clearCacheOptions = {
appcache: true,
cache: true,
cookies: true,
localStorage: true
};
fin.System.clearCache(clearCacheOptions).then(() => console.log('Cache cleared')).catch(err => console.log(err));
System.deleteCacheOnExit - This API call will clear all cached data when the OpenFin Runtime exits. This could look something like below:
fin.System.deleteCacheOnExit().then(() => console.log('Deleted Cache')).catch(err => console.log(err));
Manually clearing the cache
You can manually clear the cache from the following location:
C:\Users<Username>\AppData\Local\OpenFin\cache
Please be aware that deleting the cache from this location could affect other applications using the same runtime.
We recommend using security realms if there is a risk of other applications being affected by deleting the runtime cache from this location. Security realms ensure all applications, not in your security realm do no have access to your applications cache (separate cache).
Information on security realms can be found here: https://developers.openfin.co/of-docs/docs/openfin-security#security-realms
Service Workers
An efficient way to control the cache of your application is by the use of service workers. There is no difference in the implementation of a service worker, whether you are doing this on the web or via OpenFin. Service workers can offer you the flexibility to run your application offline or allow you to always download updated content from your servers and then fallback to your cache (network-first recipe) other recipes can be found here.
Further information on service workers can be found here: https://developers.google.com/web/fundamentals/primers/service-workers.
A collection of working, practical examples of using service workers can be also be found here:
https://serviceworke.rs/.
Offline Access
The offlineAccess feature loads a cached version of the application manifest, but not the startup URL. A cached version of the application manifest includes the Notification Centre and Workspace manifest. It is important to note, the application will need to be launched at least once for manifest(s) to be cached. This will allow for any subsequent launches without internet access to launch the Notification Centre successfully.
If the startup URL is not available, your application will not launch. If an application has been launched at least once and there's no internet access, the rvm will launch a locally cached config.
Furthermore, using the offlineAccess feature correctly, your application must support HTML5 offline access. An efficient way of having your application available offline is to cache core files with the use of service workers, information on service workers is mentioned above.
This property should be included in the application manifest (top-level), documentation can be found here: https://developers.openfin.co/of-docs/docs/application-configuration
How Cache updates when using Security realm
When you configure the application to use a security realm the application will create is own cache directory to house all its cache files in.
you can refer to the link attached here to learn more about it here: Security overview
Useful articles & resources:
Here are a couple of resources OpenFin recommends application providers review to determine their cache strategies:
Help and Support:
Comments
0 comments
Please sign in to leave a comment.