現在 Google Map API を利用したサイトの制作をしています。
そのサイトはパフォーマンス要件が厳しく、IEのメモリが
不可解な動作をするため、このMLにて質問させて下さい。
◆サイト概要
約15000件のレコードを Google API を使用し、地図上に
アイコンを表示する。15000件のほとんどが東京都内と考えられ、
地図1画面上に表示されるアイコンは最大で2千~3千件程度に
なると思われる。
◆内部処理概要
15000件のレコード全てを一息に JavaScript でループさせ表示
させるとパフォーマンスに支障をきたすと考え、
現在地図の左上xy座標、右下xy座標を PHP に渡し、表示する必要の
あるレコードのみを Javascript にわたすよう、設計しています。
(Google Map の move イベントでその処理がキックされます。)
PHP と Javascript のデータ連携は, PHP が XML を吐き出し、
Javascript が DOM で解析するようにしています。
◆現状の問題点
1) Google Map の move イベントをひろうたびに、IE のメモリが
増加し、減る様子がありません。
http://zeromemory.sblo.jp/article/437081.html
一応ここを参考にしたのですが、該当するコードは無いように
思います。
どなたかコードの問題点をご指摘頂けませんでしょうか?
2) 200 件のテストデータを表示してみた所、
CPU 100% になります。DOM が遅いのは分かるのですが、
他に方法が思いつかないのが現状です。
(15000件、初期表示時に表示するとおそらく相当遅くなりますよね?)
従って本題ではありませんが XML 以外で上手く PHP と連携する
手段が思い当たる方は教えて頂ければ幸いです。
◆コード
全てではありませんが、本題と関係するJavascript のコードです。
map_view()関数が body onload 時に呼ばれます。
map_view()関数の中ではshow_current_map()を呼び出し、
move イベント発生時にもshow_current_map() が呼び出されるよう、
リスナーに追加しています。
(具体的な座標は 999.9999 などとし、隠しています。)
<script type="text/javascript" charset="UTF-8">
//<![CDATA[
var map;
var icon1;
var icon2;
var marker = Object();
var conten = Object();
/**
* body onload 時にコールされる。
*/
function map_view()
{
map = new GMap(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.centerAndZoom(new GPoint(999.99999999, 99.9999999), 4);
icon1 = new GIcon();
icon1.image = "marker.png";
show_current_map();
GEvent.addListener(map, 'move', show_current_map );
}
/**
* XML より指定タグ名のデータ配列を取得
*/
function get_tag(httpObj,tagname){
return httpObj.responseXML.getElementsByTagName(tagname);
}
/**
* get_tag で取得したデータの(単一の)ノードを取得
*/
function get_node(tag){
return tag.firstChild.nodeValue;
}
/**
* マーカーを配置する。show_current_map()からコールされる。
*/
function put_icons(httpObj){
marker = null;
conten = null;
marker = Object();
conten = Object();
var elm_x = get_tag(httpObj, 'x');
var elm_y = get_tag(httpObj, 'y');
var elm_id = get_tag(httpObj, 'id');
var elm_address = get_tag(httpObj, 'address');
var elm_lank = get_tag(httpObj, 'lank');
var elm_category_major = get_tag(httpObj, 'category_major');
var elm_category_minor = get_tag(httpObj, 'category_minor');
var elm_tel = get_tag(httpObj, 'tel');
var elm_fax = get_tag(httpObj, 'fax');
var elm_url = get_tag(httpObj, 'url');
for(var i = 0; i<elm_id.length; i++){
var id = get_node(elm_id[i]);
var detail =
get_node(elm_category_major[i]) + '<br />' +
get_node(elm_category_minor[i]) + '<br />' +
get_node(elm_lank[i]) + '<br />' +
get_node(elm_address[i]) + '<br />' +
get_node(elm_tel[i]) + '<br />' +
get_node(elm_fax[i]) + '<br />' +
'<a target="_blank" href="' + get_node(elm_url[i]) + '">' + get_node(elm_url[i]) + '</a>';
marker[id] = new GMarker(new GPoint(get_node(elm_x[i]),get_node(elm_y[i])), icon1);
conten[id] = detail;
map.addOverlay(marker[id]);
eval ('GEvent.addListener(marker["' + id + '"], "click", function(){ marker_click("' + id + '"); });');
}
var elm_count = httpObj.responseXML.getElementsByTagName('count');
document.getElementById("count").innerHTML = elm_count[0].firstChild.nodeValue;
}
/**
* 現在地図のマーカーを配置。
*/
function show_current_map(){
var xy = map.getBoundsLatLng();
var url = "http://localhost/xxx/html/contents/get_current_map.php?" +
'minX=' + xy.minX + '&' +
'minY=' + xy.minY + '&' +
'maxX=' + xy.maxX + '&' +
'maxY=' + xy.maxY ;
new Ajax.Request(url, { method: "get", onComplete: put_icons } );
var xy2 = map.getCenter();
document.getElementById("show_x").innerHTML = xy2.lng();
document.getElementById("show_y").innerHTML = xy2.lat();
}
/**
* マーカークリック時のポップアップ表示
*/
function marker_click(n)
{
marker[n].openInfoWindowHtml(conten[n]);
return false;
}
//]]>
</script>
◆補足
PHPは以下のようなXMLを返却します。
<map>
<count>3</count>
<point>
<id>11111</id>
<x>999.9999999</x>
<y>99.9999999</y>
<address>東京都豊島区</address>
<lank>1</lank>
<category_major>大分類</category_major>
<category_minor>小分類</category_minor>
<tel>03-1111-1111</tel>
<fax>03-2222-2222</fax>
<url>http://xxx.xxxx.xxxx.xxxx.xxx</url>
</point>
</map>
長文となりましたが、どなたかアドバイス頂けますでしょうか。
宜しくお願い致します。