EmilStenstrom / django-components

Create simple reusable template components in Django.
MIT License
1.18k stars 76 forks source link

Document how to bundle component media using a popular asset manager library #39

Open EmilStenstrom opened 3 years ago

EmilStenstrom commented 3 years ago

Making two extra HTTP requests for each component on the page makes sense with few components. It will even be decently efficient when using HTTP/2 or later. But as the number of components grow it will stop to make sense. Therefor we should add some sort of bundling of all CSS-files used by components into one file, and all JS-files into another. Using any number of components should just require one CSS file and one JS file.

Upsides?

Downsides?

Things to consider:

danjac commented 3 years ago

Personally I just use a single JS or CSS bundle anyway using webpack or esbuild - it seems like existing tools (either Django pipeline or JS/node-based tools) already do this very well. I tend use the Media options with forms or components only where a large JS/CSS include is required that I wouldn't want globally bundled by default - for example an OpenLayer or chart component.

EmilStenstrom commented 3 years ago

@danjac This wouldn't be a replacement for the CSS/JS that you need for the rest of the site. More a request-local optimization, to avoid sending 50 external files if the current page users 25 components. Instead, you would send one component-bundle, that is specific to the components that this page needs.

In your OpenLayer example, that would mean your OpenLayer CSS would be bundled together with your Dynamic SVG component, but only for that specific view.

Does that make more sense?

danjac commented 3 years ago

Yes: makes more sense. It might be something you would want to configure/opt out of however in case people have their own build setup.

EmilStenstrom commented 3 years ago

Are we not already disrupting their build setup by referencing files by direct path instead of going through staticfiles?

danjac commented 3 years ago

Components media currently works same way as forms doesn't it? (Not sure as I don't use components with own JS/CSS).

EmilStenstrom commented 3 years ago

They do, and I was very unsure of how they coexist with for instance staticfiles. Luckily, the docs say:

If the django.contrib.staticfiles app is installed, it will be used to serve assets.

Whether or not you use django.contrib.staticfiles, the STATIC_URL and STATIC_ROOT settings are required to render a complete web page.

To find the appropriate prefix to use, Django will check if the STATIC_URL setting is not None and automatically fall back to using MEDIA_URL. For example, if the MEDIA_URL for your site was 'http://uploads.example.com/' and STATIC_URL was None:

Documentation: Form Assets

I've read up on some of the popular asset management libraries, and they all seem to support form media in some form or other. So I rest my case, this does not need to exist inside django-components.

I would like to add a section in the docs explaining how to do this with one of the more popular external libraries.

hanifbirgani commented 3 years ago

I've found this package, and I think it might solve the problem within the django itself without using other bundler tools: https://django-compressor.readthedocs.io/en/latest/usage

EmilStenstrom commented 3 years ago

Yes, that's a good example, there are many! https://djangopackages.org/grids/g/asset-managers/

This issue is really about testing and documenting how django-components can be used with one or two of them.