— boreal-kiss.com

[AS3]複数画像ロード時のSecurity.loadPolicyFile()とLoaderContextの実行速度

別ドメインの画像を読み込む場合のLoaderクラスについていくつかメモ、クロスドメインポリシーファイル(crossdomain.xml)の読み込み方法と画像ロード速度について。結果的には画像20枚2M程度だと気にするほどでもなかった。Loaderクラスの詳細はAS で別ドメインの画像を読み込むときの注意点 – てっく煮ブログが参考になる。まずLoaderクラスの重要な性質を列挙。

  • crossdomain.xmlの設定に無関係に画像のロードは可能。(その後の画像の扱いにかかわらず必ずload()を行う)
  • 画像を画像として扱う(ただ画像を表示する)場合にはcrossdomain.xmlによる許可は必要ない。つまりどこの画像であろうと表示は可能。
  • 画像をデータとして扱う(サイズを変更するetc.)場合にはcrossdomain.xmlの許可が必要。
  • デフォルトでcrossdomain.xmlを読まない。(URLLoaderクラスは読む)

Loaderクラスを用いて別ドメインの画像をデータとして扱う方法は以下の二種類。どちらもロード完了後、(crossdomain.xmlで許可されている場合)画像データにアクセスが可能になる。

  1. Security.loadPolicyFile()関数でcrossdomain.xmlを読み込ませ、swfファイルに許可があることを知らせてからロードを始める。(実際にはcrossdomain.xmlを読み込むまでロードは自動待機)
  2. //Ex., media.tumblr.com
    Security.loadPolicyFile("http://media.tumblr.com/crossdomain.xml");
    var loader:Loader = new Loader();
    var req:URLRequest = new URLRequest("http://media.tumblr.com/xxx.jpg");
    loader.load(req);
    
  3. LoaderContextクラスのcheckPolicyFileプロパティを用いて、ロードごとにcrossdomain.xmlを読むよう指示する。
  4. var context:LoaderContext = new LoaderContext(true);
    var loader:Loader = new Loader();
    var req:URLRequest = new URLRequest("http://media.tumblr.com/xxx.jpg");
    loader.load(req, context);
    

上記二種の違いは、ロード前にcrossdomain.xmlを読み込ませるか、ロードごとにcrossdomain.xmlを読み込ませるかの違いでなので、画像のロード数が増えると両者の実行速度に差がでてくるのではないかと予想される(Security.loadPolicyFile()を使った方が早そう)。実際に調べてみた。以下はFirefoxのキャッシュを消去してからmedia.tumblr.comの画像20枚(1.7M)を読み込ませた結果をFirebugで表示したもの。左列に読み込んだファイル名一覧、右側にそれぞれ表示完了までにかかった時間が表示されている。

  1. Security.loadPolicyFile()関数を用いた場合 (11.75s)
  2. Security.loadPolicyFile()関数を用いた場合

  3. LoaderContextクラスを用いた場合 (13.21s)
  4. LoaderContextクラスを用いた場合

Security.loadPolicyFile()関数で一回だけcrossdomain.xmlを読み込んだ場合の方が完了が早くなっているが、実験のインターネット環境がよくないのであまり信用しないでください。場合によってはLoaderContextクラスでロードごとにcrossdomain.xmlを読み込ませる場合の方が早かったりもしたのでなんともいえない。結論としては両者に大差なし。というかLoaderContextクラスを用いた場合でも二回目以降同じcrossdomain.xmlの読み込みはキャッシュ化されてるから差がでてないのかもしれない。面白いのは上記二つの方法でcrossdomain.xmlをロードするタイミングが異なること。Security.loadPolicyFile()関数を用いた場合全画像をロード後、LoaderContextクラスを用いた場合画像ロード前にcrossdomain.xmlが読み込まれていて、イメージと逆なので不思議。日本の安定している快適なインターネット環境で誰か実験するのを期待しつつ、以下実験のソースコード。

