core-bundle icon indicating copy to clipboard operation
core-bundle copied to clipboard

HTTP/2 optimizations

Open Toflar opened this issue 8 years ago • 25 comments

This is a accumulative ticket collecting all the features/todo's for future versions of Contao to better support HTTP/2 to get the best out of it. The list is not final, I'll just keep updating it, every time something comes to my mind.

  • [x] Must be able to disable concatenation of files in the page layout.
  • [ ] Add support for server hints (server push) using either Link: <https://domain.tld/asset.jpg>; rel=prefetch headers or <link rel="prefetch" href="https://domain.tld/asset.jpg"> <head> tags. Also think about other strategies like preload etc.

Toflar avatar May 10 '16 13:05 Toflar

Must be able to disable concatenation of files in the page layout.

This is actually not a requirement, is it? Just something we could stop doing if everyone used HTTP/2.

leofeyer avatar May 10 '16 15:05 leofeyer

Well then we could also drop the domain sharding settings. But I think we should not drop it but have it configurable.

Toflar avatar May 10 '16 15:05 Toflar

We definitely must not drop it, because currently browsers only support HTTP/2 via HTTPS. And not everybody uses HTTPS (yet).

leofeyer avatar May 10 '16 15:05 leofeyer

Or was it servers that only support it via HTTPS?

leofeyer avatar May 10 '16 15:05 leofeyer

You can strip the "currently", I think that won't change :)

Toflar avatar May 10 '16 15:05 Toflar

Keep in mind the sharding settings are still necessary for CDNs

aschempp avatar May 10 '16 15:05 aschempp

I don't think that's true. Can you elaborate?

Toflar avatar May 10 '16 15:05 Toflar

Serving all static files from a CDN?

aschempp avatar May 10 '16 15:05 aschempp

And how does this relate to our settings? Does not at all. Also, why would you serve the files via CDN but not the page HTML? This is complete nonsense.

Toflar avatar May 10 '16 15:05 Toflar

Looks like you never had that usecase ;-)

aschempp avatar May 10 '16 15:05 aschempp

Looks like you make up a use case that does not exist. That's why I asked you to elaborate.

Toflar avatar May 10 '16 15:05 Toflar

Well I just used that, so it does exist. Dunno whats to explain on "serve static files from CDN"?

aschempp avatar May 10 '16 16:05 aschempp

It makes sense to provide stuff from cdn but not the dynamic content. The usecase for having support for a cdn is real (my cdn is providing the files and I only reference them). However, it is not possible to use the current approach of one global setting, as not all static files are available in the cdn (as Contao creates them but does not publish to the cdn), therefore I had to add my own config option and CDN handling anyway in the past.

Therefore, I do not see any sense in keeping the current approach (unless we have also a mechanism for pushing to the cdn) as sharding is not a cdn.

discordier avatar May 10 '16 16:05 discordier

If you use a CDN you use it as a transparent proxy. You certainly don't upload the files to the CDN but handle the normal page requests via the origin server. What the heck?!?! You just make sure your HTML always has private caching headers if you want to make sure the origin server is always asked for the content. But you don't serve the content from two different servers?

Toflar avatar May 10 '16 16:05 Toflar

My CDN just fetches everything on the fly that is referenced on the website

aschempp avatar May 10 '16 16:05 aschempp

Yeah, your CDN is a transparent proxy in front of the origin server. So you don't even care about the Contao settings? I don't get your comments.

Toflar avatar May 10 '16 16:05 Toflar

There are push or pull CDNs, both cases exist. But I don't think the discussion makes sense...

aschempp avatar May 10 '16 16:05 aschempp

My CDN is a CDN consisting of multiple servers with load balancing and round robin DNS. All static binaries are available from these servers. However, the "page" is dynamic (serving website and API) referencing the CDN for URLs to content (said big binaries). Using a transparent proxy is definately out of question, as it won't be able to handle the traffic. Having the dynamic parts running on every CDN node is also out of question, as these don't even have PHP running but only a "plain and stupid web server".

//edit: therefore the use case exists, I hope you understand now.

discordier avatar May 10 '16 16:05 discordier

I know there are two types of CDN's but this absolutely does not relate to the domain sharding settings of Contao. The pull approach is already possible today because it works as a transparent proxy. If you want to have the push approach, then the settings are pointless. These settings are only domains for assets. So let's say you want to have https://myaccount.keycdn.com/asset/video.mp4 then you would enter https://myaccount.keycdn.com in the assets prefix field but asset/video.mp4 still has to physically exist on the Contao server because otherwise you'll never get that file URL generated by Contao. It's just a prefix for an existing file. Besides the fact that it's complete nonsense to have the file on the same server as Contao in that case, you would also have to track all the path changes users do in the back end. If they move it to whatever/video.mp4 the path will be https://myaccount.keycdn.com/whatever/video.mp4 and KeyCDN won't find shit anymore. Granted, pushing to a CDN makes sense but it has absolutely nothing to do with our prefix domain sharding stuff. If you want to do that, Contao has to support a virtual file system and you'd work e.g. with keycdn://myvideoassetuuidorwhatever as a path. This means it also does not physically exist on the origin server where Contao is hosted. THAT is a whole different story and does not relate to our current sharding settings at all!

Toflar avatar May 10 '16 16:05 Toflar

I totally agree to the last statement, this is exactly what I wrote above regarding that the current setting does not help at all when having a real CDN and therefore the sharding settings can IMO safely be dropped (for Contao 5) as they have become useless.

discordier avatar May 10 '16 16:05 discordier

@Toflar Following up our discussion at the developer's meeting: We do not really need to send HTTP headers, do we? We might as well just add rel="prefetch" to the <link> and <script> tags. Or is this not supported by the web servers?

