django-elm icon indicating copy to clipboard operation
django-elm copied to clipboard

Bundle common programs that appear together in templates

Open Confidenceman02 opened this issue 9 months ago • 1 comments

Djelm makes it incredibly easy to sprinkle elm programs across a server generated html django template and as such, it's very easy to end up with a handful of programs with independent elm runtime's on a page.

In production the compilebuild strategy creates very optimised assets so having multiple elm programs on the page may not even be an issue performance wise.

Ideally however it would be great to optimise bundles with common elm programs that always render together.

Let's look at the following example template:

{% load static %
{% load static main_tags %}
{% load static someOtherElmProgram_tags %}
<body>
    {% render_Main %}
    {% render_SomeOtherElmProgram %}
</body>

Djelm will create hydration code for both Main and SomeOtherElmProgram, with independent runtimes.

To build production assets we use the 'compilebuild` strategy which will optimize both runtimes. This is done by the very excellent elm compiler.

Ideas

As an initial step during the 'compilebuild' strategy djelm could check all django templates for known programs that exclusively render together and bundle them up. As a result of this check djelm could create and generate a JSON structure we could shove in the static directory, then at run time when a programs templatetag is called we could do a check on that JSON structure.

  • Check to see if the program name maps to an optimized bundled asset.
  • If it does, use the bundled asset.
  • If it doesnt, just render the individual program as before.

This behaves as a sort of manifest for the compiled programs. The whitenoise python package does something like this to map files to hashed files.

{
    "Main": "Main_SomeOtherElmProgram.js",
    "SomeOtherElmProgram": "Main_SomeOtherElmProgram.js",
    "RandoProgram": "RandoProgram.js"
}

Confidenceman02 avatar Apr 15 '25 09:04 Confidenceman02

I think as a first effort this should be user defined.

Perhaps in settings a user can provide a map with the relevant elm programs to bundle.

Let's consider the following url:

path(
    "organisation/<int:org_id>/home",
    views.organisation_home,
    name="organisation_home",
)

And somewhere in settings:

DJELM_ROUTER_MAP = {
    "organisation_home":  ["Main", "Dashboard"]
}

From a custom middleware djelm could resolve the map and the current url and inject a property in to the request.

def middleware(request):
        # Check the DJELM_ROUTER_MAP
        # Check if the URL is resolved and matches "organisation_home" from the map
        if hasattr(request, 'resolver_match') and request.resolver_match:
            if request.resolver_match.url_name == 'organisation_home':
            #etc

Then from the djelm template, it could try extract request info and see if the elm program that is being rendered is part of a bundle.

This puts a lot of power in to a users hands, enough to create incredibly inefficient bundling, but also to create ridiculously optimized elm runtimes on the page if done well.

Ideally, djelm would create this map internally, by parsing templates and looking for common programs. However, the issue would still be resolving the URL.

Perhaps djelm could do the check and inform the user that bundling programs might be a good idea.

Confidenceman02 avatar Apr 19 '25 10:04 Confidenceman02