【问题标题】:browser unresponsive upon loading larger files加载较大文件时浏览器无响应
【发布时间】:2014-11-19 06:18:44
【问题描述】:

我正在下载多个 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);
}

【问题讨论】:

  • 您的数据到底有多大?您是否考虑过动态加载它?
  • 我编辑问题。动态加载是什么意思?
  • 我的意思是,也许您可​​以将您的内容分成更小的部分,最初只加载其中的几个部分,然后在初始加载后加载其余部分。

标签: javascript html json d3.js


【解决方案1】:

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

要提高下载速度,您需要缩小文件,而不是下载不需要的文件,或者如果您的服务器上的上传速度受阻,而不是客户端的下载速度,请提高您的基础架构。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 2017-05-11
    相关资源
    最近更新 更多