Infinite scrolling and loading images
Infinite scrolling and loading images
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
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
This discussion has been closed.
Replies
[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]
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
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]
> "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
I've tried changing bDeferRender to true in a dev environment but it didn't make any difference.
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
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.
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