Patch #486

low speed in a large directory structure

Added by Martin Beran about 1 year ago. Updated about 1 year ago.

Status:Closed Start date:23.02.2011
Priority:Normal Due date:
Assignee:Dmitry Levashov % Done:

100%

Category:Client
Target version:-

Description

If I have large directory structure (abaut 7000 dirs in tree), it's really slow...

1. should be used array.join() instead of string+= here:

    this.renderNav = function(tree) {
        var d = tree.dirs.length ? traverse(tree.dirs) : '',
            li = '<li><a href="#" class="el-finder-tree-root" key="'+tree.hash+'"><div'+(d ? ' class="collapsed expanded"' : '')+'/>'+tree.name+'</a>'+d+'</li>';
        this.tree.html(li);

        this.fm.options.places && this.renderPlaces();

        function traverse(tree) {
            var i, hash, c, html = [];
            html.push('<ul style="display:none">');
            for (i=0; i < tree.length; i++) {
                c = '';
                if (!tree[i].read && !tree[i].write) {
                    c = 'noaccess';
                } else if (!tree[i].read) {
                    c = 'dropbox';
                } else if (!tree[i].write) {
                    c = 'readonly';
                } 

                html.push('<li><a href="#" class="'+c+'" key="'+tree[i].hash+'"><div'+(tree[i].dirs.length ? ' class="collapsed"' : '')+'/>'+tree[i].name+'</a>');

                if (tree[i].dirs.length) {
                    html.push(traverse(tree[i].dirs));
                }
                html.push('</li>');
            }
            html.push('</ul>');
            return html.join('');
        }
    }

and here:

    this.renderCwd = function() {
        this.cwd.empty();

        var num  = 0, size = 0, html = [];
        for (var hash in this.fm.cdc) {
            num++;
            size += this.fm.cdc[hash].size;
            html.push(this.fm.options.view == 'icons'
                ? this.renderIcon(this.fm.cdc[hash])
                : this.renderRow(this.fm.cdc[hash], num%2));
        }
        if (this.fm.options.view == 'icons') {
            this.cwd.append(html.join(''));
        } else {
            this.cwd.append('<table><tr><th colspan="2">'+this.fm.i18n('Name')+'</th><th>'+this.fm.i18n('Permissions')+'</th><th>'+this.fm.i18n('Modified')+'</th><th class="size">'+this.fm.i18n('Size')+'</th><th>'+this.fm.i18n('Kind')+'</th></tr>'+html.join('')+'</table>');
        }

        this.pth.text(fm.cwd.rel);
        this.nfo.text(fm.i18n('items')+': '+num+', '+this.formatSize(size));
        this.sel.empty();
    }

but it's still slow, it's problem with draggable that binds to each item, we are trying to use draggable as live() - only for selected items

Associated revisions

Revision 8fb13d21
Added by Dmitry Levashov about 1 year ago

client: lazy load complete. closes #486, closes #54

History

Updated by Dmitry Levashov about 1 year ago

The first part of problem solved with dinamic tree loading http://elrte.org/redmine/issues/18 in developer version.
For second part, I think reason not in draggable but in slow browser rendering. But this need detailed investigation.
Watch developer version here - https://github.com/Studio-42/elFinder/tree/experimental

Updated by Martin Beran about 1 year ago

Thanks for answers and I'm sorry for duplicate first question

Dmitry Levashov wrote:

For second part, I think reason not in draggable but in slow browser rendering. But this need detailed investigation.

I have tried to disable all of draggable() method callings and the loading time has been reduced from 21 to 12 seconds. I think that the better solution would be to bind draggable() method only to selected items - not generally for all items during the initialisation.

But 12s is still slow

Updated by Dmitry Levashov about 1 year ago

You have over 7000 dirs in one directory or in tree?
If in tree - dinamic tree loading will help.
But if in one directory...

I not like idea to attach draggable only for selected items.
In this way usability go off - you can not drag file on mousedown and drag - you need first click and drag only after it.
Also I was tring to attach draggable on mousedown event, but failed.
May be you offer a solution?

Now I see only one solution - attach drag/drop not exactly after render, but in setTimeout call.

And I have another idea for directory content - render files in parts. 500-1000 files at once. tests required.

You may contact me in skype - dio_el_claire

Updated by Dmitry Levashov about 1 year ago

I got crazy idea!
Attach draggable on selection and on HOVER event 0_o

Updated by Dmitry Levashov about 1 year ago

It works!
I load tree with 872 directories and attach only droppable events. Render time is 1500 ms

Updated by Martin Beran about 1 year ago

I downloaded the development version, and I looked at it and:

1) Why don't you buffer the html to the list and join it? It would be faster ...

2) I have 7000 folders in one layer, if I want to show it, it's not loaded- Invalid backend configuration (but firebug show me correct JSON), but if I open a directory with a few items, it works.

Dmitry Levashov wrote:

Attach draggable on selection and on HOVER event

If you think hover like mouseover, it's not a good solution. If I select more items by dragging, mouseover isn't called on all items

Updated by Dmitry Levashov about 1 year ago

Lazy load save us! Thanks, Martin!

Updated by Dmitry Levashov about 1 year ago

  • Status changed from New to Closed
  • % Done changed from 0 to 100

Also available in: Atom PDF