浏览器加载较大的文件时无响应

时间:2014-09-24 16:44:30

标签: javascript html json d3.js

我下载了多个json数据文件,然后使用D3数据图表显示这些文件。当我加载页面时,需要花费大量时间来下载和可视化2-3分钟,甚至更多地在移动设备上。和浏览器显示一个无响应的对话框。有没有办法改善加载时间并优雅地处理加载时间?

每个文件都有几百(100 - 500)KB,而且有20到200个文件

以下是仅折线图的示例代码

drawLineChart它下载json文件并从中提取数据,formatLineChartData将数据格式化为输入d3,最后lineChartConfig绘制图表。类似地,有条形图,饼图,文字云和地图的功能。

var drawLineChart           = function(lineChartData,  suffix, el){
    var n = lineChartData.length;
    var dataArray = []; 
    var labels= '';

    var allNull  =true; //  flag to check if every ajax does not return any data
    for (var i=0; i<n; i++){
        spark.loadCounterJSON(lineChartData[i].file + suffix,i,
        function(res){
            var data =res.values;
            if(data){
                if(lineChartData[res.counter].slug !== 'global'){
                    allNull = false;
                }
                var title = Object.keys(data.entities)[0];

                graphValues = data[title];
                if(graphValues!=''){
                    labels = data['properties'];
                    dataArray.push(
                        formatLineChartData(
                            graphValues, 
                            lineChartData[res.counter].name,
                            true
                        )
                    );
                }
            }
            if(res.counter === n  && !allNull){ // all outer ajax done;

                lineChartConfig(el, 
                    dataArray, 
                    false, 
                    true,
                    ''
                ,labels);
            }
        });
    }   
};



var formatLineChartData     = function(graphValues, key, xDataType){
    formatedData = [];  

    $.each(graphValues, function(i, v){
        value = {};
        if(xDataType !== undefined){ 
            value['x'] = new Date(v.x);
        }
        else {value['x']=v.x;}
        value['y']=parseInt(v.y)
        formatedData.push(value);
    });     
    return {values:formatedData,key:key};   
}

var lineChartConfig             = function (div, data, guideline, useDates, auxOptions,labels, width, height) {
        var margin = {top: 20, right: 20, bottom: 30, left: 50},
            width = width - margin.left - margin.right,
            height = height - margin.top - margin.bottom;

            //var parseDate = d3.time.format("%d-%b-%y").parse;

            var x = d3.time.scale()
                .range([0, width]);

            var y = d3.scale.linear()
                .range([height, 0]);

            var xAxis = d3.svg.axis()
                .scale(x)
                .orient("bottom");

            var yAxis = d3.svg.axis()
                .scale(y)
                .orient("right");

            var line = d3.svg.line()
                .x(function(d) { return x(d.x); })
                .y(function(d) { return y(d.y); }); 


            var svg = d3.select(div).append("svg")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
                .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                var dataResult;
                for(var i=0;i<data.length;i++){
                    dataResult = data[i].values;
                }
        //console.log(dataResult);
        dataResult.forEach(function(d) {
            d.x = new Date(d.x);
            d.y = d.y;
          });

                x.domain(d3.extent(dataResult, function(d) { return d.x; }));
                y.domain(d3.extent(dataResult, function(d) { return d.y; }));

                svg.append("g")
                    .attr("class", "x axis")
                    .attr("transform", "translate(0," + height + ")")
                    .call(xAxis);


                svg.append("g")
                    .attr("class", "y axis")
                    .call(yAxis)
                  .append("text")
                    .attr("transform", "rotate(-90)")
                    .attr("y", 6)
                    .attr("dy", ".71em")
                    .style("text-anchor", "end");

                svg.append("path")
                    .datum(dataResult)
                    .attr("class", "line")
                    .attr("d", line);
}

1 个答案:

答案 0 :(得分:3)

您要做的第一件事就是找出问题所在。如果您有分析或性能工具,您可以尝试这些工具,但快速脏的方法可能只是让您的脚本在完成下载文件,当它完成创建图表等时使用当前时间回显。这应该可以让您大致了解您的时间花在哪里。

要提高下载速度,您需要将文件缩小,不要下载不需要的文件,或者如果保持在服务器上的上传速度而不是在客户端下载速度,则需要你的基础设施。

为了提高图表的处理速度......您需要优化代码,如果您使用的是构建的API,则可能没有选项。但您肯定希望确保不进行任何冗余调用,并检查文档中是否有任何优化选项。如果可能的话,您的服务器端操作也可以通过多线程/多处理来改进,并且您有硬件支持它。

至于优雅地处理它,一般原则应该是尽可能多地使用异步操作。例如,如果要加载多个图表,请将每个图表作为进度条启动,以便在数据下载(等)时更新,然后在可用时立即显示图表。它不会使流程更快,但它会使页面保持响应并让用户知情。