admin管理员组

文章数量:1277898

I am using datatablejs on client side for displaying the database to client. I download the database from server initially using backbone indexeddb adapter and store it in indexedDB so as to support offline access to data. However, datatables take approx around 5 minutes to render 20,000 entries. This is my JS code:

render_data: function(entity_collection) {
        //create table body in memory
        tbody = $('<tbody>');
        tbody.html('');

        //iterate over the collection, fill row template with each object 
        //and append the row to table
        entity_collection.each(function(model) {
            tbody.append(this.row_template(model.toJSON()));
        }, this);
        //put table body in DOM
        this.$('#list_table')
            .append(tbody);
        //initialize datatable lib on the table    
        this.$('#list_table')
            .dataTable();
        $("#loaderimg")
            .hide();
        $("#sort-helptext").show();
},

Table headers:

<script type="text/template" id="person_table_template"> 
    <tr> 
        <th>Id</th> 
        <th>Name</th> 
        <th>Father Name</th> 
        <th>Village</th> 
        <th>Group</th> 
        <th></th> 
    </tr> 
</script>

JSON which is converted to html:

Object {
    age: 45, 
    father_name: "Jiyan Sah ", 
    gender: "F", 
    group: Object, 
    id: 10000000155392, 
    label: "Gangajali Devi (Sahila Rampur,Jiyan Sah )", 
    online_id: 10000000155392, 
    person_name: "Gangajali Devi ", 
    phone_no: "", 
    resource_uri: "/coco/api/v1/person/10000000155392/", 
    village: Object
}

Can anybody suggest about how to increase the performance of datatable?

I am using datatablejs on client side for displaying the database to client. I download the database from server initially using backbone indexeddb adapter and store it in indexedDB so as to support offline access to data. However, datatables take approx around 5 minutes to render 20,000 entries. This is my JS code:

render_data: function(entity_collection) {
        //create table body in memory
        tbody = $('<tbody>');
        tbody.html('');

        //iterate over the collection, fill row template with each object 
        //and append the row to table
        entity_collection.each(function(model) {
            tbody.append(this.row_template(model.toJSON()));
        }, this);
        //put table body in DOM
        this.$('#list_table')
            .append(tbody);
        //initialize datatable lib on the table    
        this.$('#list_table')
            .dataTable();
        $("#loaderimg")
            .hide();
        $("#sort-helptext").show();
},

Table headers:

<script type="text/template" id="person_table_template"> 
    <tr> 
        <th>Id</th> 
        <th>Name</th> 
        <th>Father Name</th> 
        <th>Village</th> 
        <th>Group</th> 
        <th></th> 
    </tr> 
</script>

JSON which is converted to html:

Object {
    age: 45, 
    father_name: "Jiyan Sah ", 
    gender: "F", 
    group: Object, 
    id: 10000000155392, 
    label: "Gangajali Devi (Sahila Rampur,Jiyan Sah )", 
    online_id: 10000000155392, 
    person_name: "Gangajali Devi ", 
    phone_no: "", 
    resource_uri: "/coco/api/v1/person/10000000155392/", 
    village: Object
}

Can anybody suggest about how to increase the performance of datatable?

Share Improve this question edited Feb 17, 2014 at 19:42 Carrie Kendall 11.2k6 gold badges63 silver badges81 bronze badges asked Feb 6, 2014 at 11:31 GauravGaurav 1,0453 gold badges15 silver badges33 bronze badges 4
  • Can you provide sample data row and template ? – Damian Krawczyk Commented Feb 6, 2014 at 13:05
  • @DamianKrawczyk Table headers: <script type="text/template" id="person_table_template"> <tr> <th>Id</th> <th>Name</th> <th>Father Name</th> <th>Village</th> <th>Group</th> <th></th> </tr> </script> – Gaurav Commented Feb 7, 2014 at 6:37
  • JSON which is converted to html: Object {age: 45, father_name: "Jiyan Sah ", gender: "F", group: Object, id: 10000000155392, label: "Gangajali Devi (Sahila Rampur,Jiyan Sah )", online_id: 10000000155392, person_name: "Gangajali Devi ", phone_no: "", resource_uri: "/coco/api/v1/person/10000000155392/", videos_seen: Array[19], village: Object} – Gaurav Commented Feb 7, 2014 at 6:39
  • my 2cents, why should we not assume that the delay is partly on the browser too, to draw the table onto the page. put a table-layout:fixed style to it and see if that helps. more info here w3/TR/CSS2/tables.html#propdef-table-layout – Sanjeev Commented Feb 18, 2014 at 2:02
Add a ment  | 

4 Answers 4

Reset to default 9 +25

Firstly, the is no need to append data on each iteration, you can do it once after loop.

var tmp_str = '';

entity_collection.each(function(model) {
    tmp_str+=this.row_template(model.toJSON())
}, this);

tbody.append(tmp_str);

But to really speed-up the app i remend you to change render way - now you render all data at once and have no information what part of information is watched but client. Lazy loading can help you - for eg. you render first 100 items, when page is scrolled to the bottom on the list you render + 100 and so on.

If you need some code help let me know.

Try to build the datatable directly from your js object (see DataTables Example here) instead of building a DOM object first.

Maybe datatablejs is faster in evaluating json arrays than in analysing such big DOM objects (and deleting most of it again)

Going this way you can set "bDeferRender": true which will cause that datatablejs will only render visible rows giving you a huge speed boost (see the datatablejs features page)

By using the js array initialization you lose HTML fallback for users without JavaScript of course - but I guess that's not your audience ;-)

Also take a look at disabling CSS height matching This could save you some rendering time.

if you want speed improvement, write your own function with Javascript and not use Jquery.

!!!! Its faster to first append and then add. !!!!!

use also cloneNode which is faster then document.createElement only create once and clone. Look at this and place in the html <body onload="alert (new Date().getTime()-b);">

it tooks 700 ms to generate a datatable with 20000 entries of course it depends on the machine and data reading

 var a=new Date().getTime ();
 var table_master=document.createElement ("table");
 var tbody_master=document.createElement ("tbody");
 var tr_master=document.createElement ("tr");
 var td_master=document.createElement ("td");
 var i,u, tr, td;
 document.body.appendChild (table_master);
 table_master.appendChild (tbody_master);

 for (i=0;i<4000;i++)
        {
        tr=tr_master.cloneNode ();
        tbody_master.appendChild(tr);   // check what happens if you put this line after for operation , when you first add the cells with data to tr and then append to the tbody, that would slow down imense
        for (u=0;u<5;u++)
            {
            td=td_master.cloneNode();
            tr.appendChild (td);
            td.appendChild (document.createTextNode("hello"));
            }
        }

Hey Brother Check this out this may help u -------

Client Side code -----

$("#table-tripNote").dataTable({
                "oLanguage": {
                    "sZeroRecords": "No records to display",
                    "sSearch": "Search from all Records"
                },
                "bProcessing": true,
                "bServerSide": true,
                "bDestroy": true,
                "sAjaxSource": "frmTrip.aspx/GetMemberNotesByTrip",
                "sPaginationType": "full_numbers",
                "bDeferRender": true,
                "aoColumns":
                            [
                                null,
                                null,
                                null,
                                null,
                                null,
                                null,
                                null
                            ],
                "fnServerData": function (sSource, aoData, fnCallback) {
                    $.ajax({
                        "dataType": 'json',
                        "contentType": "application/json; charset=utf-8",
                        "type": "GET",
                        "url": sSource,
                        "data": aoData,
                        "success":
                                                    function (msg) {

                                                        var json = jQuery.parseJSON(msg.d);
                                                        fnCallback(json);
                                                        $("#table-tripNote").show();
                                                    }
                    });
                }
            });

Server side code---

[WebMethod()]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public static string GetMemberNotesByTrip(string sEcho, int iDisplayStart, int iDisplayLength)
{

    string rawSearch = HttpContext.Current.Request.Params["sSearch"].Trim();

    var whereClause = string.Empty;

    var filteredWhere = "1=1";

    var wrappedSearch = rawSearch.Trim();
    var Tempsb = new StringBuilder();

    Tempsb.Append("mbrid=" + MemberID);
    if (TripID != 0)
    {
        Tempsb.Append("and trpid=" + TripID);
    }
    else
        Tempsb.Append("and trpid=0");

    if (rawSearch.Length > 0)
    {
        Tempsb.Append("AND ( ISNULL(trpDate,'''') LIKE ");
        Tempsb.Append("'%" + wrappedSearch + "%'");
        Tempsb.Append(" OR clrFullName LIKE ");
        Tempsb.Append("'%" + wrappedSearch + "%'");
        Tempsb.Append(" OR clrPhone LIKE ");
        Tempsb.Append("'%" + wrappedSearch + "%'");
        Tempsb.Append(" OR clrRelationshipToMember LIKE ");
        Tempsb.Append("'%" + wrappedSearch + "%'");
        Tempsb.Append(" OR trpNote LIKE ");
        Tempsb.Append("'%" + wrappedSearch + "%'");
        Tempsb.Append(" OR clrOrganization LIKE ");
        Tempsb.Append("'%" + wrappedSearch + "%'");
        Tempsb.Append(" OR trpIsGrievance LIKE ");
        Tempsb.Append("'%" + wrappedSearch + "%'");
        Tempsb.Append(")");
    }

    if (Tempsb.Length > 0)
        filteredWhere = Tempsb.ToString();

    string orderByClause = string.Empty;
    orderByClause = "trpDate desc";

    StringBuilder sb = new StringBuilder();
    sb.Append(Convert.ToInt32(HttpContext.Current.Request.Params["iSortCol_0"]));

    sb.Append(" ");

    sb.Append(HttpContext.Current.Request.Params["sSortDir_0"]);

    orderByClause = sb.ToString();

    if (!String.IsNullOrEmpty(orderByClause))
    {
        orderByClause = orderByClause.Replace("0", ", trpDate ");
        orderByClause = orderByClause.Replace("1", ", clrFullName ");
        orderByClause = orderByClause.Replace("2", ", clrPhone ");
        orderByClause = orderByClause.Replace("3", ", clrRelationshipToMember ");
        orderByClause = orderByClause.Replace("4", ", clrOrganization ");
        orderByClause = orderByClause.Replace("5", ", trpIsGrievance ");
        orderByClause = orderByClause.Replace("6", ", trpNote ");

        orderByClause = orderByClause.Remove(0, 1);
    }
    else
    {
        orderByClause = "pronID ASC";
    }

    DataSet ds = clsTrip.GetTripNotesMaster(filteredWhere, orderByClause, iDisplayLength, iDisplayStart, true);


    List<clsTrip> lstTripNotesGrv = new List<clsTrip>();
    for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
    {
        clsTrip lsttripNotes = new clsTrip();
        lsttripNotes.clrFullName = ds.Tables[0].Rows[i]["clrFullName"].ToString();

        if (!string.IsNullOrEmpty(ds.Tables[0].Rows[i]["trpDate"].ToString()))
            lsttripNotes.trpDate = Convert.ToDateTime(ds.Tables[0].Rows[i]["trpDate"].ToString());
        else
            lsttripNotes.trpDate = DateTime.MinValue;

        lsttripNotes.clrPhone = ds.Tables[0].Rows[i]["clrPhone"].ToString();
        lsttripNotes.clrRelationshipToMember = ds.Tables[0].Rows[i]["clrRelationshipToMember"].ToString();
        lsttripNotes.clrOrganization = ds.Tables[0].Rows[i]["clrOrganization"].ToString();

        if (!string.IsNullOrEmpty(ds.Tables[0].Rows[i]["trpIsGrievance"].ToString()))
            lsttripNotes.trpIsGrievance = Convert.ToBoolean(ds.Tables[0].Rows[i]["trpIsGrievance"].ToString());
        else
            lsttripNotes.trpIsGrievance = false;
        lsttripNotes.trpNote = (ds.Tables[0].Rows[i]["trpNote"].ToString());

        lstTripNotesGrv.Add(lsttripNotes);
    }
    int TotalRec = Convert.ToInt32(ds.Tables[1].Rows[0][0]);

    var result = from c in lstTripNotesGrv
                 select new[] { 
                       //Convert.ToString(c.pronID),                               
                       c.trpDate !=null && c.trpDate!=DateTime.MinValue ? string.Format("{0:MMM d, yyyy}",c.trpDate):"-",
                       c.clrFullName.ToString(),
                       c.clrPhone.ToString(),
                       c.clrRelationshipToMember.ToString(),
                       c.clrOrganization.ToString(),
                       ( Convert.ToBoolean(c.trpIsGrievance)?"Yes":"No"),
                       c.trpNote
                   };

    JavaScriptSerializer jss = new JavaScriptSerializer();
    return jss.Serialize(new
    {
        sEcho,
        iTotalRecords = TotalRec,
        iTotalDisplayRecords = TotalRec,
        aaData = result
    });
}

本文标签: javascriptSpeeding up Datatables load time on client sideStack Overflow