Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

addRule is very slow for large pages

Status
Not open for further replies.

Einstein47

Programmer
Joined
Nov 29, 2001
Messages
737
Location
US
It is me again - back with more speed issues on my menu frame navigation. Just to let you know I am only programing for IE at this time (5.5, 6.0, and 7.0). FireFox isn't a consideration at this time (talk to my boss about it). Here is the URL of my example: Menu Frame Test

Running my test, this is the result I get
MenuSpeedSmall.png


Here is my code so you can see what is happening at each test point:
Code:
<script type="text/javascript">
var menuDiv;
var win;
[red]var timingStr = "";[/red]
function setInnerHTML(x,menu) {
    if (menu.length > 0) {
[purple]var startTime = new Date();[/purple]
      menuDiv = window.frames["mainFrame"].document.getElementById("menuDiv");
[purple]a = new Date();[/purple]
[red]timingStr += "Get Div: " + (a-startTime) + " ms";[/red]
      if (win && menuDiv && menuDiv.style) {
        win.populate(menu);
[purple]b = new Date();[/purple]
        win.showPopup(x,0);
[purple]c = new Date();[/purple]
[red]timingStr += "\n Populate Existing: " + (b-a) + " ms\n Show Popup: " + (c-b) + " ms";[/red]
      }
      else {
        var newElement = window.frames["mainFrame"].document.createElement("div");
[purple]b = new Date();[/purple]
        newElement.setAttribute("name", "menuDiv");
        newElement.setAttribute("id", "menuDiv");
        window.frames["mainFrame"].document.body.appendChild(newElement);
[purple]c = new Date();[/purple]
[red]timingStr += "\n Create Elem: " + (b-a) + " ms\n Append Child: " + (c-b) + " ms";[/red]
        with (window.frames["mainFrame"].document.getElementById("menuDiv").style) {
            position = "absolute";
            backgroundColor = "transparent";
            color = "MenuText";
            width = "auto";
            margin = "0";
            padding = "0";
            fontFamily = "Arial";
            fontSize = "8pt";
            overflow = "visible";
        }
[purple]c1 = new Date();[/purple]
        if (document.all) {
          with (window.frames["mainFrame"].document.styleSheets[0]) {
[purple]c2 = new Date();[/purple]
            [b]addRule("#menuDiv ul","margin:0;padding:0;list-style-type:none; width:210px; border:2px outset ThreeDFace; background:Menu;");[/b]
[purple]c3 = new Date();[/purple]
            [b]addRule("#menuDiv ul li","position: relative; background:Menu; overflow:visible;");[/b]
[purple]c4 = new Date();[/purple]
            [b]addRule("#menuDiv ul li ul","position: absolute;width: 180px;top:0; visibility:hidden; background:Menu;");[/b]
[purple]c5 = new Date();[/purple]
            [b]addRule("#menuDiv ul li a","font-family:Arial; font-size: 8pt; display:block; overflow:auto; padding:1px 5px; color:MenuText; background-color:Menu; text-decoration:none;");[/b]
[purple]c6 = new Date();[/purple]
            [b]addRule("#menuDiv a:hover","color:HighlightText; background-color:Highlight;");[/b]
[purple]c7 = new Date();[/purple]
            [b]addRule("#menuDiv hr","padding:0; margin-top:-2px; color:MenuText;");[/b]
[purple]c8 = new Date();[/purple]
            [b]addRule("#menuDiv .subfolderstyle","padding-right:0; background: url(ArrowPopup.gif) no-repeat center right;");[/b]
[purple]c9 = new Date();[/purple]
            [b]addRule("* html #menuDiv ul li","float: left; height: 1%;");[/b]
[purple]ca = new Date();[/purple]
            [b]addRule("* html #menuDiv ul li a","height: 1%;");[/b]
[purple]cb = new Date();[/purple]
          }
[red]timingStr += "\n - Init Styles: " + (c1-c) + " ms\n - Get With: " + (c2-c1) + " ms";[/red]
[red]timingStr += "\n - menuDiv ul: " + (c3-c2) + " ms\n - menuDiv ul li: " + (c4-c3) + " ms";[/red]
[red]timingStr += "\n - menuDiv ul li ul: " + (c5-c4) + " ms\n - menuDiv ul li a: " + (c6-c5) + " ms";[/red]
[red]timingStr += "\n - menuDiv a:hover: " + (c7-c6) + " ms\n - menuDiv hr: " + (c8-c7) + " ms";[/red]
[red]timingStr += "\n - menuDiv .subfolder: " + (c9-c8) + " ms\n - * html menuDiv ul li: " + (ca-c9) + " ms";[/red]
[red]timingStr += "\n - * html menuDiv ul li a: " + (cb-ca) + " ms";[/red]
        }

[purple]d = new Date();[/purple]
        win = new PopupMenu('menuDiv');
[purple]e = new Date();[/purple]
        win.autoHide();
        if (!win.listenerAttached) {
            win.listenerAttached = true;
            win.attachListener();
        }
[purple]f = new Date();[/purple]
        win.populate(menu);
[purple]g = new Date();[/purple]
        win.showPopup(x,0);
[purple]h = new Date();[/purple]
        menuDiv = window.frames["mainFrame"].document.getElementById("menuDiv");
[purple]h1 = new Date();[/purple]
[red]timingStr += "\n Apply Styles: " + (d-c) + " ms\n Create New Menu: " + (e-d) + " ms";[/red]
[red]timingStr += "\n Attach Listener: " + (f-e) + " ms\n Populate: " + (g-f) + " ms";[/red]
[red]timingStr += "\n Show Popup: " + (h-g) + " ms\n Get Div: " + (h1-h) + " ms";[/red]
      }
      [green]// Run script to convert unordered list to menus[/green]
[purple]z = new Date();[/purple]
      buildsubmenus();
      [green]// if main menu is too wide and the right edge extends off the screen, move it left[/green]
	  var clientWidth = parseInt(window.frames["mainFrame"].document.body.clientWidth,10);
	  var elemWidth = parseInt(menuDiv.offsetWidth,10);
	  while ((getLeftPos(menuDiv)+elemWidth) > clientWidth) {
        menuDiv.style.left = (getLeftPos(menuDiv) - 2) + "px";
        elemWidth = parseInt(menuDiv.offsetWidth,10);
	  }
var endTime = new Date();
[red]timingStr += "\n Build Submenus: "+(endTime-z)+" ms\nTotal: "+(endTime-startTime) + " ms";[/red]
[b]alert([red]timingStr[/red]);[/b]
[red]timingStr = "";[/red]
    }
}

The issue happens on very large pages. Some of our intranet pages are searches where the user can specify criteria and then get a list of results. One such page I have uploaded (after modifying names to protect privacy) and you can get to it from my sample page by selecting any link from the "Case" button other than the top "Find Case" link. It is 1,700 KB so it takes a while to load. After it loads completely, click on any of the buttons (other than "Home" or "Find Case") and you can see that it takes over 30 seconds to populate the menu and display it.

I have tracked it down to the [blue]addRule()[/blue] function to dynamically add Style information to an existing page element.

Is there someway I can make this process faster for large pages? Does IE have something other than addRule for adding complex Style Sheet rules?

Any advice is appreciated.

Einstein47
There are no kangaroos in Austria!
[&#91;]Starbase47.com]
 
no ideas? Anyone ... anyone ... Bueler?

Einstein47
There are no kangaroos in Austria!
[&#91;]Starbase47.com]
 
Thanks to a great FAQ about loading css dynamically, I have replaced all the "addRule" lines with the following:
Code:
  var css = window.frames["mainFrame"].document.createElement('link');
  css.rel = 'stylesheet';
  css.type = 'text/css';
  css.href = '/site/theme/Stylesheet.css';
  window.frames["mainFrame"].document.body.appendChild(css);
This still has to re-process the whole page again, but it only does it once. What was happening is that each time an "addRule()" was encountered, the whole page would need to be re-processed to apply the new CSS information. I guess you can't get around that - even though I am only adding style information for the new DIV I just created, how is the browser supposed to know that.

So I reduced my time from 40+sec to 5+sec. So it isn't the best, but it is better.

Einstein47
There are no kangaroos in Austria!
[&#91;]Starbase47.com]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top