In creating Flash content for the web you are given the ability to push new versions of your application by merely overwriting your .swfs on your server. However, your .swfs are served by the rules of the browser that they are hosted in on the client’s system. It is important to understand that this end client application requests new content based on rules of it’s application settings.
A browser may request new .swfs everytime it hits your site (not caching anything) or it may follow some other rule of content purging(based on total content cached etc.). Therefore, it is important that when you overwrite an application .swf that you force it to update on a client system. If you understand how an browser treats document requests this is quite an easy task. A normal document request may look like http://www.foo.com/foo.swf, where foo.swf is the document requested. If you append what is called a query string to the end of that request, you can request the same document but send data to it like http://www.foo.com/foo.swf?APPVERSION=1.23. Interestingly enough, each unique query string added treats the request as a new one, forcing the document to be loaded again. With this knowledge, you can see that if I add APPVERSION=1.24 that I will get a new .swf, and 1.25 a new .swf, etc. However, due to caching once I download the .swf and the url doesn’t change on the next request the .swf is cached until it is purged by a changed request or settings purge. This behavior allows you to force updates to your users when they make requests by merely adding a versioning variable to the source tags in the embed and object code for your .swf, and in addition to efficiently cache .swfs as well. Caching is important, for instance if the client has a slow connection, say 56k and the file is 150kb. If the .swf hasn’t changed they will have to wait to download it each time they visit your site. On the other hand if it is cached on a version basis then they can use a cached version of the base .swf and only load ondemand needed items (data requests, etc.). If you use a content versioning system like CVS, you can easily use the current document version as the version for your swf update. This allows you to be in sync with your system and automate this versioning methodology if you have a formal build script/process.
Another important thing to point out is the FlashVars attribute. This html attribue also allows you to pass information into your .swf. This is an important attribute and should be used to pass all data in. By using the FlashVars attribute all data passed in is sent in to the currently cached .swf, it doesn’t force an update of the .swf. If however, you use a query string to pass all your data in, it will force the .swf to be purged anytime you change a variable. This could be bad, if for instance, you had a 100kb swf that had a var which changed constantly. The constantly changing var would cause the 100kb .swf to be served on every request instead of being efficiently cached. If your site was heavily hit, your servers would have to work harder.
[UPDATE] I forgot to mention how to send data into a Flash 5 swf. For those looking for a high adoption rate with Flash 5, you can not use Flash Vars, because it is a Flash 6 feature. In these cases you have to append your data to the query string of your embed. This does not mean that you are at a loss and will have no way of getting around loading the swf everytime. There is a trick you can play. This trick involves putting a proxy swf in the embed that in turn loads your application. The proxy is a blank swf with the simple purpose of loading your swf and maintaining passed in parameters. You app swf is versioned by the proxy appending the version query to its loadMovie operation. The app swf once loaded can then access all the html parameters by referencing them in the proxy. This allows you to have a swf (the proxy) that is less than 1 kb that takes the non cache hit, making it minimal. The application swf is still cached and can access the passed in values.
Hopefully, my explanation is clear and helps out. Post if you have any questions.

