开发者

Javascript performance: Fastest way of building and injecting html

This is for a single page, mobile web-app....

For readability I've been concatenating my html, then injecting. I'm pretty certain there's a more efficient way, and would like to get a js expert's opinion!

heres an example of one of my concatenated html strings...

var html_str = '';
$.each(events_array, function(k, ev_type){
    if( localStorage.getItem('show_type'+ev_type.type_num) !== 'false' ){        
        $.each(ev_type, function(k2, e){
            if(typeof e != 'string'){
                if(fav_mode && last_date_num != e.date){
                    html_str += '<li class="date">'+e.date_text+'</li>';
                    last_date_num = e.date;
                }
                html_str += '<li';
                if(fav_mode | (FAVOURITES && $.inArray(parseInt(e.event_id), FAVOURITES) >= 0) ){
                    html_str += ' class="fav"';
                }
                html_str += '>';
                html_str +=     '<div class="l_'+e.gig_club+'"></div>';
                html_str +=     '<p rel="'+e.event_id+'"><span>'+e.venue+' : </span>'+e.nameofnight+'</p>';
                html_str += '</li>';                 
            }                         
        });
    }
});
return 开发者_开发知识库html_str


There is no "Fastest". There is only "Fastest" for a browser.

There are 3 common techniques. HTML string manipulation, templating and DOM manipulation.

Because templating can use both HTML string manipulation and the DOM internally I would recommend it for readability / maintainability.

Here are a few benchmarks

Templating

More templating

Templating with data for mobile platforms

Loads of templates

Dust js benchmark


If you're talking huge amounts of HTML and perf is paramount

Definitely Don't:

  • Inject dom nodes iteratively in a loop. This can mess with perf even in not-gigantic HTML scenarios.

  • Try to save work by using live existing HTML by tweaking attributes and swapping out content across a large variety of elements. As with the previous point this can get ugly even in things not involving thousands of elements. Large tables that don't have table-layout set to fixed can get particularly nasty when you trigger a ton of reflow.

  • Use jQuery's direct string to dom building - which, IMO, is actually excellent for most uses since it does a great job of validating for nasty escape sequences if injecting data from sources that may one day not be that secure. Use the html method to build from and inject from strings instead if you're going with strings. Although really for max perf, I'd probably just drop JQ if I 100% trusted my data.

Do:

  • Build it all out in a document fragment and append with that. Or build an HTML string and drop it all in at once. I prefer the hybrid method described below under "Maybe" but haven't tested in 2-3 years. That way the browser only has to repaint the page once. Google "CSS reflow" for more on that.

  • If you have to make lots of tweaks to a large volume of HTML, just change data and rebuild the whole set for same reason as above.

  • If you build from strings, minimize concatenation with the '+' operator and use array joins instead. Templating with arrays works great in a pinch.

  • Worry about the loops vs iterators that take a function argument if IE<=8 is a concern. Repeated function calls can get expensive without a JIT compiler. They can actually help you in JITs if they're inline (defined inside another function without any references returned outside).

  • Test everything you try. There's gray areas in everything but the multiple vs. one giant append rule. Multiple will always be slower.

Maybe:

An excellent trick in legacy browsers was to innerHTML large strings to document fragments and append those via DOM methods. This wasn't the fastest for all browsers but it was the best approach across the board back when IE7 mattered and the difference in modern JIT browsers between one-block innerHTML, DOM methods only into document fragment, and the hybrid approach were mostly negligible.


I would totally recommend templating too.

But I think you already make use of best practices about injecting HTML: it's far better to build the HTML, then inject it at one time, rather than injecting many times small bits of HTML, as the browser may repaint/reflow the document on each injection.


An explicit for loop will definitely be much faster than $.each(), mainly since that executes a function call for each element, but also for other reasons, e.g. with the new execution frame the lookup time for html_str will be longer.

There is some empirical evidence to suggest (I think this was valid with older browsers, I'm not sure what is faster nowadays or on mobile devices, it's worth checking out) that adding the elements to an array (with the loop variable html_str[i], and not html_str.push()) and then calling .join is faster than string concatenation.

As has been mentioned, adding one large DOM string is faster than small appends, and much faster than using DOM methods (appendChild, insertBefore, etc.).

A good templating engine would do these things for you (at a small extra cost), although I'm not sure if many of them do. And if it's only a small amount of "templating" then it might be overkill to use a library, when a simple loop does the trick.


You might as well consider using documentFragment, though it may not as readable as html string, it is very much effective (performance-wise) and readable maybe in object-oriented way.

you can visit this page for details: http://ejohn.org/blog/dom-documentfragments/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