Static content on subdomains or use ClientDependency?
I am in need of some guidance. I have been asked to create a website that has different domains for static content (images, css and scripts) to make the page load faster.
I will be getting this static content including HTML from my frontend dev and usually I just throw that into umbraco and everything works.
How do I make it as easy as possible to work with the "raw" frontend products on my dev environment and when I deploy it to staging/live server, it will use images.mydomain.com for images, scripts.mydomain.com for scripts and css.mydomain.com for css files? The CSS files will contain links to background images as well, so that would need an update as well then..
Am I looking at creating replace script that I have to run after deploy? That feels like the wrong way to go..
Would it be easier to use the ClientDependency framework to handle this or would that still generate the same amount of request as just using the static files as usual? I must admit I've never really worked with the CD framework so I'm not sure how far I could stretch it.
I don't know about ClientDependency, but you could fetch each content asset with a static method (e.g. GetAssetUrl(string relativePath) defined in e.g. a PageHelper, which uses an AppSetting in your web.config for the url. You can automatically change this AppSetting between local, testing, staging and live environments with web.config transformations.
Like when the appSetting is empty, just use the passed in relativePath, else put the defined subdomain in front of it ;-)
I mean that would be a LOT of work to replace all of the images for very little benefit, don't you think? Besides, all of my HTML would have to be in a macro then, no more master pages..
Well there is another option; use the IIS Url Rewrite module to redirect requests based on the request path: /images/(.+) and redirect it to http://something.domain.com/images/{R:1}
You can still benefit from web.config transformations with this approach (put the rewrite rule in the Web.(Live/Testing/Staging).config) :-)
Rewrites won't really work as intended as the browser will be requesting assets originally from the same domain, sending it cookie information too, only to be told to try again on another domain. Thats wasteful. You'll be loosing some of benefit of what you are trying to achieve here (reduce Http request, cookie less domains, multiple domains).
Using a Content Delivery Network sounds a bit fancy but all we do is use the same server but have multiple domain names bound to it. You have the main one which everyone uses to navigate around and then a totally separate one(s) which all your assets come from. We tend to use totally different domains (rather than just different sub domains) to avoid the risk of cookie information being sent with every request.
For cuttingedgeknives.co.uk as a example we use the main domain and then pull most of the assets off of assets1.offroadcode and assests2.offroadcode. We find having a different subdomain for each type of asset does not give much of an advantage, better to just stagger the sub-domains. Remember multiple domains means you can pull down more files at once. To be nice to servers browsers are meant to limit the requests they do to any one server (or domain name in this instance) to 2. So you can only down load 2 assest from a server. If you have 10 CSS files in a row you'll still be causing a bottle neck if you load them all off css.myserver.com as the browser can still only pull 2 down at a time. If you alternate between 2 asset subdomain in your Link tags though you'll be pulling 4 files down at once, result! The page won't start rendering until its got all the CSS down so speeding this up with multiple domains is a quick win, quicker time to render and domready too.
How to achieve it, well you've already hit on the way to do it. Have some code which works out which domain to glue at the front of each of your asset requests. Is is a lot of work? Depends how you built your site really. Move everything into Macros, you bet. We hardly have anything in Masterpages these days nearly everything is in Macros as we do a lot of this sort of logic in our code and it just makes it easier to manage and share around from within Macros.
We created a simple XSLT template which returns the asset domain name that we want to glue to the front of the asset. This is included in all our other XSLT files so we can use it site wide. If we are developing on local host then it returns an empty string so the asset gets pulled relative. If its on live (which for ease is anything other than localhost) then we render out asset1.offroadcode.com or you can pass in a different asset subdomain as a param. Ideally it is nice to have a way of switching it off on live too incase things go wrong, web.config or an XSLT include are the way to go with that one (or as its you some Razor magic).
Images in your CSS are not a real issue either, if you pull the CSS file from assets1.yourserver.com and the image paths in the CSS are relative then they all get pulled off from the same server. If you have a lot of images in your CSS then we then in the body of our HTML we will use the actual live domain name for any images which helps share the load a little, remember there is nothing wrong with pulling images from our main domain name (other than the overhead of cookie info). Ideally you want about 2-5 domain names to help share the download load from for maximum effect. Cutting Edge Knives loads a lot of content and assets using exactly this setup, we had to to make that image heavy homepage load as fast as it does :)
The above might mean you have to do some hacking around and modifying you code a bit but it will be worth it, the speed increases can be quite dramatic. As I've said everything gets quicker when you can get it down the wire quicker. Domready, rendering, time to first content etc.
Static content on subdomains or use ClientDependency?
I am in need of some guidance. I have been asked to create a website that has different domains for static content (images, css and scripts) to make the page load faster.
I will be getting this static content including HTML from my frontend dev and usually I just throw that into umbraco and everything works.
How do I make it as easy as possible to work with the "raw" frontend products on my dev environment and when I deploy it to staging/live server, it will use images.mydomain.com for images, scripts.mydomain.com for scripts and css.mydomain.com for css files? The CSS files will contain links to background images as well, so that would need an update as well then..
Am I looking at creating replace script that I have to run after deploy? That feels like the wrong way to go..
Would it be easier to use the ClientDependency framework to handle this or would that still generate the same amount of request as just using the static files as usual? I must admit I've never really worked with the CD framework so I'm not sure how far I could stretch it.
Thanks in advance for your advice!
I don't know about ClientDependency, but you could fetch each content asset with a static method (e.g. GetAssetUrl(string relativePath) defined in e.g. a PageHelper, which uses an AppSetting in your web.config for the url. You can automatically change this AppSetting between local, testing, staging and live environments with web.config transformations.
Like when the appSetting is empty, just use the passed in relativePath, else put the defined subdomain in front of it ;-)
I was thinking of something along those lines as well. but won't that make my html look like:
I mean that would be a LOT of work to replace all of the images for very little benefit, don't you think? Besides, all of my HTML would have to be in a macro then, no more master pages..
Well there is another option; use the IIS Url Rewrite module to redirect requests based on the request path: /images/(.+) and redirect it to http://something.domain.com/images/{R:1}
You can still benefit from web.config transformations with this approach (put the rewrite rule in the Web.(Live/Testing/Staging).config) :-)
Not bad, not bad at all! I'm going to have a play with that to see if it's flexible enough..
I'll report back, thanks!
Rewrites won't really work as intended as the browser will be requesting assets originally from the same domain, sending it cookie information too, only to be told to try again on another domain. Thats wasteful. You'll be loosing some of benefit of what you are trying to achieve here (reduce Http request, cookie less domains, multiple domains).
Using a Content Delivery Network sounds a bit fancy but all we do is use the same server but have multiple domain names bound to it. You have the main one which everyone uses to navigate around and then a totally separate one(s) which all your assets come from. We tend to use totally different domains (rather than just different sub domains) to avoid the risk of cookie information being sent with every request.
For cuttingedgeknives.co.uk as a example we use the main domain and then pull most of the assets off of assets1.offroadcode and assests2.offroadcode. We find having a different subdomain for each type of asset does not give much of an advantage, better to just stagger the sub-domains. Remember multiple domains means you can pull down more files at once. To be nice to servers browsers are meant to limit the requests they do to any one server (or domain name in this instance) to 2. So you can only down load 2 assest from a server. If you have 10 CSS files in a row you'll still be causing a bottle neck if you load them all off css.myserver.com as the browser can still only pull 2 down at a time. If you alternate between 2 asset subdomain in your Link tags though you'll be pulling 4 files down at once, result! The page won't start rendering until its got all the CSS down so speeding this up with multiple domains is a quick win, quicker time to render and domready too.
How to achieve it, well you've already hit on the way to do it. Have some code which works out which domain to glue at the front of each of your asset requests. Is is a lot of work? Depends how you built your site really. Move everything into Macros, you bet. We hardly have anything in Masterpages these days nearly everything is in Macros as we do a lot of this sort of logic in our code and it just makes it easier to manage and share around from within Macros.
We created a simple XSLT template which returns the asset domain name that we want to glue to the front of the asset. This is included in all our other XSLT files so we can use it site wide. If we are developing on local host then it returns an empty string so the asset gets pulled relative. If its on live (which for ease is anything other than localhost) then we render out asset1.offroadcode.com or you can pass in a different asset subdomain as a param. Ideally it is nice to have a way of switching it off on live too incase things go wrong, web.config or an XSLT include are the way to go with that one (or as its you some Razor magic).
Images in your CSS are not a real issue either, if you pull the CSS file from assets1.yourserver.com and the image paths in the CSS are relative then they all get pulled off from the same server. If you have a lot of images in your CSS then we then in the body of our HTML we will use the actual live domain name for any images which helps share the load a little, remember there is nothing wrong with pulling images from our main domain name (other than the overhead of cookie info). Ideally you want about 2-5 domain names to help share the download load from for maximum effect. Cutting Edge Knives loads a lot of content and assets using exactly this setup, we had to to make that image heavy homepage load as fast as it does :)
The above might mean you have to do some hacking around and modifying you code a bit but it will be worth it, the speed increases can be quite dramatic. As I've said everything gets quicker when you can get it down the wire quicker. Domready, rendering, time to first content etc.
Hope that helps, any more queries let me know.
Pete
You're right Peter, that's exactly the big downside of using Url Rewriting...
But Sebastiaan is too lazy to replace all image url's in his code ;-))
Anyway, I'd go with the first solution too (Helper method, using the web.config appSetting).
Hey Sebastiaan,
Did you ever figure this out?
I'm just abut to embark on the exact same thing.
is working on a reply...