Subscribe to RSS
#1 by mason - January 10th, 2005 at 09:25
Nice write-up there Mr. Bunch. Caching is defiantly a huge issue in Flash development. So much so that recently its been one of the selling points / benefits people have been talking about for doing Flex development. –which for me, I don’t quite buy… (in more ways than one) Calling the version from the embed tag is a very easy and elegant way to go. Its not a solve all but its a good start.
#2 by Guy Watson - January 10th, 2005 at 10:25
Cheers Kenny.
It’s good practice, to write out your object/embed tags with javascript during development, and append a unique string to the query string to ensure visitors always see the latest release. Especially when you have testers, checking the application while your building it.
"mymovie.swf?rn="+new Date().getTime()+(Math.random()*100)*/
its it highly improbable that the resulting query string will ever be the same twice, even if the user changes their system time due to the extra addition of a random number at the end
*/
#3 by Kenny Bunch - January 10th, 2005 at 10:38
Guy,
Good point about writing out the object/embed with js. I actually have a custom js class that I use to write out all my .swfs. However, be careful with using a unique # everytime in the embed code. The reason I say this is server and client efficiency. For the server, if you are having to serve the same file everytime and noone is caching it, and you have tons of concurrent requests your server is going to have to do more especially if the files are large. More importantly, (and I forgot to mention in my post, which I’ll probably edit in) if the client has a slow connection, say 56k and the file is 150kb which I consider to be large they will have to wait to download it each time they visit your site. On the other hand if it is cached on a version basis then they can use a cached version of the base .swf and only load ondemand needed items in the .swf. Make sense?
#4 by casey corcoran - January 10th, 2005 at 11:21
I was reading this and just thought, “I could probably just use some server side script to get the mod date of the swf and append it to the query string…”
That way you wouldnt have to worry about versioning your swf by hand, good idea?
#5 by Kenny Bunch - January 10th, 2005 at 11:31
Casey,
Exactly. Mod date is a smart method to automate to. I sync mine with the CVS version just so I can look and have a visual indicator to know which version is out there. It’s a personal preference, but you definitely get the point.
#6 by Guy Watson - January 10th, 2005 at 12:16
You also have to remember that the page that contains the .swf will still be cached (even if you add various no-cache headers on the server-side) and any .swfs loaded into the main movie will also be cached unless you also add a random query string:
my_mc.loadMovie("myMovie.swf?rn="+new Date().getTime()+(Math.random()*100))
Kenny, very true, but during development this is not an issue. Its also an issue that is merley a shortcoming if you actually want to ensure that people always see the latest content/application/flash movie on your website. You have to weigh up the pro’s and the con’s and decide which way to go.
Also remember that this can be done with any type of content, including movies, sounds and images both inside of flash and in html.
#7 by Richard Leggett - January 10th, 2005 at 12:52
Very cool stuff, haven’t tried syncing with CVS yet. I use the “?version=X.XX” when it comes to the object/embed tags for the main movie, but when it comes to loading in sub movies. I decided to put together a simple little utility class to help:
http://www.richardleggett.co.uk/downloads/flash/CacheKiller/CacheKiller.as
So I use it like this:
var subs_array = ["one.swf", "two.swf"];
if (CacheKiller.isOnline()) CacheKiller.fixArray(subs_array);
Seems to work quite well, but it does suffer from the “always having to reload content” issue, however I usually find the main site/navigation (which IS version controlled) is the heftiest in terms of kB’s anyway, so no big issue
#8 by Kenny Bunch - January 10th, 2005 at 12:53
Guy,
Right. In the main movie if you are loading assets you have to have a versioning scheme or something to force updates of assets as they face all the same issues. I use a unique ID on all data requests internal to the base swf to ensure clean requests when I need to. During internal dev and testing, unique requests are fine. Versioning and caching becomes more of an issue in a high profile production environment. For example, on CNN.com I may have an app that I put out there, but 3 months later they add features to it. I use the versioning system to enforce it caches, but it updates on clients when I add the new release with its versioning. I couldn’t have it not cache because I need the efficiency of the base caching. Of course, all this I’m describing depends on what you are doing and who you are serving to.
PS. why the Math.random()*100 on your call? new Date().getTime() returns a unique millisecond # which should be sufficient, what’s the extra expression for?
#9 by Aran Rhee - February 3rd, 2005 at 19:39
Just a little reminder about flashVars which wasn’t covered.
It is only available on flash v6+ So for anyone still having to do a flash 5 project ( for whatever reason), you have to use the query string method. If I know I am targeting the to the widest audience, I include flashVars as well as a querystring in the object/embed tags.
#10 by Kenny Bunch - February 8th, 2005 at 13:02
Aran,
I haven’t had to deal with Flash 5 in a while, but you should never put variant parameters (those that change a lot) as query strings on the actual load of your app. I updated my post with a way of doing this with a proxy swf that gets around the issue.
#11 by lingie - July 30th, 2008 at 09:49
Wow – this is a really really helpful post! I’ve been looking for this information for a few days, so I’m glad to have come across it!
Thanks!