draw icon indicating copy to clipboard operation
draw copied to clipboard

Sketches after ~100 edits take a long time to load and sometimes don't even load!

Open JohnMcLear opened this issue 12 years ago • 11 comments

Really weird one, can be replicated by stress testing

JohnMcLear avatar May 08 '13 15:05 JohnMcLear

Also I think if an edit is received prior to all sketches being loaded then it wont display previous sketches.

JohnMcLear avatar May 08 '13 16:05 JohnMcLear

It might make sense to "stream" these in

JohnMcLear avatar May 08 '13 16:05 JohnMcLear

I think the 100+ edits thing might be a server limitation. My 1250+ edit stress test that crashed loads just fine after restarting the server and quickly from a localhost connection. Are you testing this against localhost or http://draw.etherpad.org?

Also I think if an edit is received prior to all sketches being loaded then it wont display previous sketches. It might make sense to "stream" these in

That's a good point.

tranek avatar May 08 '13 21:05 tranek

One thing that I noticed from the 70 edit test, I couldn't load the sketch until all of those 70 generated sockets timed out. (I did a 70 10 and killed the test after the edits were written to database from the server debug output before the next 70 came in). When a real person closes their browser, they don't time out and instead close the connection (timeouts still can happen from lost connections of course). So I think this is more a problem with timeouts.

Try loading your 100+ edits after all connections timeout and see if it's still a slow load/doesn't load at all.

tranek avatar May 08 '13 21:05 tranek

localhost

JohnMcLear avatar May 08 '13 22:05 JohnMcLear

So here are my thoughts on this.

opacity doesn't seem to affect performance despite what I first thought.. i suck! rendering old edits down to a png could work, we'd have to provide an option to ungroup them though which would mean just drawing the objects onto the screen I don't think the TCP overhead of the edits is so large, 200 edits from hand test is: 20kb or so, network here is cheep, from stress test 200 is 90Kb so still small

So what's the plan, Render previous 50 to raster and show that then onRasterHover render the objects onto the canvas and remove the raster?

There has to be a way we can have 100 items on the canvas without any latency.. I think the issue is here is more that our objects are relatively complex due to number of points (each 100ms) - normal edits don't seem to cause this problem. I tested this by manually mkaing a bunch of edits (some that overlayed) and I didn't notice any bad latency..

Is it possible to group edits? We can't merge them really cause then we lose fidelity..

So yea, TLDR; tests are pretty rough but a good way of handling that case.

I would expect the logic looks something like this

  • Client sends Edits
  • Server realizes some edits are over 50 edits old so goes about flattening edits with age 0-50 to a single image
  • Server Pushes flattened image to clients and tells client to not show items 0-50
  • Client hovers(this will not work with mobile devices and tablets) over items 0-50, if the client edits any of the objects in 0-50 the server modifies the image and pushes it back out to other clients.

Because bandwidth is cheep the server never actually needs to push anything other than images around, theoretically we could make the client do the heavy lifting here but im not sure how computationally heavy it would be to recreate images should one(or many) be edited. Also race conditions could prove to be a problem. I guess getting the client to create the actual raster is the solution for this...

It basically needs a week or so work to resolve it cleanly imho. A clean resolve would mean that the ed_stress tool can push any many edits as it wants to the server and the client would periodically receive a flattened image and use that instead of many objects on the canvas. Should the edits 0-950 exist on a canvas (ie a big drawing) then we should serve 0-900 as a single raster..

Another considering and probably a requirement is that we carve the canvas up into 100x100 pixels, doing this would mean that should the user hover over the 0-900 single raster it doesn't have to draw 900 objects onto the page at this point, however the issue here is that an object might span over many points in a grid IE start at pos(0,0) but end up in grid(10,1), we might have to figure out how to deal with that..

This is my proposal anyway, imho it will introduce more bugs than fix actual use cases we are encountering right now.. The problem is that if we add new features and this remains as an elephant in the room.... It's not an easy problem to solve, there might be an algo we can use somewhere on the web should we do some deep digging!

I'm really surprised paperjs doesn't cover this edge case, perhaps this is something we can raise with them to see if they have a suggestion?

JohnMcLear avatar Jul 04 '13 16:07 JohnMcLear

I've been putting off reading this because is so long...

I'm really surprised paperjs doesn't cover this edge case, perhaps this is something we can raise with them to see if they have a suggestion?

What edge case are you referring to? A lot of items on the canvas slowing it down?

tranek avatar Jul 09 '13 01:07 tranek

Yea sorry about the length, I think it's important we get this right first time as it really affects how the app performs.

Yea i'm talking about paperJS not having a way to "flattern" a canvas to a static state then the ability to "unflattern" on demand

JohnMcLear avatar Jul 09 '13 11:07 JohnMcLear

Node.js/etherpad/github newbie here so take my advice with a grain of salt. I noticed the client slow down after manually playing around for a while.

The thing complicating the flattening of the drawing is the selection tool. If we remove that functionality, and replace it with an eraser tool, a la MSPaint, then we have something much simpler to model. Any point in the timeline can be represented by a bitmap + a list of drawing/erasing events, just like any point in an etherpad can be represented by a text string + a list of insertion/deletion events.

DanBeard avatar Aug 02 '13 16:08 DanBeard

If we remove that functionality, and replace it with an eraser tool, a la MSPaint, then we have something much simpler to model.

No eraser tool for vector graphics (has to be done with boolean operations). Paper.js doesn't support edits to raster images (bitmaps) so we couldn't erase or add directly on the bitmap.

The most straightforward way of flattening would be to render to a bitmap and save a .svg image on the server as a copy that can be swapped in on demand.

tranek avatar Aug 03 '13 04:08 tranek

Could we help the draw speed by simplifying the paths? http://paperjs.org/reference/path/#simplify That also seems like it might be able to help server-side with storage and bandwidth, but I'm not sure how we could make use of that server-side.

DanBeard avatar Sep 19 '13 22:09 DanBeard