-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Move JS Processing to background thread or allow creation of other WebWorkers/Threads #85
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
Comments
Yeah, I'm pretty sure ReactNative does something along those lines at the moment. Even if JS is in its own thread, I still think that having something like a WebWorker would be very useful feature to have. |
+1 I made a comment about this on the Q&A blog post and didn't get a respond. I think this is important to, especially when animation or long background task comes into play. I hope other upvotes this feature. It very important for performance. |
+1 |
My reply was originally posted on the forums but I'm reposting it here is well: This is really a tough engineering problem to solve as there is no silver bullet here. For example we can introduce WebWorkers but they do have their flaws as well. There is this new re-thinking of WebWorkers in the web space - SharedWorker that tries to solve some of the limitations there. There are other concept like immutable data structures that are slowly gaining momentum. I also want to mention that React Native solution has its own flaws. Being always on a separate thread means that you will constantly have to marshall data (in their case serializing/deserializing JSON) between the JS thread and the UI thread. This might be beneficial for compute intensive JavaScript but in the general case the price you pay is significantly higher compared to doing it in the UI thread. In order for us to provide the right solution we need your use cases. What is your particular scenario that you need to perform compute intensive JavaScript operations? Having more use cases on the table will help us drive this forward. |
Persoanlly, more I'm a fan of the code running in the UI thread by default. I just think that having the option to run things in a worker would be a useful feature to have for projects that would need a separate thread for heavy computations and what not. But even more so, it'd be nice if we had an abstraction that would let us write something like and Android Service which would let our JS code run even when it's not part of the UI of an app. |
My top case isn't even necessarily compute intensive, but that I have a
background operation that isn't tied to an Android activity but still
needs to run. Maybe I have a messaging app that receives pushes from a
server, a location tracker that performs activities based on where the
device is, etc. In Android, the only way to reliably run code separate
from the visible UI is in a service. It'd be nice if Nativescript could
encapsulate that idea somehow into some cross-platform concept,
something like a headless block of code with a lifecycle and the ability
to communicate with other blocks. Not familiar with WebWorkers but
perhaps their semantics could be adopted and translated to Android
services, whatever the IOS equivalent is, etc.
|
+1 to what @ndarilek is saying. I think that ServiceWorker is a better abstraction than WebWorkers for this case, though. Since WebWorkers are more like a separate thread and must be started by the UI, where as a ServiceWorker can run even when a website isn't even opened. |
Sometimes you don't get a preference as to whether or not a long-running
task can execute on the UI thread. As an Android user who relies on
accessibility, I can tell you that actions that block the UI thread can
murder accessibility. Say you're displaying a splash screen to notify a
visual user that a long-running action is taking place. As a blind user,
I don't know that is happening unless I touch the screen to learn of it.
If your long-running action is happening on another thread, then the
accessibility service can get the UI details from the app and report the
screen's message to me. If it is blocking, the service hangs and throws
an ANR, or sometimes crashes out-right. I doubt the Android a11y
developers see this as a bug because developers are urged to run
intensive tasks on another thread, and indeed not doing so is a
StrictMode policy violation. I can almost always spot apps that don't
spin off threads for long-running actions--until recently, one of my
fitness trackers didn't do so, and I usually took several attempts to
launch it because it'd block communicating with the server and I'd touch
the screen too quickly.
All that is to say that moving long-running tasks into another thread
isn't usually a matter of developer preference. It's a platform best
practice whose violation has consequences for some users. That said, I
recognize this is a difficult problem and don't have a solution to
propose. That's probably why we don't see lots of these types of
scripting environments on mobile platforms years after they've surfaced. :)
|
This comment was marked as abuse.
This comment was marked as abuse.
Hi everyone, I looked at the documentation (perhaps I did it wrong) and saw nothing about multi-threading too. This thread is actually quite new so I was simply wondering the status of this request? Thanks a lot. Can't wait to see all NativeScript possibilities. Regards. |
Hi @VinceOPS, this issues is still not in active development. We treat it with high priority and we are evaluating what will be the best strategy here based on all the feedback. Can you please share your scenario that requires multithreading. Thanks! |
Hi @valentinstoychev. Understood! The typical scenario would be any common background task like fetching some data from a webservice (which could eventually timeout) or a database. Inserting group of rows in a database, too. Generating a .CSV file (sent, later, by email) with few hundred or thousands or entries... I hope it helps. Thanks! Regards. |
Thanks @VinceOPS - this helps a lot! |
Thing here is that React's JS computations is heavy, this is why they went native and on separate thread by default. Here, for {N} is not real need to be by default on separate thread, but having ability to run system thread with JS handling would be good since without it smooth UI is hard thing (see how hard it's for mobile web to live on one thread). |
Anything new on this one? |
@cime Bitmap decoding is already on a background thread if you are using our http/fetch module to download a picture. For 1.4.0 we will try to move all image decoding operations in the background no matter where the picture is loaded from. |
Sorry, I wasn't clear. I mean custom bitmap processing like rotations etc.
|
A few use cases I need to cover and would ideally (or necessarily) handle off the UI thread. Web socket communication with a server to update a local cache of the database the user needs access to, which would be updated in diffs (on child added/changed/removed events), then scheduling cleanup operations to trim or update the oldest accessed items in the local cache. The UI thread would only interact the local cache in this scenario. Custom image/file processing, such as cropping a photo before uploading, or reading image EXIF data. Background service to sip GPS data over time while the app is not open and send that data to the server, potentially executing callbacks based on proximity to geo-fencing data. |
Think the others have hit most of my pain points ready, so I'll add a +1 for image processing/manipulation as a function that can be intensive and tends to be a bit of a blocker. +1 Database processing. All have aspects that get intense and cause blocking |
To me, network and database access would be the items that are the most likely to have an impact on the UI thread (thus causing hiccups when doing intensive processes) |
Could one hypothetically just use the Java Thread class? Or would that cause issues since v8 runs javascript single threaded? |
👍 |
👍 on this. Even though the response to network calls is async, the work involved in issuing the requests is enough to make our UI too slow to use, particularly on Android, where doing anything in an onNavigatedTo callback blocks the navigation, which isn't a problem on iOS so much. |
Got it, so I wonder if it would make sense to close this issue with that
explanation? I keep reading this thread expecting some amazing solution
that would let me spin off JS code in a background thread/worker while
not slowing down the UI. If that isn't going to happen then that's an
acceptable answer. Unfortunately a lot of the apps I develop do a fair
amount of background processing, and if I can't do those entirely in
NativeScript then that's a good thing to know. :)
Thanks.
|
@atanasovg I partially agree with you. But i think if we go to force users write native code, there must be a better solution than using XCode/Android studio and making separate projects. May be have a |
Thanks for your feedback. I don't find your comment offensive and I don't think any of the team find it either. I like your approach and I appreciate it. Now, let's go back to the issue. Currently, we don't know how to provide a good threading model in {N}. And I want to emphasize on "good". All we know is that we won't make it right from the first try. Our team discussed internally this issue for a long time and indeed it is hard one. One of my main reasons to ask for use cases is that I have some concrete ideas how this feature can be implemented. I cannot get any meaningful information from other implementations because there no implementations. My main concerns is how modules and plugins have to work. For example, what are your expectations when you These are only part of the questions our team has discussed. So far, it seems much easier to stick with some event-driven approach, similar to Node.js, which perfect for I/O scenarios and not so suitable for parallel computations. We know we are going to make some trade-offs and asking for your scenarios we collect data so we can present you some initial approach/implementation which we will then start to discuss with you guys. |
Got it. I think this list of questions is more helpful because, as a
Having said all that, I'm not necessarily advocating this as the way to I hope that helps. Thanks for putting it in terms of questions/specific |
@slavchev I think even allowing simplified threads with having access to only native classes will be a big 👍 for {N}.
I think even with having these limitations will handle most (if not all) the situations above |
This comment was marked as abuse.
This comment was marked as abuse.
@NathanaelA So, to rephrase what you are saying - because {N} does not allow you to run JS on another thread you execute CPU intensive code on the main thread, which freezes the UI. Well, every GUI platform strongly advises against running blocking code on the main UI thread. Btw, would you share what kind of work you are actually performing in your screenshots? I'd love to check whether this is a common application scenario. Now, let's accept for a moment that background JS processing is a currently not available feature in {N}. And the {N} team may not engage with any particular time frame for implementing it. What are our options then to perform CPU-intensive logic?
Obviously, we'll want to go for the second one. Imagine we have asynchronous plugins for most of the common use cases - like the HTTP cross-platform module or the push notifications plugin. If this is true then the pure application developer would be good to go by just installing the needed plugins. With that said - @NathanaelA, @PeterStaev and every plugin author, we need your help, guys, to isolate these common scenarios and to create plugins to cover them. I know going native is probably not the most effective approach for plugin authors but it is currently the only available (and viable) one. And I can only assure you that we will definitely have your feedback in mind when prioritizing our backlog. Btw, @NathanaelA, what about your workaround with utilizing a WebView and using its workers support? |
This comment was marked as abuse.
This comment was marked as abuse.
Love the discussions :) What I'd like to do is using the native code to do the background processing ex: asynctask in android, and like @enchev said it can be done like the tns notification plugin, my problem is, this process is not very developer friendly, so somehow there's an easy way (maybe like the recent activity android that can be enhanced) But then again, I dont know very much :) |
@atanasovg it is not a good practice to extract everything to a plugin. For example the workflow that @NathanaelA gave above. This is a specific use case for his app. I dont see any benefit in extracting this as a plugin for the masses. Not to mention that i might have some proprietary logic which i do not want to expose as a plugin for apparent reasons ;) like @x4080 says above - it is not very developer friendly to make every portion of a more resource intensive task in native development environment (android studio or XCode). If I have to open XCode for 50% of the code I have what benefit i have in using {N} instead of just going pure native? |
@PeterStaev I bet having the SQLite plugin do its work on a background thread would most probably solve @NathanaelA's issues. No need to extract the application logic to another thread. I still believe that there exists a set of plugins that would solve, say 90%, of the application scenarios. And instead of arguing whether this is true or false let's try to compile this list of plugins and discuss case by case. So far I've heard a scenario related to SQLite data manipulation - well, it is obvious that this is a general purpose plugin that does not have appropriate code and is the ideal candidate for offloading its work to another thread. @PeterStaev 'n all, please fill the following list with scenarios where you'd need a background thread:
|
@atanasovg i already listed my case above but here it is again:
|
Personally I would just like a way to "process" something off somewhere else and whatever is handing that be a core part of {N} so I know it's fully tested and rock-solid. I'd be less optimistic about this being done generically by a plugin author who might disappear in 2 months. |
Yes and plugins is too big for small services that needs async like async .. Task :) |
This comment was marked as abuse.
This comment was marked as abuse.
One scenario for me would be doing data transformations, i.e. iterating on datasets fetched from my backend. A workaround is to do the transformations server-side, but it seems a bit counter intuitive, as the transformations will often be specific to a given view. A concrete example where background processing made a huge difference in my native code: I am displaying a map, and fetching points of interests inside the area currently displayed. After the POIs are fetched, I need to calculate the display location for each of them, and group them if they are too close to each other. Doing this on the UI thread, will make the map unresponsive and sluggish. |
This comment was marked as abuse.
This comment was marked as abuse.
+1 |
Any plans for blog to develop native plugin for background threading using Android studio and xcode ? Or maybe NS guys can describe how they develop the tns plugin? It will be great time saving Thanks |
Hey everyone - In order to explain better the current state of the threading model we wrote a blog post. It also outlines what we are planning for the future and how you can use background threads now. http://developer.telerik.com/featured/benefits-single-threading-model-nativescript/ |
nice blog, so the next JavaScript background thread will be able to pass variable from the main JavaScript? and in iOS will it use wkwebview for more performance? |
+1 |
I'm closing this issue, lets use the other ones for the current state - We would love to continue the discussion there on the current thinking! |
Use density for clip-path calculations
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
From what I understand everything runs on the primary thread. So this is a feature request -- but if done possible sooner would eliminate any later incompatibilities. Having the main thread run the interface and JS runtimes means that hiccups can and will occur frequently. Either the design where the interface is run on its own thread; and the engine is on its own or the ability to start webworks will eliminate these types of issues where you need to do any long running calculations.
Please vote for this feature in our ideas portal.
The text was updated successfully, but these errors were encountered: