pqina / filepond

🌊 A flexible and fun JavaScript file upload library
https://pqina.nl/filepond
MIT License
15.05k stars 821 forks source link

Tick function active when not using FilePond #243

Open lukey78 opened 5 years ago

lukey78 commented 5 years ago

Hi,

I'm including filepond in a react component and render a page where the component is not used. Thus, when measuring performance of the page in Chrome, I get this output:

image

Apparently, Filepond does something in the background even when it's not instantiated (only loaded in the webpacked js file). This is not really affecting performance, but I wonder if this is on purpose and maybe how to disable it, so that Filepond only becomes "active" if a filepond instance is rendered somewhere on the page.

Thanks! Jens

rikschennink commented 5 years ago

Hi! That's the function of FilePond's internal draw loop. It should ideally be canceled when no FilePond instance is active but currently, it simply runs and does nothing.

saravmajestic commented 5 years ago

Hello.. thanks for this nice library. We have been using this for a while and now we are facing some performance issues. This tick function runs always in the page, so in Chrome browser, our page gets throttled (https://developers.google.com/web/updates/2017/03/background_tabs) and after a while (like in 5 mins), the page is dead and when the user comes back to our page tab, the page reloads. This makes our app unstable. Is it possible to make the tick function called only when uploads are happening? Or a way to stop and start when needed? Thanks in advance.

rikschennink commented 5 years ago

@saravmajestic The requestAnimationFrame loop is only active when the page is visible to the user. When the tab is hidden FilePond uses setTimeout instead (since 4.4.5), otherwise it wouldn't be able to handle file queue's. When FilePond is not active the loop takes nanoseconds to run which while not ideal also shouldn't affect anything.

I seriously doubt the freezing of the page is caused by FilePond.

saravmajestic commented 5 years ago

@rikschennink Thanks for the quick reply. I have been using v4.4.0. I will check with the latest version and will update

saravmajestic commented 5 years ago

@rikschennink our app is quite heavy in real time updates for user. This freezing happens because of background tab throttling by chrome based on the budgets allocated for the tab. This budget will be used for each timer and decreases on continuous usage.

In our case, we have filepond in chat widget and even before initializing file pond instance (i.e on filepond code is loaded), the tick function is running. It would be more useful if this tick runs only when at least one instance is initialized. Is there any way to stop the tick when no instances are there?

rikschennink commented 5 years ago

@saravmajestic once the script loads the draw loop is started. This is basically what this issue is for so the only way to prevent this right now is to not load the script. But again, the loop takes literal nanoseconds to run so it shouldn't be a problem. You can time it yourself using developer tools performance tab.

AltiumWilliam commented 4 years ago

Hi. I have same problem. In clients with good hardware this issue is not affected anything and no one feel anything, but in clients with weak hardware it cause CPU usage up to 20%. I can't load it when I needed because I load this plugin with webpack and it loads filepond on it's startup. the only way I can fix it is define a global variable (window.hasFilepond) and on vue component beforeMount method I set it to true and On beforeDestroy method set it to False, and in filepond.js I check this global variable, if it set to true then I allow Normal Tick function, otherwise change the Tick Interval to 2 seconds.

rikschennink commented 4 years ago

@AltiumWilliam The draw loop is used to detect changes in layout and animate the items and drop area accordingly. Maybe the loop can be auto-paused when FilePond is inactive, the trick is to detect changes, maybe we could use ResizeObserver for this.

I'll see if I can take another look at this next week.

AltiumWilliam commented 4 years ago

@AltiumWilliam The draw loop is used to detect changes in layout and animate the items and drop area accordingly. Maybe the loop can be auto-paused when FilePond is inactive, the trick is to detect changes, maybe we could use ResizeObserver for this.

I'll see if I can take another look at this next week.

Thanks for quick reply. I'll be happy to see it. You uploader is amazing and I didn't like to switch to another plugin. I see this issue lase week when one of my clients say his computer hang when my program running, when I see his computer, I saw CPU usage is 100% and when program close it reduce to 0%! My program has another performance problems but one the problems was this tick! By increasing tick interval and remove other interval calls, the problem completely solved. I didn't see this problem because my computer hardware is good, but that client with Core2 CPU has problem. Again thank you for your reply, I'll waiting for bug fix.

rikschennink commented 4 years ago

@AltiumWilliam It shouldn't really impact performance that much, it will only run the function each frame, but the function doesn't do anything as long as FilePond is in idle mode (all animations are in rest state). Still, it would be nice of the tick function wouldn't be called at all in that situation.

// edit This issue is still on my high prio list, not sure how to approach it yet.

mtpilarek commented 3 years ago

@rikschennink We've been using your library for a while and our users started reporting increased CPU usage on our React App up to 10% while app was idle. After investigating I have discovered this issue and as it turns out after removing your library cpu usage returned to 0 in idle app. So I can confirm this issue does have a performance impact and unless it is fixed we are forced to stop using this library, which is quite sad, because it's a very good one...

DavidHenri008 commented 1 year ago

@rikschennink We are using FilePond and it is really nice, thanks. I was investigating performance issues and I came across the always-called tick function. It seems to take a lot of time for me even if there is no FilePond React component used in my current view.

Here is a screenshot of Chrome performance: image

Any idea to improve or debug my situation? Thanks.

rikschennink commented 1 year ago

@DavidHenri008 While it would be nice if the tick loop was not active it currently how FilePond manages layout, I'm planning to look into it in v5.

That said, it should not take up that much time, is this a cumulative view over an x amount of frames?

This is the tick task, it takes 67 nano seconds.

Screenshot 2022-11-07 at 09 05 21
shaylevi2 commented 8 months ago

I'm surprised this is not a bigger deal, this is actually quite terrible. Saying "but each frame takes a few nanoseconds" while the CPU usage spikes to 20% is also baffling. Definitely should be considered a bug and there should be a warning before using this library as this is the case for the last 5 years.

edotassi commented 3 months ago

This is a very serious problem. I noticed that in a large Angular app the CPU remains at 20% even without doing anything. Removing filepond returns the CPU to 0%. I had to replace Filepond with an ad hoc implementation.

The features that Filepond includes do not justify wasting CPU.

With Filepond:

Screenshot 2024-05-31 alle 19 30 15

without Filepond:

Screenshot 2024-05-31 alle 19 30 24
rikschennink commented 3 months ago

@edotassi v5 fixes this, the internal draw loop will halt if FilePond is not visible.

In the meantime maybe unload FilePond if it's not on the page?

edotassi commented 3 months ago

@rikschennink do you have an example of how to disable it? thanks

rikschennink commented 2 months ago

@edotassi You can use the destroy method to unload FilePond when it's not in use.

CODEheures commented 3 weeks ago

I have the same problem (I use filepond by ngx-filepond module for Angular V14) I notice that it was not due to filepond because it was was appeared when I use requestAnimationFrame in a component (in my case to adjust a fixed position top/left depending to other element) To avoid this, I use the runOutsideAngular of NgZone on the first RequestAnimationFrame call (and all component properties changes in callback are processed in a zone.run() to keep a fluid effect)