/simple-reload

Reload a web page as it is iteratively developed or modified

Primary LanguageJavaScriptMIT LicenseMIT

simple-reload

Summary

simple-reload provides a straight-forward (~30 lines of JS and zero server-side requirements) way of reloading a web page as it is iteratively developed or modified. Once activated, a page will be reloaded whenever it regains focus.

Trade-offs

Mature solutions like LiveReload are available, which makes a different set of trade-offs. Please read this section carefully to determine if simple-reload makes sense for you:

Cons:

  • Reload won't take place until the page is focused by the user, which requires manual interaction.
    • This is significantly less burdensome if using focus follows pointer in your window manager.
  • Reloads will occur even if there were no changes.
    • With e.g. LiveReload, a reload only happens when the server indicates there has been a change. This may be a big advantage for stateful pages or pages with lots of forms.

Pros:

  • Tiny, easy to modify implementation.
  • Can dynamically enable/disable reloading on a per-tab basis.
    • This can be helpful to keep a fixed revision of a page in one tab to compare against.
  • No server-side requirements.
    • So works even from file://.
    • Makes it easier if using with a remote server (e.g. no need to worry about exposing a port as for LiveReload).

Code

<script type="module">
// Set to true to enable reloading from first load.
const enableByDefault = false;
// Firefox triggers blur/focus events when resizing, so we ignore a focus
// following a blur within 200ms (assumed to be generated by resizing rather
// than human interaction).
let blurTimeStamp = null;
function focusListener(ev) {
  if (ev.timeStamp - blurTimeStamp >= 200) {
    location.reload();
  }
}
function blurListener(ev) {
  if (blurTimeStamp === null) {
    window.addEventListener("focus", focusListener);
  }
  blurTimeStamp = ev.timeStamp;
}
function deactivate() {
  sessionStorage.removeItem("simple-reload");
  window.removeEventListener("focus", focusListener);
  window.removeEventListener("blur", blurListener);
  document.title = document.title.replace(/^\u27F3 /, "");
  window.addEventListener("dblclick", activate, { once: true });
}
function activate() {
  sessionStorage.setItem("simple-reload", "activated");
  location.reload();
}
if (enableByDefault || sessionStorage.getItem("simple-reload") == "activated") {
  document.title = "\u27F3 " + document.title;
  sessionStorage.setItem("simple-reload", "activated");
  window.addEventListener("blur", blurListener);
  window.addEventListener("dblclick", deactivate, { once: true });
} else {
  window.addEventListener("dblclick", activate);
}
</script>

Usage

Paste the above code into the <head> or <body> of a HTML file. You can then enable the reload behaviour by double-clicking on a page (double-click again to disable again). The title is prefixed with ⟳ while reload-on-focus is enabled. If you'd like reload-on-focus enabled by default, just flip the enableByDefault variable to true. You could either modify whatever you're using to emit HTML to include this code when in development mode, or configure your web server of choice to inject it for you.

The enabled/disabled state of the reload logic is scoped to the current tab, so will be maintained if navigating to different pages within the same domain in that tab.

In terms of licensing, the implementation is so straight-forward it hardly feels copyrightable. Please consider it public domain, or MIT if you're more comfortable with an explicit license.

Implementation notes

  • In case it's not clear, "blur" events mentioned above are events fired when an element is no longer in focus.
  • As noted in the code comment, Firefox (under dwm in Linux at least) seems to trigger blur+focus events when resizing the window using a keybinding while Chrome doesn't. Being able to remove the logic to deal with this issue would be a good additional simplification.