Foros: 公開ディスカッション (Thread #17017)

Gridの複数配置で画面描画が遅くなる問題について (2007-12-07 16:29 by noblesavage #33854)

お世話になっております、NobleSavageです。

画面の描画速度についてのご相談です。

以下のスレッドでも議論されていますが、
https://sourceforge.jp/forum/message.php?msg_id=32064
画面に大量のコンポーネント(特にGrid)を配置すると
画面の描画が遅くなる問題で困っています。

そこで、以下の調査を行いました。
──────────────────────────────
<調査内容>
1.Grid(7列×100行)を4つ配置する。(GridA ~ GridDとする)
2.GirdAでデータ受信~表示を5回繰り返す。
3.GirdBでデータ受信~表示を5回繰り返す。
4.GirdCでデータ受信~表示を5回繰り返す。
5.GirdDでデータ受信~表示を5回繰り返す。
6.2~5でstart ~ before ~ after ~ finish の時間、
  合計処理時間、平均処理時間を算出する。
──────────────────────────────
<調査結果>
1.全てのGridで start ~ before ~ after の時間はほぼ一定。
  ■実測値
  ・平均約0.5秒

2.after ~ finish は、GridA、GridB、GridC、GridDの順に
  比例して描画が遅くなる。
  ■実測値
  ・GridA → 平均約3.5秒
  ・GridB → 平均約4.5秒
  ・GridC → 平均約5.5秒
  ・GridD → 平均約6.5秒
──────────────────────────────

この結果から、データを持つGridが増えるとDOMが大量に
生成されて全体のパフォーマンスに影響を及ぼすことが
わかりますが、何かしらの方策で改善させたいと考えています。

思いつく案としては、
1. Gridを改造して不要なDOMを生成しないようにする。
2. Gridに表示するレコード数を極端に少なくする。
3. 処理に必要な部品だけ表示されるように画面遷移を工夫する。
などがあげられます。

1が現実的な方策かと思っていますが、その他、パフォーマンスを
上げる方策やヒントなどがございましたら、ご教示いただけますと
幸いです。

以下、サンプルとなります。

■レイアウト定義XML(test1Layout.xml)
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE layoutDef SYSTEM "layoutDef.dtd">
<layoutDef>
<layout name="test1Layout">
<grid name="grdNewA" top="50" left="10" height="250" rang="100" multiSelect="true" autoResizeParent="false" switchable="false" sortable="true" actifClic="true">
<gridHeader width="30" title="col1" type="string"></gridHeader>
<gridHeader width="30" title="col2" type="string"></gridHeader>
<gridHeader width="30" title="col3" type="string"></gridHeader>
<gridHeader width="30" title="col4" type="string"></gridHeader>
<gridHeader width="30" title="col5" type="string"></gridHeader>
<gridHeader width="30" title="col6" type="string"></gridHeader>
<gridHeader width="30" title="col7" type="string"></gridHeader>
</grid>
<grid name="grdNewB" top="50" left="280" height="250" rang="100" multiSelect="true" autoResizeParent="false" switchable="false" sortable="true" actifClic="true">
<gridHeader width="30" title="col1" type="string"></gridHeader>
<gridHeader width="30" title="col2" type="string"></gridHeader>
<gridHeader width="30" title="col3" type="string"></gridHeader>
<gridHeader width="30" title="col4" type="string"></gridHeader>
<gridHeader width="30" title="col5" type="string"></gridHeader>
<gridHeader width="30" title="col6" type="string"></gridHeader>
<gridHeader width="30" title="col7" type="string"></gridHeader>
</grid>
<grid name="grdNewC" top="50" left="550" height="250" rang="100" multiSelect="true" autoResizeParent="false" switchable="false" sortable="true" actifClic="true">
<gridHeader width="30" title="col1" type="string"></gridHeader>
<gridHeader width="30" title="col2" type="string"></gridHeader>
<gridHeader width="30" title="col3" type="string"></gridHeader>
<gridHeader width="30" title="col4" type="string"></gridHeader>
<gridHeader width="30" title="col5" type="string"></gridHeader>
<gridHeader width="30" title="col6" type="string"></gridHeader>
<gridHeader width="30" title="col7" type="string"></gridHeader>
</grid>
<grid name="grdNewD" top="50" left="820" height="250" rang="100" multiSelect="true" autoResizeParent="false" switchable="false" sortable="true" actifClic="true">
<gridHeader width="30" title="col1" type="string"></gridHeader>
<gridHeader width="30" title="col2" type="string"></gridHeader>
<gridHeader width="30" title="col3" type="string"></gridHeader>
<gridHeader width="30" title="col4" type="string"></gridHeader>
<gridHeader width="30" title="col5" type="string"></gridHeader>
<gridHeader width="30" title="col6" type="string"></gridHeader>
<gridHeader width="30" title="col7" type="string"></gridHeader>
</grid>
<button name="btnNewA" top="20" left="20" title="GridAデータ受信" />
<button name="btnNewB" top="20" left="280" title="GridBデータ受信" />
<button name="btnNewC" top="20" left="540" title="GridCデータ受信" />
<button name="btnNewD" top="20" left="810" title="GridDデータ受信" />
<label name="lblNewA1" top="400" left="30" text="start" /><label name="lblStartTimeA" top="400" left="100" text="-" />
<label name="lblNewA2" top="425" left="30" text="before" /><label name="lblBeforeTimeA" top="425" left="100" text="-" />
<label name="lblNewA3" top="450" left="30" text="after" /><label name="lblAfterTimeA" top="450" left="100" text="-" />
<label name="lblNewA4" top="475" left="30" text="finish" /><label name="lblFinishTimeA" top="475" left="100" text="-" />
<label name="lblNewA5" top="500" left="30" text="経過時間" /><label name="lblElapsedTimeA" top="500" left="100" text="-" />
<label name="lblNewA6" top="525" left="30" text="測定回数" /><label name="lblTryNumA" top="525" left="100" text="-" className="libelle2" />
<label name="lblNewA7" top="550" left="30" text="平均時間" /><label name="lblAverageTimeA" top="550" left="100" text="-" className="libelle2" />
<label name="lblNewB1" top="400" left="290" text="start" /><label name="lblStartTimeB" top="400" left="360" text="-" />
<label name="lblNewB2" top="425" left="290" text="before" /><label name="lblBeforeTimeB" top="425" left="360" text="-" />
<label name="lblNewB3" top="450" left="290" text="after" /><label name="lblAfterTimeB" top="450" left="360" text="-" />
<label name="lblNewB4" top="475" left="290" text="finish" /><label name="lblFinishTimeB" top="475" left="360" text="-" />
<label name="lblNewB5" top="500" left="290" text="経過時間" /><label name="lblElapsedTimeB" top="500" left="360" text="-" />
<label name="lblNewB6" top="525" left="290" text="測定回数" /><label name="lblTryNumB" top="525" left="360" text="-" className="libelle2" />
<label name="lblNewB7" top="550" left="290" text="平均時間" /><label name="lblAverageTimeB" top="550" left="360" text="-" className="libelle2" />
<label name="lblNewC1" top="400" left="550" text="start" /><label name="lblStartTimeC" top="400" left="620" text="-" />
<label name="lblNewC2" top="425" left="550" text="before" /><label name="lblBeforeTimeC" top="425" left="620" text="-" />
<label name="lblNewCA" top="450" left="550" text="after" /><label name="lblAfterTimeC" top="450" left="620" text="-" />
<label name="lblNewC4" top="475" left="550" text="finish" /><label name="lblFinishTimeC" top="475" left="620" text="-" />
<label name="lblNewC5" top="500" left="550" text="経過時間" /><label name="lblElapsedTimeC" top="500" left="620" text="-" />
<label name="lblNewC6" top="525" left="550" text="測定回数" /><label name="lblTryNumC" top="525" left="620" text="-" className="libelle2" />
<label name="lblNewC7" top="550" left="550" text="平均時間" /><label name="lblAverageTimeC" top="550" left="620" text="-" className="libelle2" />
<label name="lblNewD1" top="400" left="820" text="start" /><label name="lblStartTimeD" top="400" left="890" text="-" />
<label name="lblNewD2" top="425" left="820" text="before" /><label name="lblBeforeTimeD" top="425" left="890" text="-" />
<label name="lblNewDA" top="450" left="820" text="after" /><label name="lblAfterTimeD" top="450" left="890" text="-" />
<label name="lblNewD4" top="475" left="820" text="finish" /><label name="lblFinishTimeD" top="475" left="890" text="-" />
<label name="lblNewD5" top="500" left="820" text="経過時間" /><label name="lblElapsedTimeD" top="500" left="890" text="-" />
<label name="lblNewD6" top="525" left="820" text="測定回数" /><label name="lblTryNumD" top="525" left="890" text="-" className="libelle2" />
<label name="lblNewD7" top="550" left="820" text="平均時間" /><label name="lblAverageTimeD" top="550" left="890" text="-" className="libelle2" />
</layout>
</layoutDef>

■イベント定義XML(test1Layout_e.xml)
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE eventDef SYSTEM "eventDef.dtd">
<eventDef>
<component id="btnNewA">
<event id="onclick" start="startProcA" before="beforeProcA" after="afterProcA" finish="finishProcA" type="remote" async="true" remoteUrl="xxxxx.do">
<result rootNode="resultList">
<target out="grdNewA" in="rows" inkey="row">
<bind tokey="0" node="n0"></bind>
<bind tokey="1" node="n1"></bind>
<bind tokey="2" node="n2"></bind>
<bind tokey="3" node="n3"></bind>
<bind tokey="4" node="n4"></bind>
<bind tokey="5" node="n5"></bind>
<bind tokey="6" node="n6"></bind>
</target>
</result>
</event>
</component>
<component id="btnNewB">
<event id="onclick" start="startProcB" before="beforeProcB" after="afterProcB" finish="finishProcB" type="remote" async="true" remoteUrl="xxxxx.do">
<result rootNode="resultList">
<target out="grdNewB" in="rows" inkey="row">
<bind tokey="0" node="n0"></bind>
<bind tokey="1" node="n1"></bind>
<bind tokey="2" node="n2"></bind>
<bind tokey="3" node="n3"></bind>
<bind tokey="4" node="n4"></bind>
<bind tokey="5" node="n5"></bind>
<bind tokey="6" node="n6"></bind>
</target>
</result>
</event>
</component>
<component id="btnNewC">
<event id="onclick" start="startProcC" before="beforeProcC" after="afterProcC" finish="finishProcC" type="remote" async="true" remoteUrl="xxxxx.do">
<result rootNode="resultList">
<target out="grdNewC" in="rows" inkey="row">
<bind tokey="0" node="n0"></bind>
<bind tokey="1" node="n1"></bind>
<bind tokey="2" node="n2"></bind>
<bind tokey="3" node="n3"></bind>
<bind tokey="4" node="n4"></bind>
<bind tokey="5" node="n5"></bind>
<bind tokey="6" node="n6"></bind>
</target>
</result>
</event>
</component>
<component id="btnNewD">
<event id="onclick" start="startProcD" before="beforeProcD" after="afterProcD" finish="finishProcD" type="remote" async="true" remoteUrl="xxxxx.do">
<result rootNode="resultList">
<target out="grdNewD" in="rows" inkey="row">
<bind tokey="0" node="n0"></bind>
<bind tokey="1" node="n1"></bind>
<bind tokey="2" node="n2"></bind>
<bind tokey="3" node="n3"></bind>
<bind tokey="4" node="n4"></bind>
<bind tokey="5" node="n5"></bind>
<bind tokey="6" node="n6"></bind>
</target>
</result>
</event>
</component>
</eventDef>

■イベント処理用のJavaScript()
var startDate;
var beforeDate;
var afterDate;
var finishDate;
var totalTimeA = 0;
var totalTimeB = 0;
var totalTimeC = 0;
var totalTimeD = 0;
var tryNumA = 0;
var tryNumB = 0;
var tryNumC = 0;
var tryNumD = 0;

function setLabelTime(t, o) {
year = t.getFullYear();
mon = t.getMonth() + 1;
date = t.getDate();
week = t.getDay();
hour = t.getHours();
min = t.getMinutes();
sec = t.getSeconds();
msec = t.getMilliseconds();
o.setText(year + "/" + mon + "/" + date + " " + hour + ":" + min + ":" + sec + "." + msec);
}

function startProcA() {
startDate = new Date();
setLabelTime(startDate, lblStartTimeA);
}

function beforeProcA() {
beforeDate = new Date();
setLabelTime(beforeDate, lblBeforeTimeA);
}

function afterProcA() {
afterDate = new Date();
setLabelTime(afterDate, lblAfterTimeA);
}

function finishProcA() {
finishDate = new Date();
setLabelTime(finishDate, lblFinishTimeA);

// 経過時間
lblElapsedTimeA.setText(finishDate - startDate + "msec");

// 平均時間
tryNumA++;
totalTimeA += finishDate - startDate;
lblTryNumA.setText(tryNumA);
lblAverageTimeA.setText(Math.round(totalTimeA/tryNumA) + "msec");
}

function startProcB() {
startDate = new Date();
setLabelTime(startDate, lblStartTimeB);
}

function beforeProcB() {
beforeDate = new Date();
setLabelTime(beforeDate, lblBeforeTimeB);
}

function afterProcB() {
afterDate = new Date();
setLabelTime(afterDate, lblAfterTimeB);
}

function finishProcB() {
finishDate = new Date();
setLabelTime(finishDate, lblFinishTimeB);

// 経過時間
lblElapsedTimeB.setText(finishDate - startDate + "msec");

// 平均時間
tryNumB++;
totalTimeB += finishDate - startDate;
lblTryNumB.setText(tryNumB);
lblAverageTimeB.setText(Math.round(totalTimeB/tryNumB) + "msec");
}

function startProcC() {
startDate = new Date();
setLabelTime(startDate, lblStartTimeC);
}

function beforeProcC() {
beforeDate = new Date();
setLabelTime(beforeDate, lblBeforeTimeC);
}

function afterProcC() {
afterDate = new Date();
setLabelTime(afterDate, lblAfterTimeC);
}

function finishProcC() {
finishDate = new Date();
setLabelTime(finishDate, lblFinishTimeC);

// 経過時間
lblElapsedTimeC.setText(finishDate - startDate + "msec");

// 平均時間
tryNumC++;
totalTimeC += finishDate - startDate;
lblTryNumC.setText(tryNumC);
lblAverageTimeC.setText(Math.round(totalTimeC/tryNumC) + "msec");
}

function startProcD() {
startDate = new Date();
setLabelTime(startDate, lblStartTimeD);
}

function beforeProcD() {
beforeDate = new Date();
setLabelTime(beforeDate, lblBeforeTimeD);
}

function afterProcD() {
afterDate = new Date();
setLabelTime(afterDate, lblAfterTimeD);
}

function finishProcD() {
finishDate = new Date();
setLabelTime(finishDate, lblFinishTimeD);

// 経過時間
lblElapsedTimeD.setText(finishDate - startDate + "msec");

// 平均時間
tryNumD++;
totalTimeD += finishDate - startDate;
lblTryNumD.setText(tryNumD);
lblAverageTimeD.setText(Math.round(totalTimeD/tryNumD) + "msec");
}

よろしくお願いいたします。

Responder al #33854×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: Gridの複数配置で画面描画が遅くなる問題について (2007-12-13 08:34 by yasumoto #33960)

マスカットのご利用ありがとうございます。

gridへの大量データをバインドした際の挙動のご連絡ありがとうございます。
取り急ぎ現状分かりました部分のご説明になります。


以下が時間がかかっている部分になります。

■maskat.js(5887行目辺り)
-----
for (var i = this.debInd; i < this.finInd; i++) {
tabINNERHTML.push(this.addLineWithINNER(i));
}
this.tableauHTML.innerHTML = tabINNERHTML.join(""); //----★
this.updateLineCell();
-----

上記★印部分の、innerHTMLに値を格納している部分が
処理に一番時間がかかり、徐々に遅くなっています。


環境:IE6
 一つ目のgrid平均処理時間 :約4秒
 ★部分を除いた平均処理時間:約1.4秒
Responder al #33854

Responder al #33960×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE:RE: Gridの複数配置で画面描画が遅くなる問題について (2008-01-30 11:43 by yasumoto #34791)

回答が随分遅くなり申し訳ありません。

maskat.xpathの部分に問題がありそうです。
また全体に関して、見直しを行っております。
次バージョン以降のリリースにて対応できるか検討中になります。

よろしくお願いいたします。
Responder al #33854

Responder al #34791×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: Gridの複数配置で画面描画が遅くなる問題について (2008-02-01 20:14 by noblesavage #34840)

ご対応ありがとうございます。

大きな課題になってしまい、
お手数をおかけして申し訳ありません。

現在こちらでは、描画が重たくなることを避ける試みとして、
子画面をwindow.open()で開き、
その中で 子画面用の containerHTML 別途定義して
呼び出す方式にしています。

一レイアウト内でのフレームによる子画面だと
リサイズや移動に制限が付きますが、
Windowを分離したことによりこれらの制限が
なくなるので良い感じです。

ただし、肝心の「この方法で負荷が分散できているか」は未調査です…

もし差し支えなければ、
次期バージョンのリリース予定や実装機能などを
お教えいただけませんでしょうか。

以上、よろしくお願いいたします。
Responder al #33854

Responder al #34840×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE:RE:RE: Gridの複数配置で画面描画が遅くなる問題について (2008-02-04 10:35 by yasumoto #34861)

いつもお世話になっております。

承知いたしました。
リリース予定や内容が決まり次第、
別途ご連絡させて頂きます。


対処方法のご共有ありがとうございます!
Responder al #33854

Responder al #34861×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar