Kicks Condor

Fake HTML Includes (for Beaker)

My personal strategy for handling HTML on the distributed Web.

So, HTML is a bit different on the distributed Web (the Dat network which the Beaker Browser uses, IPFS and so on) because your file history sticks around there. Normally on the Web, you upload your new website and it replaces the old one. With all of these other ‘webs’, it’s not that way—you add your new changes on top of the old site.

Things tend to pile up. You’re filing these networks with files. So, with a blog, for instance, there are these concerns:

  • I want common things like headers and footers to be in separate files—because they bloat every one of my pages.
  • I also want them in separate files so that when I change something in my header it doesn’t change EVERY PAGE in my site—pushing lots of changes onto the network.
  • The trend with Dat seems to be that websites are delivered more as applications—where you could potentially access the underlying posts in a format like JSON, rather than just having a raw HTML dump.

Ultimately, I might end up delivering a pure JavaScript site on the Dat network. It seems very efficient to do that actually—this site weighs in at 19 MB normally, but a pure JavaScript version should be around 7 MB (with 5 MB of that being images.)

My interim solution is to mimick HTML includes. My tags look like this:

<link rel="include" href="/includes/header.html">

The code to load these is this:

document.addEventListener('DOMContentLoaded', function() {
  let eles = document.querySelectorAll("link[rel='include']");
  for (let i = 0; i < eles.length; i++) {
    let ele = eles[i];
    let xhr = new XMLHttpRequest()
    xhr.onload = function() {
      let frag = document.createRange().
        createContextualFragment(this.responseText)
      let seq = function () {
        while (frag.children.length > 0) {
          let c = frag.children[0]
          if (c.tagName == "SCRIPT" && c.src) {
            c.onload = seq
            c.onerror = seq
          }
          ele.parentNode.insertBefore(c, ele);
          if (c.onload == seq) {
            break
          }
        }
      }
      seq()
    }
    xhr.open('GET', ele.href);
    xhr.send();
  }
})

You can put this anywhere on the page you want—in the <head> tags, in a script that gets loaded. It will also load any scripts inside the HTML fragment that gets loaded.

This change saved me 4 MB immediately. But, in the long run, the savings are much greater because my whole site doesn’t rebuild when I add a single tag (which shows up in the ‘archives’ box on the left-hand side of this site.)

I would have used ‘HTML imports’—but they aren’t supported by Firefox and are a bit weird for this (because they don’t actally put the HTML inside into the page.)

I am happy to anyone for improvements that can be made to this.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

PLUNDER THE ARCHIVES

This page is also at kickssy42x7...onion and on hyper:// and ipns://.