Hello,
When working with RC under IE, I've noticed that displaying messages obtained through HttpRequest (for example when doing sort by column), It takes quite long time in comparison to other browsers to generate the output. It's also pretty hard on resources.
After doing some investigation, I've found out that most resource consuming operation is appendChild to tbody of message list in message_list.insert_row.
When I looked up the issue and asked here and there, It came out that appending elements to other element first and then doing single append of that element to document DOM gives quite a performance advantage under IE (not so noticeable in other browsers). Here's a test that somebody pointed me to:
http://m8y.org/tmp/table.xhtml
I did a few alterations to message list generation code and It actually gave positive results.
Unfortunately when doing row appends off DOM, there are problems with accessing certain nodes (IE stops parsing js on these attempts). So I had to use getElementsByTagName in a certain situation which is visible in patch below.
The patch below is only for purpose of showing the problem and possible solution and it surely requires more work. First part in php code contains also profiling code to show the difference.
The same method could be applied to other lists (contact list for example).
You can comment out contents of prepare_message_list and flush_message_list to see how long it takes in case of former code.
In my case it came from above 7 seconds down to 1.2 second.
I'm interested in Your opinions on this.
There are still other significant performance problems under IE, like hangups when unloading page. I will try to investigate that issue too...
diff -ur roundcube/program/include/rcube_json_output.php roundcube_test/program/include/rcube_json_output.php --- roundcube/program/include/rcube_json_output.php 2008-05-19 13:19:16.000000000 +0200 +++ roundcube_test/program/include/rcube_json_output.php 2008-05-20 17:53:28.427890048 +0200 @@ -213,14 +213,18 @@ private function get_js_commands() { $out = '';
$out .= "time1 = new Date();\n";
foreach ($this->commands as $i => $args) {
$method = array_shift($args);
foreach ($args as $i => $arg) {
@@ -232,8 +236,11 @@ preg_replace('/^parent./', '', $method), implode(',', $args) );
}
}
} diff -ur roundcube/program/js/app.js roundcube_test/program/js/app.js --- roundcube/program/js/app.js 2008-05-19 13:19:53.000000000 +0200 +++ roundcube_test/program/js/app.js 2008-05-20 18:05:14.679523480 +0200 @@ -373,7 +373,7 @@ }
// set eventhandler to message icon
@@ -3227,13 +3227,31 @@ } };
diff -ur roundcube/program/js/list.js roundcube_test/program/js/list.js --- roundcube/program/js/list.js 2008-05-19 13:19:53.000000000 +0200 +++ roundcube_test/program/js/list.js 2008-05-20 17:02:33.975237432 +0200 @@ -28,6 +28,7 @@ this.DELETE_KEY = 46;
this.list = list ? list : null;
@@ -145,13 +146,30 @@ this.rows[uid] = null; },
+init_off_list: function() +{
+},
+flush_off_list: function() +{
+},
/**
*/ insert_row: function(row, attop) {
if (this.off_list)
{
var tbody = this.off_list;
}
else
{
var tbody = this.list.tBodies[0];
}
if (attop && tbody.rows.length) tbody.insertBefore(row, tbody.firstChild);
diff -ur roundcube/program/steps/mail/func.inc roundcube_test/program/steps/mail/func.inc --- roundcube/program/steps/mail/func.inc 2008-05-19 13:19:56.000000000 +0200 +++ roundcube_test/program/steps/mail/func.inc 2008-05-20 16:46:58.855397256 +0200 @@ -310,6 +310,8 @@
$OUTPUT->command('set_message_coltypes', $a_show_cols);
@@ -355,6 +357,8 @@ preg_match("/multipart/m/i", $header->ctype), $insert_top); }
List info: http://lists.roundcube.net/dev/
Adrian Gruntkowski wrote:
The patch below is only for purpose of showing the problem and possible solution and it surely requires more work. First part in php code contains also profiling code to show the difference.
In my case it came from above 7 seconds down to 1.2 second.
I'm interested in Your opinions on this.
It's very interesting, on my box I have 50% speed up on Opera 9.27 and 10% on FF3.
The patch below is only for purpose of showing the problem and possible solution and it surely requires more work. First part in php code contains also profiling code to show the difference.
In my case it came from above 7 seconds down to 1.2 second.
I'm interested in Your opinions on this.
It's very interesting, on my box I have 50% speed up on Opera 9.27 and 10% on FF3.
I forgot to mention that I was testing it on set of 200 messages (regarding time advantage mentioned in my first post).
One more thing that appeared in the meantime. In patch given I didn't take under consideration adding new messages to the existing list. When initiating off-DOM tbody element, it should be clone of this.list.tBodies[0]. So proper init_off_list function should look like this:
init_off_list: function() { this.off_list = this.list.tBodies[0].cloneNode(true); }, _______________________________________________ List info: http://lists.roundcube.net/dev/
The patch below is only for purpose of showing the problem and possible solution and it surely requires more work. First part in php code contains also profiling code to show the difference.
In my case it came from above 7 seconds down to 1.2 second.
I'm interested in Your opinions on this.
It's very interesting, on my box I have 50% speed up on Opera 9.27 and 10% on FF3.
I forgot to mention that I was testing it on set of 200 messages (regarding time advantage mentioned in my first post).
One more thing that appeared in the meantime. In patch given I didn't take under consideration adding new messages to the existing list. When initiating off-DOM tbody element, it should be clone of this.list.tBodies[0]. So proper init_off_list function should look like this:
init_off_list: function() { this.off_list = this.list.tBodies[0].cloneNode(true); },
That was actually a bit half-baked idea :/ This way it seems to loose event handlers.
Corrected version of patch uses former method for list updates. Will check twice next time before posting anything. Sorry for making a mess...
diff -ur roundcube/program/include/rcube_json_output.php roundcube_test/program/include/rcube_json_output.php --- roundcube/program/include/rcube_json_output.php 2008-05-19 13:19:16.000000000 +0200 +++ roundcube_test/program/include/rcube_json_output.php 2008-05-20 18:51:50.342518104 +0200 @@ -213,14 +213,18 @@ private function get_js_commands() { $out = '';
//$out .= "time1 = new Date();\n";
foreach ($this->commands as $i => $args) {
$method = array_shift($args);
foreach ($args as $i => $arg) {
@@ -232,8 +236,11 @@ preg_replace('/^parent./', '', $method), implode(',', $args) );
}
}
} diff -ur roundcube/program/js/app.js roundcube_test/program/js/app.js --- roundcube/program/js/app.js 2008-05-19 13:19:53.000000000 +0200 +++ roundcube_test/program/js/app.js 2008-05-20 18:05:14.679523480 +0200 @@ -373,7 +373,7 @@ }
// set eventhandler to message icon
@@ -3227,13 +3227,31 @@ } };
diff -ur roundcube/program/js/list.js roundcube_test/program/js/list.js --- roundcube/program/js/list.js 2008-05-19 13:19:53.000000000 +0200 +++ roundcube_test/program/js/list.js 2008-05-20 23:34:04.219177552 +0200 @@ -28,6 +28,7 @@ this.DELETE_KEY = 46;
this.list = list ? list : null;
@@ -145,13 +146,30 @@ this.rows[uid] = null; },
+init_off_list: function() +{
+},
+flush_off_list: function() +{
+},
/**
*/ insert_row: function(row, attop) {
if (this.off_list)
{
var tbody = this.off_list;
}
else
{
var tbody = this.list.tBodies[0];
}
if (attop && tbody.rows.length) tbody.insertBefore(row, tbody.firstChild);
diff -ur roundcube/program/steps/mail/func.inc roundcube_test/program/steps/mail/func.inc --- roundcube/program/steps/mail/func.inc 2008-05-19 13:19:56.000000000 +0200 +++ roundcube_test/program/steps/mail/func.inc 2008-05-20 23:41:52.483990480 +0200 @@ -296,7 +296,7 @@
// return javascript commands to add rows to the message list -function rcmail_js_message_list($a_headers, $insert_top=FALSE) +function rcmail_js_message_list($a_headers, $insert_top=FALSE, $use_off_list=FALSE) { global $CONFIG, $IMAP, $OUTPUT;
@@ -310,6 +310,9 @@
$OUTPUT->command('set_message_coltypes', $a_show_cols);
@@ -355,6 +358,9 @@ preg_match("/multipart/m/i", $header->ctype), $insert_top); }
diff -ur roundcube/program/steps/mail/list.inc roundcube_test/program/steps/mail/list.inc --- roundcube/program/steps/mail/list.inc 2008-05-19 13:19:56.000000000 +0200 +++ roundcube_test/program/steps/mail/list.inc 2008-05-20 23:42:18.867979504 +0200 @@ -55,7 +55,7 @@
// add message rows if (isset($a_headers) && count($a_headers))
else $OUTPUT->show_message('nomessagesfound', 'notice');
List info: http://lists.roundcube.net/dev/