Howto: Improve performance by enabling client side caching of static resources

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
12 years ago
I thought I'd share my experience of enabling client side caching of static resources, such as jpg and js files, meaning the client browser will keep them in cache between page requests (like you would expect it to work out of the box).

First off, when using http://tools.pingdom.com as well as Firebug I discovered that the static resources were in fact not cached. To correct this, all that was required was to insert a section into Web.config (in the nopCommerce root catalog of the deployed site, or in the Nop.Web project root).

I added the following code into Web.config. This allows each of the specified resources to be cached at the client for maximum 8 days.

  <system.webServer>
  ...
    <caching>
      <profiles>
        <add extension=".png" policy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
        <add extension=".gif" policy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
        <add extension=".jpg" policy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
        <add extension=".js" policy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
        <add extension=".css" policy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
        <add extension=".axd" kernelCachePolicy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
      </profiles>
    </caching>
    <httpProtocol allowKeepAlive="true">
      <customHeaders>
        <add name="Cache-Control" value="public, max-age=691200" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>


The improvement was seen on the second request, where 20 or so files were already in cache, and load time went from 1.2s to 0.6s.

The second change I made was to use CDN (Content Delivery Networks) for the core javascripts, boosting parallel downloading of resources, as well as the chance that the users web browser already has the requested file in cache.

For example, I replaced the following from Views\Shared\_Root.cshtml
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery-ui.min.js")" type="text/javascript"></script>

with
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>


And you may find the following to work too for the ajax references:
<script src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js" type="text/javascript"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/3.0/MicrosoftMvcAjax.js" type="text/javascript"></script>


And the validation:
<script src="//ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js" type="text/javascript"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>


Maybe these changes could find themselves in a future release of nopCommerce? (I'm using v2.30)

Hope this helps someone wanting to fine tune their performance!

EDIT: The file I didn't find on CDN was jquery.validate.min.js, not jquery.validate.unobtrusive.min.js as I first wrote.
EDIT2: Link to jquery.validate.min.js added above.
12 years ago
wezzix wrote:
<script src="//ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
...
I did however not find a CDN serving the "jquery.validate.unobtrusive.min.js" file, so please let me know if you find one.

Didn't you post it above?
12 years ago
My bad. The file I didn't find on a CDN was jquery.validate.min.js, not jquery.validate.unobtrusive.min.js as I first  wrote (post edited).
12 years ago
wezzix wrote:
My bad. The file I didn't find on a CDN was jquery.validate.min.js, not jquery.validate.unobtrusive.min.js as I first  wrote (post edited).

http://www.asp.net/ajaxlibrary/cdn.ashx#jQuery_Validation_Releases_on_the_CDN_2
12 years ago
Great, thanks!

I added:
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js" type="text/javascript"></script>
12 years ago
I tried following this howto but ran into some weird results.

Specifically it would seem that the pages themselves are being cached. As such you cannot logout properly and the admin side of things has data in fields that does not belong.

I remove these lines from the web.config and everything starts working again.

Any ideas?
12 years ago
Hi,

I'm experiencing the same problem of caching.

As soon as this part is added to the web.config :
   <httpProtocol allowKeepAlive="true">
      <customHeaders>
        <add name="Cache-Control" value="public, max-age=691200" />
      </customHeaders>
   </httpProtocol>

I get the strange behavior you describe : pages in backoffice don't refresh, switching languages becomes impossible,...
Once removed everything comes back to normal.

Any idea why ?

Thanks for your help. Best regards,
Arnaud
12 years ago
wezzix wrote:
I thought I'd share my experience of enabling client side caching of static resources, such as jpg and js files, meaning the client browser will keep them in cache between page requests (like you would expect it to work out of the box).

First off, when using http://tools.pingdom.com as well as Firebug I discovered that the static resources were in fact not cached. To correct this, all that was required was to insert a section into Web.config (in the nopCommerce root catalog of the deployed site, or in the Nop.Web project root).

I added the following code into Web.config. This allows each of the specified resources to be cached at the client for maximum 8 days.

  <system.webServer>
  ...
    <caching>
      <profiles>
        <add extension=".png" policy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
        <add extension=".gif" policy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
        <add extension=".jpg" policy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
        <add extension=".js" policy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
        <add extension=".css" policy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
        <add extension=".axd" kernelCachePolicy="CacheUntilChange" varyByHeaders="User-Agent" location="Client" />
      </profiles>
    </caching>
    <httpProtocol allowKeepAlive="true">
      <customHeaders>
        <add name="Cache-Control" value="public, max-age=691200" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>


The improvement was seen on the second request, where 20 or so files were already in cache, and load time went from 1.2s to 0.6s.

The second change I made was to use CDN (Content Delivery Networks) for the core javascripts, boosting parallel downloading of resources, as well as the chance that the users web browser already has the requested file in cache.

For example, I replaced the following from Views\Shared\_Root.cshtml
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery-ui.min.js")" type="text/javascript"></script>

with
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>


And you may find the following to work too for the ajax references:
<script src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js" type="text/javascript"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/3.0/MicrosoftMvcAjax.js" type="text/javascript"></script>


And the validation:
<script src="//ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js" type="text/javascript"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>


Maybe these changes could find themselves in a future release of nopCommerce? (I'm using v2.30)

Hope this helps someone wanting to fine tune their performance!

EDIT: The file I didn't find on CDN was jquery.validate.min.js, not jquery.validate.unobtrusive.min.js as I first wrote.
EDIT2: Link to jquery.validate.min.js added above.


very weird behaviour after adding product to cart :)
12 years ago
What I did was the following:

<system.webServer>
  <staticContent>
    <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="365.00:00:00" />
    <remove fileExtension=".jpg" />
    <mimeMap fileExtension=".jpg" mimeType="image/jpeg" />
    </staticContent>
</system.webServer>

Of course you can add more extensions to your mimemap.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.