Auto-Include Asset Files



One of the most annoying aspects of web development relates to asset file caching. Assets are static files like images and JavaScript libraries, that do not change in normal operation. These files can be pulled into a web page in a variety of ways. Because they do not normally change, the browser, in an attempt to be helpful, caches the files so it does not waste time re-downloading an identical file multiple times.

This behavior can be very annoying when you are building web applications, because in development, you often do want to change the asset files. But if you change an asset file, you need to somehow notify the browser that it has been changed. On your own browser, you can do a Hard Reload, which forces the browser to reload all the asset files. But this work-around does not scale up if other people are using your code (it's very awkward to email your users and ask them to do a Hard Reload).

One simple work-around is simply to tell the browser not to cache certain files. That's a bit unsatisfying, though, because most of the time we do want the files to be cached.

The WWIO platform supports a technique that lets us have the best of both worlds. You can get the benefits of caching when you need it, but the browser will be notified when you make a change to one of the assets. This technique is based on auto-inclusion of certain asset files (CSS, JS, or FavIcon) based on a naming convention.

To use this technique, all you need to do is give your JavaScript or CSS files a name that begins with the prefix "My". Then put the files either in your base directory, or in one of the widget directories.

When the WWIO platform sees an asset file with this naming convention, it inserts an appropriate include statement when it is serving a WISP file. This statement is generated along with the JS material for serving the SQLite data. Furthermore, the include statement includes the modtime of the file. Here's what it looks like:

<!-- Custom JS code for user -->
<script type="text/javascript" src="/u/dburfoot/MyWidgetCode.js?modtime=1714270261668"></script>
<link rel="stylesheet" href="/u/dburfoot/MyWidgetStyle.css?modtime=1714270261668"></link>
<script type="text/javascript" src="/u/dburfoot/links/MyLinkDisplay.js?modtime=1716751346183"></script>
<!-- End custom JS code for user -->

You can see the system has pulled in three files automatically: MyWidgetCode.js, MyWidgetStyle.css, MyLinkDisplay.js. The first two are in my base directory, while the last one is specific to the links widget. As you can see, it the include statement has attached a modtime to the URL. This is the modtime of the file on the server. That means if the page is reloading without changing the assets, the include link will be identical, so the browser will use the cached copy of the file. If the asset has changed, the include link will be different (since the modtime has changed), so the browser won't use its cached copy. You can see the auto-include statements by using the View Source option in the browser tools.

Asset files can be either global to all your widgets, or local to a specific one. If the asset is in your base widget folder, it will be considered global and it will be pulled in for all your widgets. If it is in a widget folder, it will be including only for that widget.

You can also use the auto-include trick for your app's "favicon", the small icon that appears on the side of the browser tab. To do this, you should use the specific filename MyFavIcon, with an appropriate extension such as .png or .jpg. When you upload a file with the right name to your widget directory, the system will auto-include a link as follows:

<link rel="icon" type="image/x-icon" href="/u/dburfoot/MyFavIcon.png?modtime=1714270261668"></link>

For the FavIcon, which doesn't really change very often, the auto-include trick is primarily a way to reduce the amount of boilerplate code you need to write. You can get the same effect by simply writing out the link rel=... command on every page in your app.