• Flash Optimization – Freezing And Unfreezing Objects

    Flash optimization is becoming increasing important & with alternative development tools that developers can use. We all have a responsibility to build Flash elements that are efficient as much as they are groundbreaking. As someone who feels responsible for the future of this great application, I am creating a Flash Optimization series that will help educate the Flash development community on how to keep their Flash elements as lean as possible.

    To optimize your code, always freeze and unfreeze your objects. Freezing and unfreezing are important for all objects, but are especially important for display objects. Even if display objects are no longer in the display list and are waiting to be garbage collected, they could still be using CPU-intensive code.

    For example, they can still be using Event.ENTER_FRAME. As a result, it is critical to freeze and unfreeze objects properly with the Event.REMOVED_FROM_STAGE and Event.ADDED_TO_STAGE events. The following example shows a movie clip
    playing on stage that interacts with the keyboard:

    
    // Listen to keyboard events
    stage.addEventListener(KeyboardEvent.KEY_DOWN, keyIsDown);
    stage.addEventListener(KeyboardEvent.KEY_UP, keyIsUp);
    
    // Create object to store key states
    var keys:Dictionary = new Dictionary(true);
    
    function keyIsDown(e:KeyboardEvent):void
    {
    // Remember that the key was pressed
    keys[e.keyCode] = true;
    
    if (e.keyCode==Keyboard.LEFT || e.keyCode==Keyboard.RIGHT)
    {
    runningBoy.play();
    }
    }
    
    function keyIsUp(e:KeyboardEvent):void
    {
    // Remember that the key was released
    keys[e.keyCode] = false;
    
    for each (var value:Boolean in keys)
    if ( value ) return;
    runningBoy.stop();
    }
    
    runningBoy.addEventListener(Event.ENTER_FRAME, handleMovement);
    runningBoy.stop();
    
    var currentState:Number = runningBoy.scaleX;
    var speed:Number = 15;
    
    function handleMovement(e:Event):void
    {
    if (keys[Keyboard.RIGHT])
    {
    e.currentTarget.x += speed;
    e.currentTarget.scaleX = currentState;
    } else if (keys[Keyboard.LEFT])
    {
    e.currentTarget.x -= speed;
    e.currentTarget.scaleX = -currentState;
    }
    }
    

    When the Remove button is clicked, the movie clip is removed from the display list:

    
    // Show or remove running boy
    showBtn.addEventListener (MouseEvent.CLICK,showIt);
    removeBtn.addEventListener (MouseEvent.CLICK,removeIt);
    
    function showIt (e:MouseEvent):void
    {
    addChild (runningBoy);
    }
    
    function removeIt(e:MouseEvent):void
    {
    if (contains(runningBoy)) removeChild(runningBoy);
    }
    

    Even when removed from the display list, the movie clip still dispatches the Event.ENTER_FRAME event. The movie
    clip still runs, but it is not rendered. To handle this situation correctly, listen to the proper events and remove event listeners, to prevent CPU-intensive code from being executed:

    
    // Listen to Event.ADDED_TO_STAGE and Event.REMOVED_FROM_STAGE
    runningBoy.addEventListener(Event.ADDED_TO_STAGE,activate);
    runningBoy.addEventListener(Event.REMOVED_FROM_STAGE,deactivate);
    
    function activate(e:Event):void
    {
    // Restart everything
    e.currentTarget.addEventListener(Event.ENTER_FRAME,handleMovement);
    }
    
    function deactivate(e:Event):void
    {
    // Freeze the running boy – consumes fewer CPU resources when not shown
    e.currentTarget.removeEventListener(Event.ENTER_FRAME,handleMovement);
    e.currentTarget.stop();
    }
    

    When the Show button is pressed, the movie clip is restarted, it listens to Event.ENTER_FRAME events again, and the
    keyboard correctly controls the movie clip.

    Note: If a display object is removed from the display list, setting its reference to null after removing it does not ensure that the object is frozen. If the garbage collector doesn’t run, the object continues to consume memory and CPU processing, even though the object is no longer displayed. To make sure that the object consumes the least CPU processing possible, make sure that you completely freeze it when removing it from the display list.

    Since Flash Player 10, if the playhead encounters an empty frame, the display object is automatically frozen even if you did not implement any freezing behavior.

    The concept of freezing is also important when loading remote content with the Loader class. When using the Loader class with Flash Player 9, it was necessary to manually freeze content by listening to the Event.UNLOAD event dispatched by the LoaderInfo object. Every object had to be manually frozen, which was a non-trivial task. Flash Player 10 introduced an important new method on the Loader class called unloadAndStop(). This method allows you to unload a SWF file, automatically freeze every object in the loaded SWF file, and force the garbage collector to run.

    In the following code, the SWF file is loaded and then unloaded using the unload() method, which requires more processing and manual freezing:

    
    var loader:Loader = new Loader();
    
    loader.load ( new URLRequest ( “content.swf” ) );
    
    addChild ( loader );
    
    stage.addEventListener ( MouseEvent.CLICK, unloadSWF );
    
    function unloadSWF ( e:MouseEvent ):void
    {
    // Unload the SWF file with no automatic object deactivation
    // All deactivation must be processed manually
    loader.unload();
    }
    

    A best practice is to use the unloadAndStop() method, which handles the freezing natively and forces the garbage
    collecting process to run
    :

    
    var loader:Loader = new Loader();
    
    loader.load ( new URLRequest ( “content.swf” ) );
    
    addChild ( loader );
    
    stage.addEventListener ( MouseEvent.CLICK, unloadSWF );
    
    function unloadSWF ( e:MouseEvent ):void
    {
    // Unload the SWF file with automatic object deactivation
    // All deactivation is handled automatically
    loader.unloadAndStop();
    }
    

    The following actions occur when the unloadAndStop() method is called:
    • Sounds are stopped.
    • Listeners registered to the SWF file’s main timeline are removed.
    • Timer objects are stopped.
    • Hardware peripheral devices (such as camera and microphone) are released.
    • Every movie clip is stopped.
    • Dispatching of Event.ENTER_FRAME, Event.FRAME_CONSTRUCTED, Event.EXIT_FRAME, Event.ACTIVATE and Event.DEACTIVATE is stopped.

    This entry was posted on Wednesday, April 13th, 2011 at 2:29 pm and is filed under ActionScript, Flash, Tutorials. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

    You might also like

    Flash Optimization – Display Objects Flash optimization is becoming increasing important & with alternative development tools that developers can...
    Flash Optimization – Activate & Deactivate Events Flash optimization is becoming increasing important & with alternative development tools that developers...
    Flash Optimization – Reusing Objects Flash optimization is becoming increasing important & with alternative development tools that developers...
    Flash Optimization – Object Pooling Flash optimization is becoming increasing important & with alternative development tools that developers...
  • 2 Comments

    Take a look at some of the responses we've had to this article.

    1. Valerie
      Posted on June 8th

      I have a moviecllip of a signature playing out on my home page. What I need to do is have the signature FREEZE once played out so that it remains a static image in case the page is revisited. Right now I have a simple stop(); action at the end of the signature…and when the page is revisited, the area of the signature is blank — no static image nor does it replay. So how do I simple FREEZE the movie clip? Flash CS5; AS3

    2. Posted on June 9th

      you can use Bitmap Data Class
      for sample (basic)

      var bitmap:Bitmap = new Bitmap();
      var data:BitmapDAta = new BitmapData( mc.width, mc.height );
      data.draw( mc );
      bitmap.bitmapData = data;
      
      addChild( bitmap );
      

      and read this
      http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/BitmapData.html#draw()

      be successful. :D

  • Post a Comment

    Let us know what you thought.

  • Name:

    Email (required):

    Website:

    Message: