使用jQuery和Node在DOM上填充数据的最佳方法

wri*_*wan 4 javascript jquery dom node.js socket.io

我正在使用Node Socket.io将数据从服务器推送到客户端浏览器.在客户端我使用jQuery填充DOM中返回的行.

我在代码片段下面用来填充Socket.io返回的数据.

var OverSpeedAlerts = [];
var TripCancellation = [];
var GeofenceInOutAlerts = [];
var ScheduleOverstay = [];
var UnSchduledOverstay = [];
var SkippedBusStop = [];
var TripDelayAlert = [];

var SkippedUnplannedAlert = [];
var DelayStartEndAlert = [];
var RouteDeviatedAlert = [];

var MultipleBusEntry = [];
Run Code Online (Sandbox Code Playgroud)

声明原型:

Array.prototype.inArray = function (comparer) {
    for (var i = 0; i < this.length; i++) {
        if (comparer(this[i])) return true;
    }
    return false;
};

// adds an element to the array if it does not already exist using a comparer 
// function
Array.prototype.pushIfNotExist = function (element, comparer) {
    if (!this.inArray(comparer)) {
        this.unshift(element);
    }
};
Run Code Online (Sandbox Code Playgroud)

处理从套接字收到的数据:

if (typeof io !== 'undefined') {
    var pushServer = io.connect('http://SomeIP:3000');
    pushServer.on('entrance', function (data) {
        var rows = data.message;
        var NumberOfRows = rows.length;
        $('#notifications').html(NumberOfRows);
        // console.log(rows);
        OverSpeedAlerts = [];
        TripCancellation = [];
        GeofenceInOutAlerts = [];
        ScheduleOverstay = [];
        UnSchduledOverstay = [];
        SkippedBusStop = [];
        TripDelayAlert = [];

        SkippedUnplannedAlert = [];
        DelayStartEndAlert = [];
        RouteDeviatedAlert = [];

        var MultipleBusEntry = [];
        for (var i = 0; i < rows.length; i++) {
            if (rows[i].alert_type == 'overspeed') {
                OverSpeedAlerts.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'trip_cancellation') {
                TripCancellation.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Geofence-In' || rows[i].alert_type === 'Geofence-Out') {
                GeofenceInOutAlerts.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Scheduled-Overstay') {
                ScheduleOverstay.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Unscheduled-Overstay') {
                UnSchduledOverstay.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Skipped Unplanned' || rows[i].alert_type == 'Skipped-Busstop') {
                SkippedBusStop.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Delay Start' || rows[i].alert_type == 'Delay End') {
                TripDelayAlert.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Route Deviated') {
                RouteDeviatedAlert.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Multiple Bus Entry') {
                MultipleBusEntry.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }

        }
        CreateOverSpeedGrid();
        CreateTripCancellation();
        CreateGeofenceGrid();
        CreateScheduleOverstayGrid();
        CreateUnSchduledOverstayGrid();
        CreateTripDelayGrid();
        CreateSkippedBusStop();
        CreateRouteDeviationAlert();
        CreateMultipleBusEntry();
    });
    pushServer.on('end', function (socket) {

    });
}
Run Code Online (Sandbox Code Playgroud)

上述功能之一如下.Rest是在DOM的其他部分填充数据的类似功能.

function CreateOverSpeedGrid() {
    $('#tabs ul').find('a:contains("Overspeed Alerts")').html('OverSpeed Alerts(' + OverSpeedAlerts.length + ')');
    if (OverSpeedAlerts.length != 0) {
        $('#notifyOverspeed table').html('');
        $('#notifyOverspeed table').append('<tr class="ui-widget-header"> <th> Depot </th> <th> Route </th> <th> Schedule </th> <th> Trip Number </th><th>Trip Direction</th> <th> Alert Summary</th> <th> Alert Details </th> <th> Generated On </th> </tr>'); //new Date([UNIX Timestamp] * 1000);
        for (var i = 0; i < OverSpeedAlerts.length; i++) {
            $('#notifyOverspeed table').append('<tr> <td>' + OverSpeedAlerts[i].depot_name + '</td> <td>' + OverSpeedAlerts[i].route_name + '</td> <td>' + OverSpeedAlerts[i].schedule_no + '</td> <td>' + OverSpeedAlerts[i].trip_number + ' </td> <td>' + OverSpeedAlerts[i].trip_direction + '</td><td> ' + OverSpeedAlerts[i].alert_sub + ' </td> <td title="' + ConvertToValidTooltip(OverSpeedAlerts[i].alert_msg) + '" style="text-decoration:underline;cursor:pointer;"> ' + "Place mouse pointer to view message" + ' </td> <td>' + new Date(OverSpeedAlerts[i].alert_gen_date_time * 1000) + ' </td> </tr>');
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码工作正常.问题是,由于从套接字每隔10秒收到如此多的推送消息,浏览器无法处理如此多的数据并挂起.

有没有更好的方法呢?

Lou*_*uis 5

我在这段代码中看到以下问题:

  1. 您可以通过多次操作文档来更新表.在一次操作中更新DOM的性能更好.有关于此的Google文章.所以类似于:

    function CreateOverSpeedGrid() {
        $('#tabs ul').find('a:contains("Overspeed Alerts")').html('OverSpeed Alerts(' + OverSpeedAlerts.length + ')');
        if (OverSpeedAlerts.length != 0) {
            var html = [];
            html.push('<tr class="ui-widget-header"> <th> Depot </th> <th> Route </th> <th> Schedule </th> <th> Trip Number </th><th>Trip Direction</th> <th> Alert Summary</th> <th> Alert Details </th> <th> Generated On </th> </tr>'); //new Date([UNIX Timestamp] * 1000);
            for (var i = 0; i < OverSpeedAlerts.length; i++) {
                html.push('<tr> <td>' + OverSpeedAlerts[i].depot_name + '</td> <td>' + OverSpeedAlerts[i].route_name + '</td> <td>' + OverSpeedAlerts[i].schedule_no + '</td> <td>' + OverSpeedAlerts[i].trip_number + ' </td> <td>' + OverSpeedAlerts[i].trip_direction + '</td><td> ' + OverSpeedAlerts[i].alert_sub + ' </td> <td title="' + ConvertToValidTooltip(OverSpeedAlerts[i].alert_msg) + '" style="text-decoration:underline;cursor:pointer;"> ' + "Place mouse pointer to view message" + ' </td> <td>' + new Date(OverSpeedAlerts[i].alert_gen_date_time * 1000) + ' </td> </tr>');
            }
            // Change the rows in one operation.
            $('#notifyOverspeed table').html(html.join(''));
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. inArray添加的方法Array必须先扫描整个数组,然后才能确定元素是否已存在于数组中.

    理想情况下,此过滤将在发送端完成.这是最好的.但是,您可能正在使用无法在源头过滤的第三方数据,因此......

    有一种方法可以做得更好.如果顺序很重要,您仍然可以使用数组来存储对象.然后,您可以使用创建的对象Object.create(null)作为关联数组,记录您是否已经看到对象.所以类似于:

    var OverSpeedAlerts = [];
    var OverSpeedAlertsSeen = Object.create(null);
    
    for (var i = 0; i < rows.length; i++) {
        var row = rows[i];
        var key = row.device_id + row.alert_gen_date_time;
    
        if (row.alert_type == 'overspeed' && !OverSpeedAlertsSeen[key]) {
            OverSpeedAlertsSeen[key] = true;
            OverSpeedAlerts.push(row);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    我不止一次使用过这种方法,但上面的代码没有经过测试.错字或脑袋可能潜伏在那里.在此示例中,为所有类型的警报计算一次密钥.查看您的代码,看起来所有警报都进行了比较device_id,alert_gen_date_time因此为阵列中的每个项目生成一次密钥是正确的.

    如何生成他们关键要看的可能值row.device_idrow.alert_gen_date_time.您可能需要一个分隔符以避免可能的歧义.例如,在我工作的情况下,我必须组合字母表中所有字母都有效的值.因此,没有一个分离器就没有办法区分"ab" + "cd""a" + "bcd""abc" + "d".我用的是不能出现在价值观建设的关键分隔符:那么"ab@cd","a@bcd","abc@d".

    也可以使用关联数组的关联数组来进行检查,但我不相信它会产生很大的速度提升.它肯定会使代码更复杂.

我可以想到可以提高速度的其他变化,但我认为它们不能提供实质性的收益.