Look Ma! No Resource Registries

I'm pleased to announce the availability of collective.lazysizes 4.1.1.1, Plone's integration with lazysizes, a fast, SEO-friendly and self-initializing lazyloader for images (including responsive images), iframes and more.

this new release marks a breakthrough point in our add-ons history as is the first to implement a new and very opinionated approach to get rid of the resource registries in Plone.

you can read about it in this blog post:

collective.lazysizes is in production in many high-traffic sites and by using it you can expect reductions of up to 80% in load time, 75% in page size and 50% in number of requests.

more information:

5 Likes

You might need just a little more context on what it does. I didn't work out what it was doing until I looked at the example sites. ie that it makes the site not load any images until they come into view. Still not sure how the "size" part comes into it.

Also might need more explanation. I haven't really understood yet how a plugin using a viewlet to insert js links prevents dependency problems between different versions of the same library?

the point of this thread was not talking about lazysizes (you can learn about that on their site), but to talk about the deprecation of the resource registries in our add-ons.

to understand the sizes part, read their documentation: it's all about full cross browser responsive image support, something that may no longer be an issue with modern browsers.

that's webpack job. download the source code and run buildout to understand what we're doing; check the configuration files:

this is really a very simple example of what can be done and we're currently working on the same direction with collective.cover.

for add-ons it will be hard to load the same library many times, but in the long run I don't care about it: as I have mentioned many times, bundling all resources in one huge CSS or JS is not going to make your site faster. I can achieve better performance just by preventing loading unnecessary content (the goal of this add-on).

we're just starting to play with this; we can add, for instance, a caching header to let the browser and intermediate caches store our resources forever.

I think @rodfersou can help in case you have more in depth questions with webpack.

I was referring to lazysizes documentation not being obvious what it does.

That only solves things if everything uses webpack. Plone doesn't. So for the moment it doesn't seem to solve much.
The problem that needs solving is how to have a multi tenanted platform where any site can activate any combination of plugins and themes and have them work together when the dependency management systems require command line tools like webpack. I solve this by just avoiding plugins that have JS like yours and instead bake it all into my theme using webpack. But it's not a great solution either.

I think you're still not understanding what are we doing and why are we doing it; so, let me explain again:

first, as I mentioned before, this is a very opinionated approach: I don't want neither one single huge JS file including all the code, nor a single CSS one.

why? because, as I've been saying since early 2017, that's a bad idea in HTTP/2 times and is, by no means, a feature that a Python-based CMS must address.

that is, again, my opinion; you can agree with it or not, but I need to make it clear so people understand why we're doing what we're doing.

what problems are we solving? first, the usage of state-of-the-art, modern JavaScript tools to get our job done; second, to get rid of all the complex burden associated with registering and maintaining plugins that use JavaScript and CSS in Plone.

I don't want to define what tools other people must use and I don't want to fix Plone resource registries anymore. I just want to make my life easier and this approach is a very simple and effective step on that direction.

now, if you understand that, you can freely criticize this approach with more specific claims; I would really appreciate it.

for instance, you can ask why we are registering the viewlet in plone.htmlhead and not in plone.footer; that could be a good question to ask as performance reporters like Google PageSpeed Insights and YSlow always complain about this.

well, that was on purpose: people may get rid of Plone footer's on Diazo and disable our features by mistake.

another thing that others (like @thet) have noticed is that we're not including webpack's output in version control, but only on eggs. we're are doing that for the same reason we don't include compiled translations neither.

and this is something that is usual current practice in Plone community now, one that I think must change as we are only polluting the VCS and making life harder to every one.

just check at the number of files added/modified in some recent pull requests that came into my attention:

this is insane and must end for the sake of Belgian beer.

1 Like

Hinting at a revival?

1 Like

I don’t think sake and Belgian beer mix well but am willing to try

1 Like

That's one of the best posts I've read recently.

1 Like

see how easy was to fix one issue and upgrade the JS library used in this add-on:

1 Like

we have released collective.lazysizes 4.1.4 including some changes in the way we're using webpack to avoid an error in Plone 5 environments reported recently by @thet (Mismatched anonymous define() module).

I can't explain why this is needed as I don't understand the whole thing, but this is what we're using now:

we have also released sc.recipe.staticresources 1.1b5 including new features, like an intermediate caching step for modules that speeds up bundle generation, using HardSourceWebpackPlugin.

if you're also using webpack, this is a must have.

1 Like

Well, after some studies, I got some glue on what is going on in Plone 5 environments:

  1. output.libraryExport = 'default': this options was needed due a wrong assumption in our library configuration, and we can safety remove it changing a little bit our configuration.
  2. Mismatched anonymous define() module: This bug can be fixed adding the option output.libraryTarget = 'umd' and output.umdNamedDefine = true, but this lead to another problem.. RequireJS compatible libraries (UMD and AMD) work different from our addons, it don't execute the code while not required, and this makes some initialization code don't run (for example jquery document ready event is not assigned), what make me think again if a library is what we need.
  3. output.libraryTarget = 'var': In other hand, this option give us the best of the two worlds, we can access our library modules outside the library code (to integrate with youtube api for example we have an use case that need this), extending the code, or maybe it is even possible to do a monkey patch, and also it is possible to run some initialization code. Since now, the only little drawback noticed is that the library is added in a global variable with the library name, what I don't see like a problem in our addons use case.