Introduction
Flash movies are known for their small file size and fast download. The movie file itself is compressed, external graphics and sound elements are also often heavily compressed using for example jpeg and mp3. XML files loaded into a Flash movie however are not. This is not a big problem most of the time, but it could be. I will explain one simple way to reduce the file size of XML files to about 30-50% of the original size (in some extreme cases you can reduce them to about 10% of the original file size). If you have a lot of XML files, this could save quite a bit of bandwidth. This technique requires Flash MX or later.
How does it work?
The XML file is compressed using a variation of the LZ77 algorithm. This method is pretty effective and is very fast to decode (which is good since we are dealing with Flash). The encoding is quite CPU intensive though, and it is not ideally done using ActionScript. The Flash XML Compressor is therefore available as a separate program (Windows executable).
ActionScript Prototype
In order for your Flash movie to understand compressed XML files, you need to add the following prototype:
XML.prototype.onData = function(i) { if (i.charAt(0) != '<') { var ecPos = i.indexOf(" ")+1; var eC = i.charAt(ecPos); i = i.substr(ecPos+1); var o = ""; var iL = i.length; for (var n=0;n<iL;n++) { if (i.charAt(n) == eC) { var p = i.charCodeAt(n+1)*114 + i.charCodeAt(n+2) - 1610; var l = i.charCodeAt(n+3)-14; o += o.substr(-p, l); n += 3; } else { o += i.charAt(n); } } this.parseXML(o); } else { this.parseXML(i); } this.onLoad(i != undefined); }
The code above is preferably placed on frame 1 in the movie. You can now load compressed XML files in the same way you load normal XML files. You can still load normal XML files, just make sure you don't have any white space before the <?xml version = "1.0"?>
.
Example .fla
Here is an example you can look at: exampleFLA.zip (22Kb)
It includes a test xml file (48Kb), and the same xml file compressed (14Kb). The xml file contains map data for a game if you were wondering :-)
The Flash XML Compressor - Windows application
Download Version 1.1:
- Windows executable (14Kb zipped)
Note: You need Microsoft .NET Framework installed in order to be able to run the program.
New in version 1.1:
- Fixed a bug which made the compressor fail to compress files over ~20Kb
Usage:
- Simply drag one or more xml files to the compressor window, or select File -> Compress XML File(s).
- By default, new compressed files will be created in the same directory as the original XML files. If you compress a file called myXMLFile.xml, a file called myXMLFileCompressed.xml will be created. If it already exists, it will be overwritten.
- Done! The file is compressed and hopefully much smaller! :-)
You can also convert a compressed file back to the original XML file. Select File -> Decode Compressed File. When the window with the decoded data appears, select File -> Save As to save the decoded data to a file.
Options:
- You can turn on UTF-8 encoding. This will increase the file size a bit, but UTF-8 supports all the unicode characters. You will probably not need to use UTF-8 though.
- Tabs can be stripped before encoding. This is off by default. Note that if a file is compressed with this option turned on, you will not get the tabs back when you decode the file.
- You can turn off automatic file naming of the compressed files in the Options menu if you would rather specify the new file name manually.
Tip:
Place a short cut in Window's "Send To" Context menu. This way you can right click on XML files and choose Send To -> Flash XML Compressor. Here's how:
- Click Start, and then click Run.
- In the Open box, type
sendto
, and then click OK. - Place a short cut to Flash XML Compressor in the sendto folder.
Flash XML Compressor in Java
Java Class (12Kb zipped)
Flash XML Compressor in PHP
Ian Turgeon has ported the encoder to PHP.
File Format and Source Code
Flash XML Compressed File Format 1.0:
- The first 4 characters: v1.0
- The 5th character: Space
- The 6th is the "encoding character". This could be any character which does not appear in the file which is being compressed. I recommend using one of the characters with ASCII value 161-190. If the file uses all the characters in the ASCII table, then that file cannot be compressed. Not very likely this will happen, but this special case should be taken into consideration by the encoder. Not all ASCII values can be used (like the first 32 for example).
- The 7th character and all the characters following are the compressed data
The compressed data looks like the original file data, with one difference: A sequence of at least 5 characters which has appeared earlier in the original data is replaced with 4 characters:
- character 1: the encoding character
- character 2 and 3: position
The position is a number, and it specifies the number of characters back in the original data from the current position where we should start to copy a sequence. Since we only have two characters to store the position in, we can only store 100 values if we were to use base 10. Instead, we use base 114, which will allow us to refer up to 12995 (114*114-1) characters back in the data, which is enough for an effective compression. Note that the position cannot be larger than 114*114-1.
To get the position characters, convert the position from base 10 to base 114, and then add 14 to each of the two digits in the base 114 number. Then convert the two digits to the corresponding ASCII values.
Why the use of base 114? It was the longest sequence in the ASCII table which works in Flash, some characters cannot be converted to the ASCII values in Flash.
- character 4: sequence length
The sequence length number is saved in the same way as the position, but limited to one character, which means it must be less than 114.
C# Encoder Function:
Troubleshoot
Q: The decoding works fine on my computer, but when I upload the compressed xml file to a server the decoded xml data is corrupted.
A: When uploading the compressed xml file, use binary transfer instead of ASCII to make sure the text file format is not converted when uploading.
Other approaches
xml2swf
This is an interesting tool which converts the xml file to a compressed swf (Flash MX and later). You use loadMovie to load the xml data. When the movie has loaded, you can read the xml data which is located in the loaded movie. This is a really neat solution!
HTTP Compression
This is something which will make this tool a bit redundant. It is already supported in many browsers. The content is compressed using gzip before it is sent from the server. The browser uncompresses the data, and the Flash movie doesn't know the difference, but the xml file will load a lot faster!