skip to Main Content

I’m using billboard.js to display this type of chart somewhere below the fold of my page.

Adding the billboard JS code is causing my mobile page speed to decrease from 90+ to 75-80.

My code is structured like this:

<!-- chart area -->
<div class="chart_holder">
    <div id="chart_area"></div>
</div>
...
...
...
<script src="/js/d3.v5.min.js"></script>
<script src="/js/billboard.min.js"></script>
<script defer src="/js/moment.min.js"></script>
<script type="text/javascript">function drawChart(t){$(".chart_holder").show(),.........);</script> 

Is there any way to make the chart load later, in order to solve google page speed issues like:

  • Reduce JavaScript execution time
  • Keep request counts low and transfer sizes small (Extra JS files are pretty big)

  • Minimize main-thread work (Script Evaluation)

While at the same time, allow Search engine crawlers to understand that I’m providing added value to my visitors by displaying them data charts? It might be good for SEO so I don’t want to hide the chart in a way that google can’t see it for example.

EDIT:

This is how the chart is called:

$(document).ready(function() {
    $.ajax( {
        type:"GET", url:"chart/data.php", dataType:"json", data: {
            item_id: 'item'
        }
        , success:function(t) {
            void 0!==t.criteria?t.criteria[0].length<=2?$(".chart_holder").hide(): drawChart(t): $(".chart_holder").hide()
        }
        , error:function() {
            console.log("Data extraction failed")
        }
    }
    )
}

2

Answers


  1. CAUTION: this is based on the assumption that Google page speed calculations will not count the script loading if it is delayed 1 second, I haven’t verified myself. Google page speed calculation script may change in the future, be sure to test with and without the delay.

    NOTE: of course it can be damaging for user experience if your entire page display rely on the script. For the OP’s problem, it seems acceptable.

    The trick here is to use a timeout of 1000ms after page load to load the script and when done, display the chart:

    $(document).ready(function() {
        setTimeout(function() {
            //you may need to change URL to a full URL here (with 'http://domain.etc')
            $.getScript('/js/billboard.min.js', function() {
                //you probably can keep this in your <script> tag, put it here if you have 'X is undefined' errors coming from calls to billboard's stuff
                function drawChart(t){$(".chart_holder").show(),.........);
                //your ajax call and the chart display
                $.ajax( {
                    type:"GET", url:"chart/data.php", dataType:"json", data: {
                        item_id: 'item'
                    },
                    success:function(t) {
                        void 0!==t.criteria?t.criteria[0].length<=2?$(".chart_holder").hide(): drawChart(t): $(".chart_holder").hide()
                    },
                    error:function() {
                        console.log("Data extraction failed")
                    }
                } );
            });
        }, 1000);
    });
    

    ALSO: It’s not clear from the question if you need the 3 scripts in the code for the chart or only billboard. If you want to delay the 3 of them, you need to chain getScript calls like this:

    $.getScript('/js/d3.v5.min.js', function() {
        $.getScript('/js/billboard.min.js', function() {
            $.getScript('/js/moment.min.js', function() {
                //the rest
            });
        });
    });
    
    Login or Signup to reply.
  2. Minimizing http request

    billboard.js provides a packaged version of d3 + billboard.js.

    https://cdn.jsdelivr.net/npm/billboard.js/dist/billboard.pkgd.min.js

    So, if you need to deal with file counts, deal with packaged version.

    Lazy rendering

    From the 1.11.0 release, added new feature to delay chart rendering. (Internally it will hold the rendering process)

    https://naver.github.io/billboard.js/demo/#ChartOptions.LazyRender

    var chart = bb.generate({
      ...,
      render: {
        lazy: true,
        observe: false
      }
    });
    
    setTimeout(function() {
        // call '.flush()' at the point you want to be rendered
        chart.flush();
    }, 1000);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search