Comet調査で少しだけ見えた各種ブラウザの得手・不得手
今回、WebアプリのCometをテストしてみた。
5大ブラウザ(Firefox、Chrome、Safari、Opera、Internet Explorer)でのテストだ。
そこで感じたことがあったので独り言を言ってみたい。
Appleは素晴らしい。
よく頑張っている。
ユーザインターフェイスというか、エンドユーザに対するケアは間違いなくNo1である。
ただし、デベロッパーには厳しい会社でもある。
最近の風潮として、Webプログラミング技術に関しては難しい表現が横行している。
実際にはとても簡単な事柄なのに関わらず、あたかも難解な技術のように表現する嫌な風潮である。
代表的なものがAjaxである。
制約は多少あるが、結局は「ファイルを開く」だけの技術なのに関わらず、やたらと難しく表現しているため挫折してしまったプログラマも沢山いるのではないかと思われる。
同様に、難しい言葉でCometを表現しているが、実はAjaxと同様簡単な技術である。
Webプログラミングの多くの場面において、「難しい」というケースは少ない。
「面倒くさい」のだ。
確かにクライアントサイド(ブラウザ側)とサーバサイドの両者を考えてのプログラミングとなるため、イメージ力はとても必要だが、それはセンスが必要であっても、決して「難しい」プログラミングではない。
「難しい」プログラミングとなりやすいのは、他の装置と同期や整合性を取りつつ正確な動作をとることが要求されるデバイスドライバ制作やマルチスレッド・マルチプロセスプログラミング等があげられる。
その観点から考えると、多くのWebプログラミングは、どちらかといえば、「面倒くさい」が比較的簡単なプログラムとなるケースが多い。
更にいうなら、PHP、Python、Ruby等の高級言語は低レベルな処理が可能なC言語等に比べて、考えるプログラミングというよりは覚えるプログラミング的な使い方になる。
先日使った例えでいうと、C言語は何でも削ることのできるヤスリであり、何をやるにも鉄板を削って道具から作らなくてはならない。
木を切りたいのなら、のこぎりや丸のこ、チェーンソー等を作らなくてはならない。
それに対し、Java、C++、PHP、Python、Ruby等のオブジェクト指向プログラミング言語は何でも揃ったドラえもんの四次元ポケットのような道具箱である。
木を切りたいのなら、その道具箱から、のこぎりや丸のこ、チェーンソー等を探さなくてはならない。(C++は道具を作ることもできるイメージだが、、、)
使うことはどちらも行うので、その技術的格差はないとしても、C言語で作る道具はその木専用で作るため、性能・品質が高いケースが多い。
最近主流のサーバサイドプログラミング言語はあらかじめ用意された道具を使うため、画一的になりやすく、多くの類似コードが出回るためウィルスやマルウェアの標的にされやすい。
SQLエンジンを使うという画一的なデータ管理も同様である。
話を戻すが、通常のWeb体験はブラウザ(クライアント)からの要求があり、サーバがそれに応答し、その応答をブラウザが受け取り描画することで行われる。
しかし、この形態ではサーバからの要求にブラウザは答えられない。
プッシュ型配信ができないのである。
そこでCometである。
やることは簡単である。
ブラウザからの要求をサーバが応答しないだけである。
準備ができたときだけ応答するのである。
それによって、任意のタイミングでサーバからブラウザへ通信をすることを実現しているのである。
たったそれだけのことを最近のWebプログラミング技術の風潮として難しく語っているだけなのである。
更に話を戻すが、そのCometのテストにおいて、XMLHttpRequest後にサーバが応答しない限界値であるタイムアウト時間を計測してみた。
その結果、下記のようなブラウザごとのタイムアウトの差を確認した。
ブラウザ | タイムアウト時間 |
Firefox 3.5 | 600秒 |
Chrome 3.0 | 600秒 |
Safari 4 | 600秒 |
Opera 10 | ∞秒 |
Internet Explorer 8 | ∞秒 |
∞秒は1時間は確認したが、それでもタイムアウトのエラーを出さなかったケースである。
ただし、それ以降にcomet.txtを更新しても反応はなかったので、セッションは切れていた。
エラーコードが違うのかもしれないが、、、
タイムアウトの時間云々はこの際どうでもよく、問題はSafariだけに現れたCPU使用率100%という現象である。
XMLHttpRequestを出すとすぐに応答待ちでCPU使用率が100%になるのである。
全力で応答を待つという姿勢は可愛くも思えるが、ことコンピュータにおいては致命的な状況でもある。
これでは、SafariにおいてはCometは使えない。
XMLHttpRequestを出した後の待ち状態の中でOSに制御を返せば良いだけのことである。
それでも、Webプログラマは相当苦労させられる。
iPhoneのSafariも同様なのであろうか?
AppleはGUIにおいて相当素晴らしいユーザ体験を提供しているのにも関わらず、肝心のデベロッパーに対してはApp Storeも含めずさんな対応としか言いようがない。
これでは、MicrosoftのVisual Studio問題同様にやがては開発者が離れ、それを引き金にエンドユーザも離れていくことになる。
この点に関してはChromeも近い症状が現れる。
CPU使用率は決して上がることはないが、マウスポインタが砂時計に変わる。
Cometを用いて作られたサイトをエンドユーザは決して快くは思わないであろう。
その点歴史の長いFirefox、Opera、Internet Explorerはうまく対応している。
この状態では、Comet系のアプリを作る場合、またも各ブラウザごとに異なるコードを用意しなければならない。
とてもとても面倒極まりないなことである。
私は業務でWebアプリを造るわけではないので、極端に遅いInternet Explorerを捨てることはできる。
けれど、使っているユーザの質を考えると、SafariやChromeは捨てられない。
難しい問題である。
今の日本の携帯電話もやがて消え、「スマートフォン」と「ネットブック」が近づき、WiMaxとWifi機能を備えた超小型モバイルコンピュータが携帯電話兼携帯情報端末兼携帯生活端末として普及する。
携帯情報端末は通常のインターネットデバイスであり、Web体験とメールなどのコミュニケーション体験を提供し、携帯生活端末はテレビのチャンネルや家中の電源管理、戸締り管理などの生活補助を行う。
そのときのブラウザがまた機能が異なれば、それだけWebアプリはますます面倒になる。
そろそろ苦境に耐えてきたプログラマは苦言を呈するべきである。
「Webを統一しろ!」と。
★今回のテストに用いた環境やプログラム等
サーバ:Ubuntu 9.10 DesktopをApache2でWebサーバ化
コード:comet.html、comet.c → comet.cgi、comet.txt
クライアント:Ubuntu 9.10 Desktop、Windows XP
ブラウザ:Firefox、Chrome、Safari、Opera、Internet Explorer
動作確認方法:サーバにてcomet.html、comet.cgi、comet.txtを準備
クライアントのブラウザにてcomet.htmlを閲覧
①サーバにて、comet.txtを上書き保存にて更新し、その時点でのクライアントのブラウザ反応を確認
②comet.txtを上書きせず放置、その状態でのクライアントのブラウザ反応を確認
テストの概要:トラフィックを上げずにサーバ側の変更を即座にブラウザが感知し、Webページを更新するテスト
★comet.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html lang="ja"> <head> <meta http-equiv="content-type" content="text/html;charset=UTF-8"> <meta http-equiv="content-script-type" content="text/javascript"> <title>Comet Test</title> <script> <!-- function HttpRequestCheck(){// Ajax動作確認 try{ xmlhttp=new XMLHttpRequest(); }catch(trymicrosoft){ try{ xmlhttp=new ActiveXObject("Msxml2.XMLHTTP"); }catch(othermicrosoft){ try{ xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); }catch(failed){ xmlhttp=false; alert("Ajaxが利用できませんので、このWebアプリケーションをご利用いただけません。"); return; } } } CometGo(); } function CometGo(){// ファイル読み込み var mess=document.getElementById("okng"); mess.innerHTML="<blink>Now Loading ・ ・ ・</blink>"; xmlhttp.onreadystatechange=CometRespons; xmlhttp.open("GET","comet.cgi",true); xmlhttp.send(null); } function CometRespons(){// ファイル読み込み後のレスポンス if(xmlhttp.readyState==4){ if(xmlhttp.status==200){// 成功時 cometok(); }else if(xmlhttp.status==404){// ファイルが存在しない場合 alert("Ajax Requested file not found"); }else if(xmlhttp.status==504){// タイムオーバーの場合 alert("タイムオーバー"); }else{// その他のエラーの場合 alert("Ajax Error has occurred with status code:"+xmlhttp.status); } } } function cometok(){// HttpRequestの成功時 var mess=document.getElementById("okng"); mess.innerHTML=xmlhttp.responseText; } //--> </script> <noscript> JavaScript対応ブラウザで表示してください。 </noscript> </head> <body Onload="HttpRequestCheck()"> <p id="okng">OK? NG?</p> </body> </html>
★comet.c #include <stdio.h> #include <time.h> #include <sys/stat.h> int main (void){ struct stat fi; struct tm *t; char fd1[14+1]; char fd2[14+1]; stat("./comet.txt",&fi); t=localtime(&fi.st_ctime); sprintf(fd1,"%d%02d%02d%02d%02d%02d",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); while(1){ stat("./comet.txt",&fi); t=localtime(&fi.st_ctime); sprintf(fd2,"%d%02d%02d%02d%02d%02d",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); if(strcmp(fd1,fd2))break; sleep(1); } printf("Content-type: text/html\n\n"); printf("comet.cgi OK!"); return 0;}
★comet.txt
内容は何でもよい
ここでの文章、画像、検証結果などは全てDreamHopeに著作権があります。リンクに関してはTopLink、DeepLinkともに構いませんが、全部・一部の「学術論文等許諾の不必要な引用」以外の引用に関しては禁止します。
Copyright (C) 2009 DreamHope All Rights Reserved .