开发者

A jQuery AJAX request with LinQ filter and jQuery tmpl example

We used this script to get, and filter a JSON with 100.000 elements, to make some quick search at user-side, but unfortunately this is not fast enough.

What do you think, how can i make this script run faster?

<script> 
    $(document).ready(function () {
        var data__ = new Array();
        var val__ = new Array();
        var val_sum = 0;


            $.ajax({
                url: 'hotel.php',
                type: 'POST',
                dataType: 'json',
                timeout: 5000,

                beforeSend: function () {

                }, error: function (xhr, ajaxOptions, thrownError) {
                    alert(xhr.responseText);
                    alert(thrownError);
                    return false;
                },

                success: function (data) 
                {
                    var list = JSLINQ(data)
                       .Where(function(item){ return item.regio == "Afrika"; })
                       .OrderBy(function(item) { return item.name; })
                       .Select(function(item){ return item; });

                    var movies = list['items']

                    var markup = "<tr><td colspan='2'><b>Hotel: </b> ${name}</td><td><b>Régió:</b> ${regio}</td><td><b>Ors开发者_如何学编程zag:</b> ${orszag}</td><td><b>Város:</b> ${varos}</td></tr>";

                    /* Compile markup string as a named template */
                    $.template( "movieTemplate", markup );

                    /* Render the named template */
                    $( "#movieList" ).empty();
                    $.tmpl( "movieTemplate", movies ).appendTo( "#movieList" );
                }
            });
            return false;
    });
</script> 

Thanks for the help.


I'm going to propose some general enhancements (item #1) and some specific (rest of them). You can pick and choose which ones you want to go with.

  1. Compile your template once and not on every success call. Move them outside of success.
  2. Instead of JSLinq, use underscoreJS. UnderscoreJS delegates calls to native browser implementation whenever possible and thus, is the single biggest performance improvement.
  3. If you can, use underscore templates instead of jQuery. They are faster than jQuery and also are more flexible (as they are pure JS unlike jQuery which wraps things for you). Note: Recently there have been talks about other templating engines but since I haven't used them, I can't say much about them.
  4. If the syntax of underscore bothers you, you can easily customize it to use jQuery syntax (they have an example on their documentation), although you'll easily get used to it pretty soon.

Rewriting your code with underscore JS:

<script> 
        $(document).ready(function () {
            var data__ = [];
            var val__ = [];
            var val_sum = 0;
            var markup = "<% _.each(items, function(item) { %><tr><td colspan='2'><b>Hotel: </b> <%= item.name %></td><td><b>Régió:</b> <%= item.regio %></td><td><b>Orszag:</b> <%= item.orszag %></td><td><b>Város:</b> <%= item.varos %></td></tr><% }); %>";
            var compiledTemplate = _.template(markup);


                $.ajax({
                    url: 'hotel.php',
                    type: 'POST',
                    dataType: 'json',
                    timeout: 5000,

                    beforeSend: function () {

                    }, error: function (xhr, ajaxOptions, thrownError) {
                        alert(xhr.responseText);
                        alert(thrownError);
                        return false;
                    },

                    success: function (data) 
                    {
                        var list = _(data)
                                         .chain()
                                         .select(data, function(item){ return item.regio == "Afrika"; })
                                         .sortBy(function(item) { return item.name; })
                                         .value();

                        var movies = list['items']

                        /* Render the named template */
                        $( "#movieList" ).empty().append(compiledTemplate(movies));

                    }
                });
                return false;
        });
    </script> 

The biggest improvement can be seen on the slowest browser - IE7. This code should be 10 times (approx) faster than you existing code, but do profile them to get exact figures.


Surely you want to apply the logic that JSLinq is doing on the server side.

So on the serverside only return results where Name='Afrika' and order the results by name. Then you don't have the overhead of JSLinq filtering and ordering all of your results.

This would produce.

  • Less data sent over the wire (as filtering done server side)
  • No ordering required (data sent in correct order)


I would guess that most of the time is spent executing the LINQ-query. I'd suggest that you run the code through a javascript profiler, like Profiles in Google Chrome to locate cumbersome operations.

Also, === might at times be faster than == as the former does not perform type conversion, which you might benefit from when traversing larger collections. Also using the profiler, see if there are any benefits by using raw javascript code to perform the operations:

var result = [];
for (var d in data) { // or regular for (var i = 0; ... 
    if (d.regio === "Afrika") {
        result.push(d); // or result[result.length] = d;
    }
}

result.sort(function(a, b) {
    // sort a.name and b.name
});

I do realise this make minimum use of the jQuery core, but it's a means for you to at least examine the overhead (or optimisation) that the library is offering.

Also try to use regular string concatenation (or array joins depending on what works the best for you) over a fully fledged template engine.


You are returning items where region indicates "Afrika". Note that spelling of 'Afrika' could be 'Africa' and that you may still get a lot of items even when you get a timeout. In the database, make sure that the table is properly indexed to make the where and orderby as fast as possible.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