This is the third day of my participation in the First Challenge 2022

In the last article we used the browser worker method. Today we’re going to try a different method to get a file hash

This method is based on React Fiber. We will not explain the principle of Fiber here. It is to divide a time-consuming task into small pieces, and after each piece is completed, the task is returned to React control. I continue with the task of slicing.

As for React Filber, it uses the requestIdleCallback method. Obviously, it’s a callback function based on its name. It’s a method that can be used when the browser is idle, but it’s not very compatible and it’s an experimental feature.

For documentation on the requestIdleCallback API, click here

Window. RequestIdleCallback () method inserts a function, this function will be called the browser idle period. This enables developers to perform background and low-priority work on the main event loop without affecting the delay of critical events such as animations and input responses. Functions are typically executed in first-come-first-called order; however, if a callback function specifies a timeout, it is possible to scramble the order of execution in order to execute the function before it times out.

With that in mind, let’s also fiddle with our file uploads

  1. Let’s first define a function that needs to be executed
  2. When the slice is not uploaded and the browser has free time, we execute the slice task
  3. Calculate progress bar

We first use sparkMD5 to generate an array of buffers that are placed in the appendToSpark method for each small piece of work performed

const spark = new sparkMD5.ArrayBuffer()

The progress bar of this method may not be as accurate as the previous one, which is obtained by the number of currently completed small tasks/total number of slices. The greater the chunk of each task executed, the less accurate the progress bar will be

The main purpose of this article is to broaden our horizons and see if we can do something interesting when we learn about some good ideas (Filber).

The complete code is attached below

export const calculateHashIdle = async (chunks: Array<chunksType>, hashProgress: any) => { return new Promise((resolve) => { const spark = new sparkMD5.ArrayBuffer() let count = 0 const appendToSpark =  async (file: any) => { return new Promise((resolve): void => { const reader = new FileReader() reader.readAsArrayBuffer(file) reader.onload = (e) => { Spark.append (e.target.result) resolve()}})} const workLoop = async (deadline) => {// timeRemaining the remaining time of the current frame while (count < chunks.length && deadline. TimeRemaining () > 1) {// Free time, AppendToSpark (chunks[count].file) count++ if (count < chunks.length) {// Progress bar hashprogress.value = Number(((100 * count)/chunks.length).tofixed (2))} else {// The progress bar of the small task is set to 100 hashprogress.value = 100 resolve(spark.end()) } } window.requestIdleCallback(workLoop) } window.requestIdleCallback(workLoop) }) }Copy the code

Supplementary notes:

  1. deadlineThere are two parameters
  • TimeRemaining (): How much time is left in the current frame
  • DidTimeout: indicates whether to time out
  1. requestIdleCallbackThe defects of

requestIdleCallback is called only 20 times per second – Chrome on my 6×2 core Linux machine, It’s not really useful for UI work. – the from Releasing Suspense

RequestIdleCallback’s FPS is only 20, while the page’s FPS is 60 (16.7s per frame), which is far below the page fluency requirement!