* Not really everything.
Imports Are Required**
In the AS2 days, you could get around having to write an import
statement by simply using the fully-qualified class name within the class body (such as flash.display.Sprite
as opposed to just Sprite
). While you are welcome to use the fully-qualified class name as you write your code, import
statements for each class are required in AS3.
So there's not a whole lot of need to write fully-qualified class names, unless you happen to use two classes that share the same short name within the same class — perhaps if you are using Flash's Camera
class along with a 3D library's Camera
class.
** Unless the Class is in the Same Package
The exception to the previous rule is if the class you are using and the class you are writing are both in the same package. All classes in a package are implicitly available to each other, without an import
statement.
It's still not a bad idea to write the import
statement anyway, because:
Import Statements Are Self-Documenting Code
By listing all of your imports, you create a sort of manifest of what other classes your class relies on in order to do its job. It may seem like a trivial thing, but this information can actually be quite useful. Consider the following class***:
package com.activetuts { import com.activetuts.SuperTrace; import com.activetuts.ActiveTween; public class QuickTip { public function QuickTip { var tracer:SuperTrace = new SuperTrace(); tracer.log("Quick Tip"); var tween:ActiveTween = new ActiveTween(); tween.go(); } } }
*** Hopefully it's obvious that this class is illustrative, not functional.
If you then use this QuickTip
class, Flash will automatically make sure that the SuperTrace
and ActiveTween
classes are also compiled into the resulting SWF, because you used QuickTip
, and QuickTip
requires these classes.
Simple enough, but now consider more realistic classes which use dozens of other classes. If you need to know which classes are in use, a quick look at the import
section can give you a decent idea. It's not exhaustive, and it's a little misleading even, but you'll be hard-pressed to find someone who thinks that self-documenting code is a bad thing.
flash
Classes Need Importing, But Are Not Compiled
There is a common misconception around the idea that using lots of classes necessarily means the file size of your SWF will increase. Normally, that's true. But any class that starts with flash
is one provided by the Flash Player, and will not have any effect on the size of your SWF. The byte code for, say, Sprite
is contained in the Flash Player, and you're simply registering the fact that you will use a Sprite, not bundling that byte code into your SWF. This is kind of the point of having the Flash Player.
I don't expect you to believe me on this. I expect you to be slightly incredulous, and demand proof. I welcome you to prove this to yourself, by following these steps:
- Create a new FLA and associated document class.
-
In the document class, write the minimum you need to actually define it as a document class:
package { import flash.display.Sprite; public class Document extends Sprite { public function Document() { } } }
- Open up the Publish Settings by pressing Option-Shift-F12 / Alt-Shift-F12 (or by choosing File > Publish Settings...).
- Click on the "Flash" tab.
- In the "Advanced" section, check the "Generate size report" option.
- Also, in the "SWF Settings" section, check the "Export SWC" option, an uncheck the "Include XMP metadata" option (this last option removes a bunch of metadata from the SWF that inflates the size of the SWF and also make a mess of the size report we'll be looking at).
- Press Control/Command-Enter to Test the Movie.
- Press Control/Command-B to open up the Bandwidth Profiler (also available under View > Bandwidth Profiler while viewing the SWF)
- Notice the number of bytes this SWF is (mine is currently 354, your mileage may vary, but it'll be in that ballpark). Be sure to note the bytes, and not the Kilobytes. Remember this number.
- Close the SWF.
-
Edit your document class to use a bunch of
flash
classes. For example:package { import flash.display.*; import flash.media.*; import flash.net.*; import flash.text.*; public class Document extends MovieClip { public function Document() { var l:Loader = new Loader(); l.load(new URLRequest("someasset.swf")); var tf:TextField = new TextField(); var format:TextFormat = new TextFormat("Verdana"); format.align = TextFormatAlign.CENTER; tf.defaultTextFormat = format; var v:Video = new Video(); var s:Sound = new Sound(); var channel:SoundChannel = s.play(); } } }
We're using quite a few classes, which themselves incorporate even more classes. All of these classes, though, are
flash
classes. - Test the Movie again. The Bandwidth Profiler should still be open from last time; if not, open it again.
- Note the size of the SWF: I'm reporting 596 bytes with the above code, an increase of 242 bytes. That's not a lot considering that I'm using
MovieClip
(which extends a whole bunch of other classes),Loader
,URLRequest
,TextField
,TextFormat
,TextFormatAlign
,Video
,Sound
, andSoundChannel
. That's a lot of functionality for 242 bytes. -
In the Output panel, you'll see something like the following (if you used the above code verbatim, you'll also see sound and load errors, but those aren't important):
flash-test.swf Movie Report ---------------------------- Frame # Frame Bytes Total Bytes Scene ------- ----------- ----------- ----- 1 598 598 Scene 1 (AS 3.0 Classes Export Frame) Scene Shape Bytes Text Bytes ActionScript Bytes ------- ----------- ---------- ------------------ Scene 1 0 0 546 ActionScript Bytes Location ------------------ -------- 546 Scene 1:Frame 1:Document
This test should illustrate that, even though we have used many Flash-provided classes, the resulting size of our SWF is comparatively small. The proof comes with the size report, though, in which we see no entries for any of the built-in classes. We see our Document
class but no other classes, and that one class is responsible for all ActionScript bytes.
If this is not enough proof for you, feel free to expand on the experiment. You could add even more Flash-provided classes, while measuring the increase in the size of the SWF as still be just a matter of bytes. You could incorporate classes of your own, and make sure they appear in the list of classes, and also affect the size of the SWF in a more obvious way. For example, I created this simple Test
class:
package { public class Test { public function Test() { trace("TEST"); } } }
Including this single, 7-line class, which uses no other classes itself, bumped my test SWF to 717 bytes, an increase of 121 bytes. This increase is half of the increase we saw when adding all of those flash
classes; the byte-to-functionality ratio should indicate that the flash
classes are not compiled into your SWF.
Note, too, that you'll see an additional entry in the size report for the extra class; something like this:
flash-test.swf Movie Report ---------------------------- Frame # Frame Bytes Total Bytes Scene ------- ----------- ----------- ----- 1 719 719 Scene 1 (AS 3.0 Classes Export Frame) Scene Shape Bytes Text Bytes ActionScript Bytes ------- ----------- ---------- ------------------ Scene 1 0 0 673 ActionScript Bytes Location ------------------ -------- 179 Scene 1:Frame 1:Test 494 Scene 1:Frame 1:Document
The moral of the story: feel free to use as many flash
classes as you want****. They will not affect the size of your SWF (although the code that uses those classes will, of course)
**** Keep in mind that components and Flex classes are not provided by the Flash Player. These classes appear to be integrated, but if the package does not start with flash
, then it's not provided by the Player.
Wildcard Imports are Not Inefficient
I'm sorry for the double-negative*****, but this is another common misconception that I'd like to clear up.
First, a quick definition. A wildcard import is one that looks like this:
import flash.display.*;
This makes available all classes within the flash.display
package. This is shorthand compared to (for example):
import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMode; import flash.display.Graphics; import flash.display.Sprite;
Now, the misconception. When I say, "this makes available all classes," I do NOT mean that every class in that package is automatically compiled into your SWF. I mean that any class in that package is available to you in short-name form as you write the class. So in the preceding example, I would be free to write this:
var sp:Sprite = new Sprite; var g:Graphics = sp.graphics; g.beginFill(0); g.drawRect(0, 0, 100, 100); sp.blendMode = BlendMode.MULTIPLY;
That code uses Sprite, Graphics, and BlendMode, all of which are in the flash.display package, and all of which need imported. Either approach has the same result. Feel free to use wild card imports.
Again, a simple experiment for those who require proof. For this experiment, we need non-flash
classes. You will need to have external classes available, either ones you've written, or something like Papervision3D or TweenMax. I won't get into downloading and installing these packages, but for the purposes of my sample code I'll be using a simple package of four classes created for this purpose. You can find them, along with test files, in the download package, in the "wildcard-import" folder. The classes are in the library
package.
- Create a new FLA, and associated document class.
- In your code, import a single class. For example:
import library.One
. - And be sure to use it, such as with
var o:One = new One();
- Test the Movie (press Command-Return / Control-Enter, or go to Control > Test Movie).
- Open the Bandwidth Profiler with the SWF running (press Command-B / Control-B or go to View > Bandwidth Profiler)
- Note the size of the SWF (again, in bytes, not Kilobytes).
- Close the SWF
- Edit your document class so that the import uses a wild card instead. For example:
import library.*;
- Test the Movie again.
- Note the size of the SWF. It should be identical as last time.
- You can also enable the size report (don't forget to turn on the SWC option and turn off the XMP option) to see which classes are getting compiled.
This should indicate that even though it sort of looks like we're importing everything from the package, we're really only compiling the classes we actually use.
***** No, I'm not
An Import Statement Alone Will Not Compile the Class
That is, in this following hypothetical example:
package { import SuperTrace; import ActiveTween; public class QuickTip { public function QuickTip() { } } }
The SuperTrace
and ActiveTween
classes are imported. But they are never used within the class. The Flash compiler is usually smart enough to figure this out, and determine that those two classes need not be compiled for the QuickTip
class.
Of course, if another class does use the SuperTrace
class, then it will be compiled. The point is that the compiler is pretty good at not including unneeded classes in your SWF.
You can prove this by setting up a test similar to the previous tests: compare both the byte size and the size reports of two SWFs that are identical except for the usage of an imported class. You can see such an example by comparing the "import-without-use" and "import-with-use" projects included in the source zip.
If, for some reason, you need to ensure that the SuperTrace
and ActiveTween
classes compile, even if you're not using them in this class, you can force that by simply referencing them in the body of the class. For example:
package com.activetuts { import com.activetuts.SuperTrace; import com.activetuts.ActiveTween; public class QuickTip { public function QuickTip { SuperTrace; ActiveTween; } } }
That's enough to get the compiler to see these as needed classes, even though the lines don't do much when the code is run.
Comments