BattlefyBlogHistoryOpen menu
Close menuHistory

Rule of least power applied to Webapps

Ronald ChenJanuary 3rd 2022

You are tasked with implementing a privacy consent modal.

Your website is composed of different Webapps hosted on the same-origin, but under different context paths.

https://domain.tld                 → serves Vue.js app  
https://domain.tld/some-path       → serves Preact app  
https://domain.tld/some-other-path → serves React app

Are we going to have to implement a consent modal multiple times? Even sharing the HTML/styling template wouldn’t be possible. There is no common format that works for Vue.js template, Preact.h function and React.createElement function.

If we implement the consent modal independently of the existing apps, how are we going to integrate them? The existing apps need to know whether consent has been given to load additional scripts.

One solution is to iframe the modal and use postMessage to communicate with the parent app, but doing so would require us to carefully implement the event listener as any other iframes can now be a security concern.

We can do better. We can implement the consent modal as its own independent JavaScript bundle and include it into our existing Webapps. The Webapps and consent modal communicate state change with a simple callback function exposed on window.

Independent JavaScript bundle

This is easy enough, let’s just implement the consent modal in React, right? But this raises a few issues.

First of all, bundling React or any other framework for that matter is going to make the bundle massive. The functionality we need is very simple, a modal with 3 buttons.

Second of all, if we were to use React for our consent modal and for the main app, this would mean we’ll be loading React twice. React isn’t a library like lodash where you could just pull in multiple versions. React is a framework that hooks into the browser’s event system. This causes issues when more than one instance of React is loaded.

This is where the title of this blog post comes into play. Applying the Rule of least power directs us to consider, could we implement the consent modal in pure JavaScript without any frameworks? Do we dare to reach for the DOM?

Heresy! It's forbidden dark art to use the DOM API directly! If we touch the DOM, we’ll suffer…wait what’s wrong with using the DOM again?

We’ve been shielded from the DOM for such a long time with modern frameworks, we’ve forgotten how to use it. Heck, some people have never even heard of it and have been productively relying on only knowing React Hooks as their first foray into web development.

The DOM can’t hurt you

The reason why web frameworks, such as React, sprung up was to allow us to handle the complexity of larger websites. It is difficult to manage state and events directly with the DOM, but we don’t have a large website in this case! The consent modal is tiny, in fact here is the entirety of the code for our demo.

Does this seem like too much code for a simple consent modal? Well, compare it to the same code implemented in React. The code is formatted with prettier, so it artificially made it a bit longer due to the style objects, but even then both implementations are similar. However, the React variant’s bundle blows up in size by over 50x as it needs to now include react and react-dom.

Size of production built bundles:

2.5KB consent-modal-2.0.0-min.js

132KB consent-modal-react-2.0.0-min.js

Demo time

Here is the full demo of the consent modal in Vue.js and Preact Webapps. The full source code is all found within one organization.

Some details to connect the remaining dots.

The demo site and the consent modal bundle are both arbitrarily hosted with GitHub Pages.

Additional use cases

These ideas can be applied to many other features that need to be implemented cross-functionally over all Webapps. Consider the following features as independent JavaScript bundles

  • User login/logout
  • Loading of translated content for localization
  • Triggering browser notification from real-time events such as Firebase
  • Third-party integrations such as Intercom, Google Analytics, Facebook Pixel
  • Error logging
  • Backend API client
  • Clipboard management

Essentially any reusable chunk of JavaScript that is framework-independent can be extracted. Those with a UI component can also be extracted if it can be its own independent root level DOM element in the HTML body.

Do you want to learn frontend architecture? You’re in luck, Battlefy is hiring.


Powered by