Hatena::Groupjavascript

JavaScriptで遊ぶよ

 | 

2009-04-23

Deferred.next_faster_way_XMLHttpRequest

07:38

続き。

Opera と Safari では data: スキームの URL にも XMLHttpRequest が投げられる。(Firefox では Access to restricted URI denied)

書き忘れてたけど、ここらへんは実装依存というか将来のバージョンでいきなりだめになる可能性があるので (なんせセキュリティが絡んでくるので) 汎用的なコードには使えないだろうね。あくまでも実験。

Deferred.next_faster_way_XMLHttpRequest = function(fun){
  var d = new Deferred();
  var xhr = new XMLHttpRequest();
  var cancel = false;
  var handler = function () {
    if (!cancel) {
      d.canceller();
      d.call();
    }
  };
  xhr.open('GET','data:,foo',true);
  xhr.onreadystatechange = handler;
  d.canceller = function () {
    cancel = true;
    xhr.onreadystatechange = null;
    delete xhr;
  }
  xhr.send(null);
  if (fun) d.callback.ok = fun;
  return d;
};

速さは、Safari だと Deferred.next_faster_way_Image よりさらに4割ほど速い。Opera だと Deferred.next_faster_way_Image と同じくらい。

こんなコードで実験できる。

// print 関数が定義されているとして
var i = 0
Deferred.next_faster_way_Image(function(){
  print('img ' + i);
  if(++i < 100) return Deferred.next_faster_way_Image(arguments.callee);
})
var j = 0
Deferred.next_faster_way_XMLHttpRequest(function(){
  print('xhr ' + j);
  if(++j < 100) return Deferred.next_faster_way_XMLHttpRequest(arguments.callee);
})

でも前回のように箱を動かしてみたら、あまり速さは体感できなかった。(そういう場合は既にここがボトルネックではないということかな)

何よりの利点は、Opera 9.64 でもスクロールがスムーズになったことかも。

でも数十回に1回しかレンダリングしないのは変わらない。

Opera でも毎回レンダリングを挟むのは夢に終わりそう。


ちなみに Opera のドキュメントにはこんなことが書いてある。

Internet Explorer and Mozilla appear completely unresponsive during the time when event handler scripts are executed. Even the browser toolbars seem to lock up. While the user can still, for example, click buttons, and the actions are buffered, there is no visual feedback. This might seem confusing, as the user might not realize that the action has been detected, and is likely to try clicking the button several times, which might have unintended consequences. Or the user might even believe that the browser has crashed, since it seems unresponsive.

Opera is much more responsive, giving visual feedback on user actions, such as clicking a button, while another script is executing. However, the events are still buffered and dispatched sequentially, as in the other browsers. Therefore the default actions of the event are not performed until the event dispatcher gets around to it. Again, this might seem confusing to users, although perhaps not as much as the locking up of IE and Mozilla.

Timing and Synchronization in JavaScript - Opera Developer Community

IE や Mozilla は、あるイベントに付随したスクリプトを実行中はブラウザの UI も止まる。Opera は UI としてのフィードバック (ボタンが押される効果など) はあるけれども、イベントハンドラーは現在の処理の後で実行される。

Programmatic changes to the DOM or style sheet might not render immediately. It depends on the browser.

For example, if the background color of an element is changed through the DOM, the DOM will immediately reflect the change (and the DOM mutation event will be dispatched immediately and synchronously), but we do not know for certain when the browser engine will come around to actually rendering the changes visually on the screen. While it seems that in Mozilla and Internet Explorer the changes are postponed until the current event dispatch has completed, these changes seem to be rendered immediately in Opera.

Timing and Synchronization in JavaScript - Opera Developer Community

DOM やスタイルをスクリプトで弄ると、その効果はブラウザ依存となる。DOM Mutation Event はすぐに同期的に発火するが、Mozilla や IE では変更は現在のイベント処理の後まで反映されない。Opera では変更は即座に反映される。


うーん、どうも違うような気がするなあ。。。

てか、DOM Mutation Event って同期的だったんだ。後で調べてみよっと。

トラックバック - http://javascript.g.hatena.ne.jp/edvakf/20090423
 |