reactive-python / reactpy-django

It's React, but in Python. Now with Django integration.
https://reactive-python.github.io/reactpy-django/
MIT License
322 stars 18 forks source link

Allow `django_css` and `django_js` to load `only_once` #194

Open Archmonger opened 11 months ago

Archmonger commented 11 months ago

Current Situation

Currently, a user can add django_css to the body of a component that is rendered multiple times. This means that the CSS stylesheet will be duplicated for each component that is on the page.

Proposed Actions

Add an only_once = True argument to django_css and django_js. This will prevent CSS/JS duplication if the static file has already been loaded within the current component tree.

To detect whether a static file has been loaded, we should store whether a static_file_path has already been loaded within the ASGI scope. Here's some pseudocode on the concept:

# This should be initialized within the ReactPy WebSocket consumer
scope["reactpy_static_files"] = set()

# This check should occur within the `django_css` and `django_js` components
if static_file_path not in scope["reactpy_static_files"]:
   return get_static_file_contents(static_file_path)
Archmonger commented 7 months ago

Note to self: Storing the stylesheet within the scope will still result in duplicate stylesheets if multiple root components exist on the page.

Loading the stylesheets might need to be handled via JavaScript and somehow globally track whether a stylesheet is needed.

Or thinking in reverse, perhaps we should always load the stylesheet every time, but have duplicates get deleted via JavaScript?


Another idea is using a global JavaScript object to keep track of how many components want a certain stylesheet.

The stylesheet themselves would need to be stored in some master object, and would need to get unloaded after there are no component left that use the stylesheet.

On the page, this master object might look like this:

<body>
    <div id="reactpy-stylesheets">
        <style id="path/to/stylesheet.css"> ... </style>
    </div>
</body>
Archmonger commented 6 months ago

Blocked on