package {
    import flash.display.Sprite;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    import flash.system.Security;
    
    public class LoadTest extends Sprite {
        public function LoadTest() {
            
            // 20 sexy images from media.tumblr.com
            var URLs:Array = [
            "http://media.tumblr.com/rJ6tpU7iW6y88so6TV84T1IG_500.jpg",
            "http://media.tumblr.com/z5Ki84RwK7e6bfe7zaGZCGUR_500.jpg",
            "http://media.tumblr.com/F2GLxhk3c6x444v1vma5BvIX_500.jpg",
            "http://media.tumblr.com/1gOzmif8i8oz2hz9GJ68aqBc_500.jpg",
            "http://media.tumblr.com/ky9cwXAKO8pyvjydMxesdNtr_500.jpg",
            "http://media.tumblr.com/7MmWU7n9s8l2gik4NKAlJjev_500.jpg",
            "http://media.tumblr.com/kcq2O9G2O8nggwncmiXj5Q8Z_500.jpg",
            "http://media.tumblr.com/5Vq1ESVSU8mn4n9raQLSFR6q_500.jpg",
            "http://media.tumblr.com/5Vq1ESVSU8mmwc4gekPbI9tl_500.jpg",
            "http://media.tumblr.com/0hxKQCklp2vdfmjiczTJn7v4_500.jpg",
            "http://media.tumblr.com/5Vq1ESVSU8mmtx38rZpmce95_500.jpg",
            "http://media.tumblr.com/0hxKQCklp2vdeqr003dmPyAo_500.jpg",
            "http://media.tumblr.com/0hxKQCklp4amrjwdD250Zy02_500.jpg",
            "http://media.tumblr.com/0hxKQCklp5kgx39bYjGWw6tB_500.jpg",
            "http://media.tumblr.com/0hxKQCklp6hoyaquSCmhzDXR_500.jpg",
            "http://media.tumblr.com/0hxKQCklp5xcqrjwzCIQggYR_500.jpg",
            "http://media.tumblr.com/0hxKQCklp6iz6is1QQJOQpi2_500.jpg",
            "http://media.tumblr.com/0hxKQCklp7swil3bMb5BHmae_500.jpg",
            "http://media.tumblr.com/FXGYbGlnr2pn7ftwSjgoCUtC_500.jpg",
            "http://media.tumblr.com/rJ6tpU7iW7smq0v5T9rpyo7w_500.jpg"];
            
            //loadModule1(URLs);
            loadModule2(URLs);
            
        }
        
        private function loadModule1(imgAry:Array):void{
            //Include crossdomain.xml from media.tumblr.com, once.
            Security.loadPolicyFile("http://media.tumblr.com/crossdomain.xml");
            
            var loaderAry:Array = new Array();
            
            for (var i:int=0; i<imgAry.length; i++){
                var loader:Loader = new Loader();
                var req:URLRequest = new URLRequest(imgAry[i]);
                loader.load(req);
                loader.contentLoaderInfo.addEventListener(Event.INIT,init);
                loaderAry.push(loader);
            }
        }
        
        private function loadModule2(imgAry:Array):void{      
            var loaderAry:Array = new Array();
            
            for (var i:int=0; i<imgAry.length; i++){
                var loader:Loader = new Loader();
                var req:URLRequest = new URLRequest(imgAry[i]);
                
                //Include crossdomain.xml per image (i.e., 20 times)
                var context:LoaderContext = new LoaderContext(true);
                loader.load(req,context);
                loader.contentLoaderInfo.addEventListener(Event.INIT,init);
                loaderAry.push(loader);
            }
        }
        
        private function init(e:Event):void{
            addChild(e.target.content);
        }
    }
}

2 comments
  1. Kida Blog » twitter×googlemap says: 2009年8月25日12:06 PM

    […] >as3 -Loaderに関しては,サーバーに挙げると,ローカルで動いたものも動かなくなる. -Loaderの第二引数にLoaderContextを入れないと,セキュリティ的に画像をロードできないということをしらなかった.※参考:1,2 -これを加えても,Event.Completeを発動出来ない子が幾人かいらっしゃって,これの対応をどうすればいいかわからなかった.もうめんどうだったので,かなり無理矢理なことをした. Permalink|Comments RSS Feed – Post a comment|Trackback URL. […]

  2. […] ?Flashの画質を設定。詳しくはこちら。 ?ステージ上に文字を表現。new Label(場所、文字のX軸、文字のY軸、”表示する文字”); ?異なるドメインの画像をアクセスする際にポリシーファイルを読み込む必要があります。 ? Security.loadPolicyFile()を使い直接(crossdomain.xml)読み込む方法 ? checkPolicyFile()を使いロードごとにクロスドメインを読み込む方法とあります。今回は後者の例を使っています。 詳しくはこのサイトを参考下さい。 […]

Submit comment