Most Performant Method for Bulk Inserts

This isn't so much a problem/issue, I'm just looking to squeeze as much performance out of this as possible and wondering if you guys had any more pointers.

In the application I'm currently working on, we sometimes load really big data sets (e.g. 5k+ billbords, 10k+ geometries and ellipses, 2k+ polygons, etc). Currently, Cesium handles it pretty well but I'm curious if there's anything else I can do.

Currently for each of these things I would loop through an array of data representing each of the items (an array of objects) and create an object structure that would be used to create an entity. That object would be passed into an entityCollection.add() call that would add it to the globe, I would take the resultant entity and cache it for quick access.

To keep performance high, I've already set requestRenderMode to true and am manually executing requestRender() where necessary. I've set a lower targetFrameRate (60fps just isn't necessary for us). I'm also now tinkering with suspendEvents/resumeEvents to disable the individual events while inserting bulk data.

Is there anything else I can do? Is there a more efficient way of loading bulk data aside from adding each entity in a for loop? When loading some of the large sets (current example is 10k billboards), the globe locks up while loading the data. Is there something I could do that would allow it maintain responsiveness during loading?

These items (for the most part) aren't time dynamic. They are mostly a static rendering. I know using a point would be more efficient than a billboard but I need the icons on the individual assets.

Thanks in advance

I think the way requestRenderMode is advertised is a bit misleading. What it does is prevent CesiumJS from re-rendering every frame, so it uses less CPU/GPU when idle. But it won’t make the application run in any faster I don’t think.

In any case, there are two general solutions to the globe locking up while loading data: split the loading tasks over multiple frames, and move tasks to background threads via web workers.

Cesium’s Entity API creates everything asynchronously be default, putting as much work on web workers as possible (which is why they don’t show up immediately when you add them). With that said, I believe there is still a lot that happens on the main thread. This PR does the first approach (split over multiple frames) to prevent loading large KML from freezing the application:

Although it was never merged because of a lack of consensus on how this is managed. I believe a very similar thing could be done for adding entities so they don’t freeze up the application. I think it isn’t a priority for the Cesium team since a lot of the focus now is on 3D Tiles solving the problem of efficiently getting a lot of data in the browser, but this would be a welcome contribution if this is something you can work on!

Omar,

Thanks for all the info. I wasn't aware that everything in the Entity API was asynchronous. After reading your post, I started looking through our code a bit more and identified the chunk of code that was our bottleneck. I did what you suggested and moved the processing of this data to another process and wow, it made a huge difference.

Our application is in Electron. Electron supports Web Workers but, in turning on "nodeIntegrationInWorkers" to allow for importing modules and such in the web worker, Cesium began throwing errors in the console. For now, since we use Electron, we've reverted to using node's child_process.fork to execute the processes instead.

Once again, thank you for the info.

Awesome, I’m glad to hear it made such a huge difference! Would you mind bumping that PR to say which chunk of code you edited (is it the same/similar to the one in the PR?) I’m sure it’ll help a lot of people running in the same issue, and it might get merged officially into the library one day.