leofeyer avatar Jul 28 '16 08:07 leofeyer

We might as well just add rel="prefetch" to the <link> and <script> tags. Or is this not supported by the web servers?

According to the spec, both must be supported which does not answer the question whether they actually do ;) But yes, we can as well just add prefetch, that's correct.

Toflar avatar Jul 28 '16 10:07 Toflar

I am reading into HTTP/2 and have a few questions/suggestions. First, @Toflar thank you for your great lecture to HTTP/2 https://www.youtube.com/watch?v=FrSCPiJnbI4

  • I think, DomainSharding will not be necessary with HTTP/2 anymore, but I think for CDN solutions it would not be harmful to further support it.
  • Also, the possibility to combine scripts and style sheets should be further supported. In Contao 4.3 it said "not recommended with HTTP/2", in Contao 4.4.7 it again says it would be "recommended" to combine scripts: image Maybe in the future we should say "recommended unless you use HTTP/2". Edit: Maybe just a translation issue between german and english.
  • It will take a long time until HTTP/2 will be standard everywhere. So until now, we should per default offer this combine functionality and enable "cutting-edge" developers to override this feature (exactily as it is at the moment).

Further recommendations

As far as I understand, the power of HTTP/2 evolves when you use many css/less/scss/script files which you could load dynamically when you need them. You don't need to have one large file; instead, it is better to use smaller and modulated styles/scripts. This means:

  • No combination of scripts/styles (should be deactivated with HTTP/2, implemented)
  • The possibility to set for each style/script:
    • if it should be loaded in a certain page Layout or not (of course already implemented)
    • if it should be implemented by preload (very important basic structure or above-the-fold) or delayed/lazy-load
    • if it should only be implemented when a certain template is loaded (this means: gallery-styles and gallery-scripts only load when the gallery is indeed used).
    • if it should be loaded for mobile/desktop/print (this means: setting of media attributes).

Implementing and loading CSS/Javascript files modularly is the main issue. https://www.viget.com/articles/managing-css-js-http-2

Current Web Developer View

  • Our developers do not use the CSS-Features from Contao (Themes->CSS) as our developers will always use and edit local stored scss-files. We will not use the Contao rule-by-rule definition feature and like to use less/scss rule nesting and scss-functions/mixins.
  • We use(d) an app.scss which combines/imports other sub-files (there is a problem with script combination when Contao does not recognize that a sub-file is changed and thus does not recalculate/recompress the app.scss, but this is another topic)
  • We import the app.scss in the Layout as a single file.
  • In our nested definitions, we use "mobile" functions to change definitions depending on the media size/type. We like it better this way than making a new mobile.scss were we would have to re-build the nested css structure to override some of the style definitions.

Future view

In the future, I could imagine a more elaborate implement mechanism: proposal_style_conditions As you can see, this is a first draft and it is not yet clear how to set the style to be implemented or not. Maybe we can find a hook "if a certain CSS Class is set for an module/template/page/article/element". Or we can work with "if a template with a certain name is implemented on this page". How would we do it with media attributes max-size, screen-size, print, ...?

If we could modularize the styles (and don't forget the scripts), maybe we could directly implement them on the places where they belong (this means, implementing styles directly before the elements within the body tag: https://www.viget.com/articles/managing-css-js-http-2). But, how could we find and manage them best in Contao? Having to navigate to each module to append a scss file and a javascript file? Maybe the possibility for implementing js/scss files for each module is not bad at all. Typing it directly into the template per hand? ugly :/

We need the possibility to rework the TL_SCRIPT and TL_STYLE to set the Styles to preload or to delay and to use media-attributes (per-Style-attribute). And then, Contao should be able to preload or delay the files.

I think, this is so crazy-developer-optimized that perhaps you should have a separate extension for this. 90% of developers would not need this, but it's the future :) @Toflar What do you think?

Push manifest

If I understood correctly, we don't need Push manifests (https://github.com/GoogleChrome/http2-push-manifest) when we tell the Server we need certain files by implementing it with <link rel="preload" ...

Xendiadyon avatar Oct 17 '17 11:10 Xendiadyon

I think, DomainSharding will not be necessary with HTTP/2 anymore, but I think for CDN solutions it would not be harmful to further support it.

I guess you're talking about the file url prefixes. If so, correct.

It will take a long time until HTTP/2 will be standard everywhere. So until now, we should per default offer this combine functionality and enable "cutting-edge" developers to override this feature (exactily as it is at the moment).

I have a different opinion about that. Browser support is extremely good and the world wide http2 server support does not matter because as a developer you know if your server supports it or not and if you need it, you can choose a provider that supports it.

No combination of scripts/styles (should be deactivated with HTTP/2, implemented)

That's not correct. Combining still makes perfect sense. Just don't combine everything into one file anymore but make logical bundles.

To me, everything performance related is very hard to automate. We cannot support things like critical css and all that ATF stuff (a highly controversial issue anyway), preloading, prefetching, dynamic bundling of files, lazy loading stuff etc. out of the box so it works perfectly for everybody. I think we should focus on providing a decent default for simple websites that do not care about all this anyway and allow professional developers to achieve what they want without actually having to configure too much in Contao. A lot of it is already possible today: Just don't use the layout settings for CSS and JS at all and compile/combine/bundle them locally with your favorite tools and refer to them as additional head tags. If you want to force preloading, just add the <link rel="preload"...> to your additional head tags as well. Or adjust the fe_page template accordingly.

Toflar avatar Oct 17 '17 11:10 Toflar

FYI, combining scripts has been re-added in the back end in Contao 4.5. Also the option explanation has been changed to Combine the .css and .js files (recommended)., because it still makes sense to combine scripts that are loaded on every page.

leofeyer avatar Oct 17 '17 11:10 leofeyer