Infinite scrolling and loading images

Infinite scrolling and loading images

flarpyflarpy Posts: 47Questions: 0Answers: 0
edited January 2013 in General
Hi Allan

My table has around 2000 rows and each row contains a small thumbnail image. At present, rendering the table results in 2000 requests to the server for images. Is there a way to only load images in view and load others later if the users scrolls?

Thanks

Replies

  • flarpyflarpy Posts: 47Questions: 0Answers: 0
    PS. This is the function that renders the relevant cell at present
    [code]
    var renderNames = function( data, type, row )
    {
    var html = ''
    html += '';
    html += '';

    html += '';
    html += ''+data+'';

    html += '<?php echo $this->translate('Comm');?>: '+row.commissionString+'';
    html += '<?php echo $this->escape($this->translate('ephc'), ENT_QUOTES);?>: '+renderFloat(row.ephc)+'';
    html += '<?php echo $this->escape($this->translate('Approval'), ENT_QUOTES);?>: '+row.affiliateApproval+'';
    if (row.userAction.status !== undefined) {
    var extraStyle = 'display:';
    } else {
    var extraStyle = 'display:none';
    }
    html += '<?php echo $this->escape($this->translate('Status'), ENT_QUOTES);?>: '+row.userAction.status+'';
    html += '';
    html += '';

    var tipDivId = 'programCommissions'+row.id;
    var myString = '';

    html += myString + renderEvents (row.events, type, row) + '';

    return html;
    }
    [/code]
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    When you note in the title "Infinite scrolling" do you mean you are using bScrollInfinite in DataTables? If so, it should only be loading the number of images in the first pass of the page size (default 10).

    If you are using regular scrolling (personally I'd recommend not using bScrollInfinite ) then you could use Scroller ( http://datatables.net/extras/scroller ) and ensure deferred rendering is enabled.

    If something else, then I think we'd more information about how you are actually initialising DataTables.

    Regards,
    Allan
  • flarpyflarpy Posts: 47Questions: 0Answers: 0
    Hi

    I am using bScrollInfinite, config is below. Images for all rows are retrieved on render which I have confirmed by checking the web server log, not just the first x. If I can tweak my config I'd rather do that.

    [code]
    // see http://datatables.net/usage/ for documentation
    var oTable = $('#programtable').dataTable( {
    "bProcessing": true,
    "bServerSide": false,
    "bDeferRender": false,
    "sAjaxSource": '<?php echo $this->sourceLink;?>?format=json',
    "aoColumnDefs": <?php echo $this->columnDefs;?>,
    "bScrollInfinite": true,
    "bScrollCollapse": true,
    "bAutoWidth": true,
    "sScrollY": "600px",
    "iDisplayLength": 30, // force scrollbar
    "sScrollX": "100%",
    "bStateSave": true,
    "sDom":'<"top"firlpt><"bottom"i>', // position elements in order http://datatables.net/usage/options#sDom
    "oLanguage": {
    "sProcessing": '<?php echo $this->translate("Downloading Program Data");?>',
    "sInfo": '<?php echo sprintf($this->translate("Showing %s to %s of %s entries"), '_START_', '_END_', '_TOTAL_');?>',
    "sInfoFiltered": '<?php echo sprintf($this->translate("(filtered from %s entries)"), '_MAX_');?>',
    "sSearch": '<?php echo $this->translate('Search').':';?>'
    },
    "aaSorting": [[1, 'asc']],
    "fnInitComplete": function (settings, data){
    $('#programtable_filter').append('');
    $('#columnChooserButton').click(function(){
    $('#columnChooser').dialog({
    show: "blind",
    hide: "explode",
    width: 675,
    title: '<?php echo $this->escape($this->translate('Choose Columns'), ENT_QUOTES);?>',
    modal: true
    });
    })
    $('#programtable_filter input[type=text]').focus();
    this.fnFilter('<?php echo $this->escape($this->translate('live'), ENT_QUOTES);?>', findColumnNumber('status', settings.aoColumns));
    },
    "fnDrawCallback": function (settings, data){
    $('.commissionString').tooltip({
    delay:0,
    top: -15,
    left: 25,
    bodyHandler: function() {
    var id = $(this).attr('id').substring(17);
    return $('#programCommissions'+id).html();
    }
    }
    )
    },
    "fnHeaderCallback": function( nHead, aData, iStart, iEnd, aiDisplay ) {
    var thead = $(this.fnSettings().nTHead);
    $('#filterRow').remove();
    $('select').die('change');
    var newRow = $('');
    var filteredData = [];
    var selected;
    settings = this.fnSettings();
    for (var e in settings.aoColumns) {
    if (settings.aoColumns[e].bVisible === false) {
    continue;
    }
    if (settings.aoColumns[e].filter !== false) {
    var property = settings.aoColumns[e].mData;
    var myCell = $('');

    selected = settings.aoPreSearchCols[e].sSearch;
    myCell.append(fnCreateSelect( this.fnGetColumnData(settings.aoColumns[e].mData, true, false), 'sortCol'+findColumnNumber(property, settings.aoColumns), selected));
    newRow.append(myCell);
    $('select').live('change', function () {
    oTable.fnFilter( $(this).val(), $(this).attr('name').substr(7));
    } );
    } else {
    newRow.append(' ');
    }
    }
    thead.append(newRow);
    }
    } );
    [/code]
  • flarpyflarpy Posts: 47Questions: 0Answers: 0
    Allan, I've pm'd you a login
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    You've currently got:

    > "bDeferRender": false,

    Could you set that to true?

    Although the nodes aren't being inserted into the DOM, it looks like the browser is fetching the images as soon as the nodes are being created (slightly surprised by that, as I thought the browser waited until the node was put into the document - however, it does match sense for it to prefetch to try and speed up rendering when the images are used...).

    Allan
  • flarpyflarpy Posts: 47Questions: 0Answers: 0
    Hi Allan

    I've tried changing bDeferRender to true in a dev environment but it didn't make any difference.
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    I've just put together the following two examples:

    With deferred rendering:
    http://live.datatables.net/efixus/edit#javascript,html .

    Without deferred rendering:
    http://live.datatables.net/efixus/2/edit

    If you look at the console in your browser, you'll see the first one correctly only loads the initially required images and then the others while scrolling. The one without deferred rendering loads them all up front, which is what you are seeing.

    Could you try updating the page on the server you sent me the link to please, so I can see what is happening there?

    Thanks,
    Allan
  • flarpyflarpy Posts: 47Questions: 0Answers: 0
    Hi Allan

    Sorry for the delay, we had a few things backed up in the deployment queue. The current live version now has bDeferRender set to true.
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Great - thanks. it looks like it is behaving correctly within your setup now.

    It is loading 30 images (confirmed with the Chrome Inspector), which is correct as you have the initial display length ( iDisplayLength ) set to 30:

    > "iDisplayLength": 30

    It is then immediately doing a filter on one of the columns, reducing the result set to 6 - but not before the DOM has been drawn for the 30 rows, thus 30 images are requested up front.

    I'd suggest reducing the display length as the first option. Perhaps 10 would be appropriate.

    More generally, I'd suggest using Scroller rather than infinite scrolling. Scroller is effectively the replacement to infinite scrolling, which has a range of limitations (manipulating the Dom etc).

    Regards,
    Allan
This discussion has been closed.