we, at der Freitag, have some ideas on how to improve the frontend performance of our assets (tl;dr; hash every file and put far future headers on them) but we want to reach the wider Plone community to double check if the approach we want to take seems good.
What we have right now
we do some basic bundling (just logged out and logged in) with webpack for all our assets, and we inject on the base template the bundles coming from webpack-plone-plugin (thanks a lot for it @datakurre !!).
When we deploy our theme, we deploy it as an egg, and thanks to yarn.build (sorry for the sameless plug ) we generate all the assets and ship them with the egg where the diazo theme (rules and so on) are.
As we have nginx/varnish/haproxy on front, they are generally cached good enough.
What we are aiming for
- split bundles: separate vendor assets in few bundles, so they can be cached forever
- smaller bundles: so we can deliver them faster and only the needed chunks
- better caching: use content hashes on the filenames so the filename does not change if the contents do not change
Those above are easy to do with webpack alone, in fact, we have that ready. The problems are on the following ones:
- free Plone to serve those files and rather serve them on nginx/something else
- set far future headers on all those assets (doable with some nginx foo)
- one single asset: due to Virtual Host Monster, on webpack we have to put the
++theme++freitag.theme/blala so we can not put a
/ in front and thus resources will be downloaded on every different path (am I right on that? )
- keep old assets for browsers that have stale responses (as we server our assets from our released egg, that one only contains the freshly new build assets), it is somewhat mitigated by the content hashes and smaller and vendor split bundles, but still, as soon as a new release is made, all requests to the older assets will end up in a 404.
How we would approach it right now
We are thinking of creating a storage on the delivery server (i.e. the server that has nginx/varnish/haproxy) so that we can make a tool that at release time of our theme egg, it builds the assets and rather than keeping the files and shipping them on the theme egg, it uploads them there on that storage.
- as the assets will only be pointed to through the diazo theme, as long as the assets upload goes before the theme deployment, no broken links would be generated.
- as the storage is version independent (the problem with releasing the assets on the egg theme) old files would still be reachable
- as the storage is located on nginx-reachable filesystem and with some foo magic URLs can be rerouted there, we free our Plone instances from serving static assets
- as nginx is serving them, we can set far future headers to maximize delivery and second view performance
Sounds that sane? How are you approaching it? On another django project we have, we have been mixing nginx+webpack+whitenoise and the results are really good, check it out yourself (sorry for the second shameless plug ): https://digital.freitag.de
Thanks for your time!