Suo Lu

Thinking in Data

| | email

File Upload Server Progress Estimation

jQuery File Upload Plugin

blueimp/jQuery-File-Upload is a File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery.

The plugin has a feature Upload progress support most model browsers, you can create a progress bar indicating the upload progress status.

Problem

The progress is based on ProgressEvent, however any server-side processes like validation or persistence will not effect to the event.

No server-side progress

The progress is hanging on 100% and wait for server’s response.

Server Progress

There are some methods to solve the problem with server-side changes: ajax pooling, web socket, or even redesign the server process totally asynchronized and return to client instantly (actually this is the principle to design distribute system, although complicated).

Any possibly simpler way? Yes, there is a solution only need to modify front-end code, which is estimate server consume time and include into the whole progress - simulate the server progress.

Suppose server will spend 30% of time:

// test code
$('#fileupload').fileupload({
    /* ... */
    progressall: function (e, data) {
        var progress = parseInt(data.percent * 100, 10);
        $('#progress .bar').css(
            'width',
            progress + '%'
        );
    },
    progressServerRate: 0.3
});

Parameter progressServerRate: estimated server progress percentage. With it the progress bar will keep part of spaces for server consuming.

Exponential Decay

It is necessary to use a math function specify the rate of change of the parameter over time. We don’t want server progress finishes in constant time, because anyway there is no way to know the actual server consumed time, you can’t really update the progress to 100% ever unless the server is responded.

Exponential Decay is good at this thing.

Exponential decay

// source code of calculate increase percentage
var incr = Math.pow((1 - data.percent), data.progressServerDecayExp);
data.percent += incr;

Each time calling above codes the progress will increase a little bit, accelerated speed depends on the exponent parameter.

Parameter progressServerDecayExp: Server progress exponential decay (the exponent of equation).

// test code
$('#fileupload').fileupload({
    /* ... */
    progressall: function (e, data) {
        var progress = parseInt(data.percent * 100, 10);
        $('#progress .bar').css(
            'width',
            progress + '%'
        );
    },
    progressServerRate: 0.3,
    progressServerDecayExp: 2
});

Examples:

progressServerRate: 0.4, progressServerDecayExp:2

rate=0.4 and exp=2

progressServerRate: 0.5, progressServerDecayExp:3.5

rate=0.5 and exp=3.5

Moreover, you can display a message of process is in either client or server progress at a moment. More detail please refer to commit 1767bf7.

BTW Easing functions is a cool website of easing cheat sheet visualization.

Estimate Parameter Value

Note the last anime above, the progress is a little far away 100% before done. Sometimes you need to pick a suitble length for progress bar and parameter value.

Here are several rules can help estimate parameter:

Firefox

When I worked on the feature, I found a Firefox progress event bug, it didn’t trigger progress event for the final small piece resource content loaded, until the finally response from server.

My environment:

If you know something kindly let me know.

03 Nov 2015