Using Shared Libraries (SL) in Flash is still quite an adventure, similar to crossing the Pacific Ocean on a surfboard. It theoretically works, but you will need good preparation and be ready to expect trouble. Unfortunately in the past SL were really buggy so lot's of people avoided to use them and didn't touch them since. Let me tell you this: I have built two big sites now that rely heavily on Shared Libraries and I think I can say now: Shared Libraries do work!
For the general use there is some documentation on this on the Macromedia Site: Using shared libraries also the Flashcoders WiKi has quite a lot of stuff to contribute, though some of it is perhaps a little bit outdated.
If you are planning to use Shared Libraries, make sure that you (and your visitors) at least use Flash Player 6.0.65 (6.0.67 for Macs, 6.0.69 for Linux) as Macromedia adressed some issues in that release:
Release Note:
The current limitation of the player is that you can only do one-tier shared libraries (Runtime Shared Libraries to consumer SWF). Developers now have the ability to do multi-tier dependent shared libraries.
Runtime Shared Libraries improvements:
- Support for multi-tier Runtime Shared Libraries.
- Double-byte functionality.
- Ability to handle complex Runtime Shared Libraries including components.
- Timing issues with Runtime Shared Libraries are now resolved.
The principle of a shared library is that you put in all elements that get used by more that one swf movie. This will save you a lot of unnessary reloading of the same data. For example: I add one basic circle to the library and reuse it all the time by scaling and colorizing it. Same with one basic square. The biggest bytesaver is of course to share fonts, but that's a pretty delicate thing which is very nicely described by Branden Hall. There is also a technote by Macromedia themselves: Using Font Symbols
Because the elements in the Shared Library are reused by other movies Flash has to make sure that these elements are present already when the movies need them. That's why it tries to load them at the very beginning. I say it tries, because this process doesn't work all the time if you do it without preparation. What happens (especially in real life dial-up situtations) is that the main swf loads, it discovers that it uses a shared library and starts loading that. But Flash is a streaming format, so instead of waiting for the shared library to finish loading it sometimes continues with the main movie. Now that main movie might request an item from the library which is not loaded yet. Unfortunately that's something which is not defined in the Flash format specifications. Assets have to be present before they are used. In a case like this you will see nothing or the whole movie hangs. So what's the solution? You have to make absolutely positively sure that the shared library has loaded before anything else happens. Which means: use a preloader. Even better: use a preloader movie for the main movie. I'm using the following scheme and until now it works stable:
preloader.swf:
this.createEmptyMovieClip("dummy",0)
this.createEmptyMovieClip("dummy2",1)
this.dummy._visible=this.dummy2._visible=false
this.dummy.loadMovie("shared.swf") //first preload the shared library
this.onEnterFrame=this.preload1
function preload1(){
if (this.dummy.getBytesLoaded()>100){
if(this.dummy.getBytesLoaded()==this.dummy.getBytesTotal()){
this.dummy.loadMovie("main.swf") //also preload the main movie
this.onEnterFrame=this.preload2
} else {
// add some progress display here
}
}
}
function preload2(){
if (this.dummy2.getBytesLoaded()>100){
if(this.dummy2.getBytesLoaded()==this.dummy2.getBytesTotal()){
_level0.loadMovie("main.swf") //now really load and run the main movie
this.onEnterFrame=null
} else {
// add some progress display here
}
}
}
I must admit: using SL still involves sometimes using a little bit of voodoo. For example: I have the habit of using Branden's technique of placing an empty dummy movieclip symbol from the Shared Libray into the first frame of every movie that uses the library. I never checked if it works without that thing, too. Maybe it does, but in this case I go by the old admin's saying: "Never change a running system".
I guess that until here there was nothing new for Shared Library experienced developers. But here's something which might be interesting for you, too:
Mind the cache
I had this strange phenomenon: a few days after the launch of a site I made some changes to the Shared Library. Everything worked fine for me. Only did I receive a few mails from other people that couldn't see anything anymore. It took a while until I asked them about their browser's cache settings. And guess what - in every case it was set to something like "update as seldom as possible". They view the swf which gets served the old library. Of course the internal IDs do not match and flash goes into hibernation mode.
That is indeed a serious problem. Of course I can tell my clients and friends to set their cache to "update on every visit", but I cannot tell that every visitor of a site. The difficulty is that for every normal flash movie, xml or loadVars file you can add a random query string to avoid caching. For the Shared Library you cannot do that as its URL is hardcoded into the swf. So what can you do? Do not change the Shared Library after going live. Haha. Well, I guess that's no solution. If you only need additional symbols and do not need to make changes to existing ones: use a second or third Shared Library. That will mean definitely less work than solution #3: rename the Shared Library. Unfortunately this will mean that you will have to go into every movie that uses this library and edit the URL inside every imported symbol. That's not really fun. I hope Macromedia will find some solution for this in the Future. The best solution would be the ability to dynamically set the name of the Shared Library. Either from the object tag or via actionscript.
Dynamically Shared Libraries
Speaking of Dynamically Shared Libraries. Here is something I haven't read anywhere else. Did you ever think of replacing "sharedlib.swf" with "sharedlib.php"? Why should you? For a normal site this is not really interesting, but if you go multilingual - I mean real multingual, not English, German, French or Italian - I mean Japanese, Russian, Greek, short: if you need different font encodings. Well, then this gets really exiting: instead of doing different swfs or embedding all the fonts you serve different Shared Libraries under the same name. Instead of a static Shared Library you link to a server-side script which serves a different library depending on the country the request comes from. The catch? Unfortunately flash does not include a referrer header when it's downloading the Shared Library. So the PHP script gets no clue from the request itself which language it shall serve. But it knows its own server name. From that it can decide which library to send, is it mysite.com, send shared_western.swf, is it mysite.ru, send shared_cyrillic. Alternatively you could create subdomains: europe.mysite.com, russia.mysite.com, japan.mysite.com. Of course all the domains have to point to the same directory.
It came just to my mind that it might be worth to look into PHP sessions for this purpose - that could lead to a more generic solution which would allow even more flexibility, it might enable you to control which library to serve before the flash file even loads. Something more experimental could be to serve random libraries that use the same symbol or font names, but are different. You could have different templates depending on daytime. That is not tested yet, but I think I should give it a try...
Posted at June 25, 2003 07:15 PM | Further reading
