简体   繁体   中英

How can I optimise this HTML to render faster in the browser?

I've inherited an app that generates html for a large list of items. There are about 2500 items grouped into categories, so a giant 2500+ row table is created. Here is the code rendered for a single row:

  <tr id='ev_2075_321' class='datagridRow1'>
      <td align='left'>
        <div style='margin-left: 20px;'>
          <table cellspacing='0' cellpadding='0' style=
          'cursor: pointer; width: 100%;'>
            <tr>
              <td style='width: 10px;'>
                <img src='images/RewardsGreen.gif'>
              </td>
              <td valign='middle' align='left' style='cursor: default;'
              ondblclick='doNothing;' onclick=
              'listOnClick(5,"WHI.E_2075");'
              onmouseover=
              'highlightListItem("ev_2075_321", true); showInfoBubble(5,"WHI.E_2075","ev_2075_321","ev_cond_eventsContainer");'
              onmouseout=
              'highlightListItem("ev_2075_321", false, 1); hideInfoBubble();'>
              <span style='margin-left: 3px;'>Card Registration</span>
              </td>
            </tr>
          </table>
        </div>
      </td>
    </tr>

Do you think if I reduce this to a single list item with a background image, the render time will improve? Currently it just crashes in Firefox and IE. I commented out the event handlers and only saw about a 30% speed up, I am considering to making them class based, and binding the handlers via jQuery selector. Any other ways I can speed this up? Or do you think I need some paging.

If pagination is not an option you should try:

  1. Event delegation (http://davidwalsh.name/event-delegate). This will allow you to register one listener per event type.
  2. 'table-layout: fixed' on the style of the table (http://www.w3schools.com/css/pr_tab_table-layout.asp). This can drastically improve the rendering time of giant tables.
  • Pagination will see the best performance.
  • Move the inline CSS to external - why download that portion for every row?
  • Move event handlers to external - again save some bytes.

Use SlickGrid – it's designed specifically to handle huge datasets. I've used it with records numbering in the hundreds of thousands. SlickGrid achieves this level of performance by only rendering DOM elements for the rows you're actually looking at. As you scroll down, old rows are destroyed as the new ones are created, so you never actually have more than a minimum number of elements in the DOM at a given time. Demos here.

(Caveat: be careful if you're binding event handlers to elements in the grid. Slick bypasses jQuery and sets innerHTML on its own, which will leak any handlers bound via jQuery.)

From a UX standpoint, I really prefer SlickGrid's approach (virtual scrolling). I hate dealing with paginated data.

Your best bet would be to introduce paging. Your page load time will decrease by having 1/20th of the total data at a time (assuming 100 items per page). Readability of your content will also improve greatly.

2500 rows is a lot. You might want to consider a paging option to simplify this and just limit the amount of DOM on the page. Some consider paging crude, but it is relatively easy to implement.

Another options is to write a custom tables js codes that only renders what is currently viewed, plus a buffer on either side. That is very complex though.

A third option would be to use a third-party grid. Thats what I would do.

Remember that browsers are really good at innerHTML replace. So if you are appending 2500 rows individually, you can probably get a speed up by batching inner html operations.

Whilst 2500 items is indeed a lot, I don't think it's enough to warrant a browser crash (esp. in Firefox).

Try the following optimizations (as noted by others above me as well):

  • Reduce the amount of HTML markup you have
  • Inline event handlers are usually faster (from my experience) rather than a bind with jQuery. In any case, take them out and create a timer to bind the events for you instead (timers run on a separate thread to the UI). If you want to be extra tricky, you can even create pagination and only bind the click handlers as a user scrolls between pages.
  • Ditch that inline image. Those will always cause a page to load slower. A CSS class is faster.

Ultimately, the best solution for you however, is to:

  1. Introduce pagination or;
  2. Introduce a "never ending scroll" type feature (eg like Google Reader does)

An alternative to pagination is lazy loading or on-demand loading. Just load a small part of the table to begin with, and when the user scrolls to the bottom of the page, load another small part, and so on.

Also, get rid of your inline attributes like valign/align/style and offload all of that stuff into external CSS.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM