Skip to Content
Technical Articles
Author's profile photo Alexander Chan

WebIde – How to stop hitting refresh and get live reloading

Are you tired of hitting refresh every single time you make a tiny code change in webide?  I don’t know about you but I’ve wanted live-reload like we have in tools like create-react-app (webpack) and browser-sync. Now we have a way!

The idea

Why can’t we check if the files we’re interested in change?  We could fetch and compare the files we’re interested in for a bit of overhead (network and cpu cycles).

So I went off to check how we could do this and noticed that hashes are already being calculated in the /sap-ui-cachebuster-info.json file so we can even just use that to compare with which simplifies the refresh from having to watch individual files to checking the cachbuster json to see if anything has changed.

Implementation

We can read the file, check with the last cached version and then reload if the files are changed.  Some other small things like timing out if no changes have been done in 15 minutes and we have a very basic script that emulates live reloading minus the websockets.

Add the script into your index.html and it will start re-loading whenever changes are detected.  If you need IE11 you’ll have to use the transpiled version.  It would work fine from any other initialization code.  If you know you will be shipping and using the index.html, it’s a good idea to use an index_livereload.html that has the live reload code separated.

 

<script>


// Watcher
(async function liveReload({poll_frequency = 3000, max_watch_minutes = 15} = {}) {

	function addMinutes(date, minutes) {
		return new Date(date.getTime() + minutes * 60000);
	}

	const endTime = addMinutes(new Date(), max_watch_minutes); // Stop watching after 15 mins

	let prevCacheBuster = null;

	let watcher = () => {};
	async function reloadOnChange() {
		// Cachebuster is recalculated on save of any file in webide.
		let response = await fetch('/sap-ui-cachebuster-info.json');

		if (new Date() >= endTime) {
			console.log('No changes in awhile.  Stopping watching.');
			clearInterval(watcher);
			return;
		}

		if (response.ok) {
			let responseText = await response.text();

			// Compare the previous values to the new values
			if (!prevCacheBuster) {
				prevCacheBuster = responseText;
			} else {
				// compare the two and reload the page
				if (responseText !== prevCacheBuster) {
					console.log('Cache difference.  Time for reload...');
					location.reload();
					prevCacheBuster = responseText;
				}
			}
		}

	}

	if (/^webidetesting/.test(location.host)) {
		console.log('️Starting reloadwatcher...');
		console.log(`Will stop after ${max_watch_minutes} minutes at ` + endTime)

		watcher = setInterval(reloadOnChange, poll_frequency);
	}

})()

</script>

Some notes

  • This is only setup to run on webidetesting domains to ensure it doesn’t run on other platforms.
  • The cache buster json is sometimes recalculated even if you don’t save the file.
  • Don’t drop the refresh rate down too low or else your network will just be filled with requests since we’re using a polling method.
  • If you don’t want to see the network requests in chrome debugger, you can can put -json in your network filter and it will remove all .json files from the network display.

What’s next?

Out of the box support for this using something like web-sockets would be ideal and lighter weight but this solves the use case for those of us who tire of hitting refresh constantly!

follow me on twitter @alexandermchan

Assigned Tags

      2 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Alexander K
      Alexander K

      Thanks Alexander,

      Very useful

      Author's profile photo Richard Brünning
      Richard Brünning

      Nice!