Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download block UI thread with small file #193

Open
Crash-- opened this issue Oct 24, 2016 · 8 comments
Open

Download block UI thread with small file #193

Crash-- opened this issue Oct 24, 2016 · 8 comments

Comments

@Crash--
Copy link

Crash-- commented Oct 24, 2016

I'm using RNFS for downloading file inside an app. Sometimes I can use the app during a download but sometimes not.

I've tested with a small file (~10Mo) and the bug occurs, but with a large file (~1Go) it doesn't.

When I check the log with XCode, I can see, with the small file, that the percentage displayed within the app is not the same that it displayed within Xcode. But with the big file I don't have this problem.

I just tested on Android too, and I get the same weird behavior.

Here is the code I'm using. I tried without progressDivider but same result.

download = (idCourse) => {
    begin = (res) => {
      if (res.statusCode == '404') {
        this.props.cancelDownload(this.props.course.id_course)
        return false
      } else {
        this.jobId = res.jobId
        this.props.setPercentage(this.props.course.id_course, 0, this.jobId)
      }
    }

    progress = (data) => {
      const percentage = ((100 * data.bytesWritten) / data.contentLength) | 0;
      this.props.setPercentage(this.props.course.id_course, percentage, this.jobId)
    }
    const localPath = this.props.course.id_course + '.zip';
    const remoteURL = getCourseZipUrl(this.props.course.id_course)
      const downloadDirectory = Platform.OS === 'ios' ? RNFS.DocumentDirectoryPath + '/downloads/' : RNFS.ExternalDirectoryPath + '/downloads/';

      const realLocalPath = downloadDirectory + '/' + localPath;
      const progressDivider = 1;
      const ret = RNFS.downloadFile({fromUrl: remoteURL, toFile: realLocalPath, begin, progress, false, progressDivider})
      ret.promise.then(res => {
        if (res.statusCode == '404') {
          this.props.cancelDownload(this.props.course.id_course)
        } else{
          this.props.setFinished(this.props.course.id_course)
        }
      }).catch(err => {
        console.log('errorDL', err)
      })
  }

 stopDownload = (idJob) => {
    if (idJob !== -1) {
      RNFS.stopDownload(idJob);
      this.props.cancelDownload(this.props.course.id_course)
    }
  }

Without the bug

download_without_bug

With the bug

bug_dl

@hochbrian
Copy link

I'm seeing very similar behavior. 9 times out of 10 the UI locks until the download completes on Android and maybe 50/50 on iOS.

@kevboh
Copy link

kevboh commented Oct 19, 2017

Also seeing something that could be this.

@Crash--
Copy link
Author

Crash-- commented Oct 19, 2017

In fact this is something usual. As the percentage cames from the native side, it uses the RN bridge. This bridge is async. So if a lot of “operations” are passing by this bridge in a very short amount at time we get this lag.

A pretty simple workaround is to rise up progress divider if the file is small. Or getting the percentage every X secondes

@itinance
Copy link
Owner

This is strange. We use downloadFile with large Zip-FIles in our Zizzle-App very unblocking. Download happens in the background, a progressbar is shown at the bottom of the screen during the download and while all that the user can navigate thru the application without any implications.

@Crash--
Copy link
Author

Crash-- commented Oct 19, 2017

Yeah with large file it’s pretty smooth. This is exactly what I tried to explain previously. Downloading large file implies that percentage goes up slowly. So you have several seconds between each increment. As you have several secondes (or dozen or even minutes) the RN bridge is not filled, not saturated because it doesn’t received 100 events in 5 secondes... this is one of the main RN issue

@Andrfas
Copy link

Andrfas commented Jan 4, 2018

Is there a workaround? I have the same issue with blocked UI. In my case I'm downloading multiple files together (calling downloadFile for each file)

@stachu2k
Copy link

stachu2k commented Mar 6, 2018

I'm also experiencing this issue with small files when UI refreshes progress every second. With large files or when I increase progressDivider UI is not refreshed every second and I'm able to interact with app, though it's still laggy and some small delay exist. I also noticed that when downloading small file is completed, every touch interaction during downloading is queued and executed right after downloading completes. This issue is not present when debugging with Chrome remote debugger, it might be because all tasks are performed by Chrome instead of Android/iOS.

Edit: I managed to decrease an occurrence of blocking UI by disabling re-rendering unnecessary components, so now I'm updating only Text component. But still, app is very laggy when progress event updates Text every second.

@nikunjdhamelia
Copy link

did anyone solve this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants