开发者

ASP.NET: How to enforce a reload of a web static file

开发者 https://www.devze.com 2023-01-07 13:07 出处:网络
When doing webpages, the client/browser decides if it updates a file like an image or .css or .js or if it takes that from the Cache.

When doing webpages, the client/browser decides if it updates a file like an image or .css or .js or if it takes that from the Cache.

In case of .aspx page it is the server who decides.

Sure, on IIS level or also using some HttpModule techniques I can change the headers of requests to tell the client if and how long a file should be cached.

Now, I do have a website where the .aspx goes hand-in-hand with a corresponding .js. So, perhaps I have some jQuery code in the .js which accesses an element in the .aspx. If I remove that element from the .aspx I would also adapt the .js. If the user goes to my page he will get the new .aspx but he might still get the old .js, leading to funny effects.

My site uses lots of scripts and lots of images. For performance reasons I configured in the IIS that those files "never" expire.

Now, from time to time a file DOES change and I want to make sure that users get the update files.

In the beginning I helped myself by renaming the files. So, I had SkriptV1.js and SkriptV2.js and so on. That's about the worst option since the repository history is broken and I need to adapt both the references and the file name.

Now, I improved here and change only the references by using Skript.js?v=1 or Skript.js?v=2. That forces the client to refresh the files. It works fine, but still I have to adapt the references.

Now, there is a further improvement here like this:

<script type='text/javascript' src='../scripts/<%# GetScriptLastModified("MyScript.js") %>'></script>

So, the "GetScriptLastModified" will append the ?v= parameter like this:

protected string GetScriptLastModified(string FileName)
{
    string File4Info = System.Threading.Thread.GetDomain().BaseDirectory + @"scripts\" + FileName;
    System.IO.FileInfo fileInfo = new System.IO.FileInfo(File4Info);
    return FileName + "?v=" + fileInfo.LastWriteTime.GetHashCode().ToString();
}

So, the rendered .js-Link would look like this to the client:

<script type='text/javascript' src='/scripts/GamesCharts.js?v=1377815076'></script>

The link will c开发者_高级运维hange every time, when I upload a new version and I can be sure that the user immediately gets a new script or image when I change it.

Now, two questions: a) Is there a more elegant way to achieve this? b) If not: Has someone a guess how big the performance overhead on the server would be? There can be easily 50 versioned elements on one page, so for one .aspx the GetScriptLastModified would be invoked 50 times.

Looking forward to a discussion :)


There are a few different answers to this question.

First of all, if you have files which only change every once in a while, set the Expires and Cache-Control headers to expire in one year. Only if the files truly never expire should you say that they never expire. You're seeing the issues with saying "never expire" right now.

Also, if you are having performance issues on your site from serving up lots of images and JavaScript, the commonly accepted solution is to use a CDN (Content Delivery Network). There are many different providers and I'm sure that you can find one that meets your budget. You'll also save money in the long run as the CDN will offload a great deal of I/O and CPU time from IIS. It's astounding how big of a difference it can make.

Lastly, one way to make sure that users are getting the latest for your files which almost never change is to implement some sort of versioning scheme in your assets URLs to make cache busting happen. There are many different ways to do this, but one (very naive) way to do it is to have a version number that increases every time you deploy to your site.

E.g. all your asset URLs will look like /static/123/img/dog_and_pony.jpg

Then, next time you deploy to your site, you increase the version number so that it's "124". You would need some way to keep track of the version, dynamically injecting it into asset URLs, as well as making sure that the version number changes every time you deploy. The idea being that anything referencing this asset should automatically know the new version number.

In terms of performance, it's an admirable goal to never need the user to refresh or have to download the same thing twice. But sometimes it's just a lot less hassle, and if users are only refreshing everything periodically, that's probably okay for most websites.

Hope this helps.

0

精彩评论

暂无评论...
验证码 换一张
取 消