daledesilva / obsidian_ink

Other
417 stars 10 forks source link

Solving the performance problem #13

Open Azeirah opened 6 months ago

Azeirah commented 6 months ago

Hey @daledesilva, in a impulsively opened issue I said I'd investigate the performance issue. I took a look at the tldraw approach to rendering and proposed a technique to greatly increase performance of adding new strokes to the tldraw canvas.

https://github.com/tldraw/tldraw/issues/3346

I hope it'll be implemented since it will greatly improve the user experience for many people and you won't have to move away from TLDraw!

:)

daledesilva commented 6 months ago

That's really interesting @Azeirah. I look forward to seeing their response. I might also experiment with this myself, as I'm sure two tldraw instances can be run transparently over each other. I'm already managing the shapes manually anyway so it wouldn't be hard at all to pass shapes between them.

As you've pointed out, panning and zooming will be a more difficult problem. Which reminds me of a solution I was considering previously but shelved for now. The idea was that as the user finished writing each line, I recognised that and rendered and replaced each line as a png. If the user ever clicked back on the line to select a word or something I could detect the proximity and replace it with the original SVG elements.

I felt that was getting so complex, though, that it would be better to transfer of tldraw. however, adapting that to your idea, perhaps when the view starts panning or zooming, I could dynamically render all shapes as one png to make the pan/zoom more fluid - When to do that will be tricky as there's probably a slight lag in svg to png creation. But it seems an easy enough version of it to try.

On another note, I expect that the drawing functionality (which is in the plugin but turned off by default) will likely stay tldraw as they benefit a lot from tldraws infinite canvas features. The handwriting sections, however, don't need 99% of what tldraw offers, so even if performance improves a bit, it may still be worth switching to canvas2D - but that's yet to be decided.

At any rate, I'm probably going to push that conversion back but I've realised it's not as important as I was thinking. The performance issues are largely an issue with safari's web kit engine, and while I'm sure other slower devices and engines have limits too, I've been accidentally forgetting that web kit isn't what everyone (or even most?) are using. So I'm going to do a couple of things first up:

  1. Add the number of strokes allowed to be visible at one time as an option in the settings, so if you're not on an ipad and your device can handle more strokes, you can dial it up.
  2. Consider putting a height limit on how long handwriting sections can be. Giving it a max height of approximately an A4 piece of paper will help when people print notes as they'll have sections that fit on a page, and it will also help with the max complexity of any tldraw instance. There are some big UX hurdles to solve here though.

I'm really not sure about the second one because one of my long-term goal is to enable users to easily draw words around and have their writing reorganise automatically... that will be very limited if sentences are broken across multiple instances though.

At any rate, so sum up. Thanks for being so interested and involved, and I won't be ditching tldraw any time soon. I'll give some of this stuff a go.

Azeirah commented 6 months ago

I wanted to try running tldraw on the slowest ios device (and only) I have, an iPod touch latest gen. The issue is that safari doesn't even render tldraw :(

So I couldn't test performance on it with my solution.

Given my experience with this solution, if tldraw happens to integrate it I know it should be ridiculously fast on any device that can handle drawing to a clean canvas quickly, which is 100% of the devices you are targeting.

I am fairly certain that if this can be implemented in tldraw core, the performance issues for drawing are 100% solved.

Concerning TLDraw's inner implementation, I think the panning and zooming will be handled automatically when the primary canvas is "cloned" (with zoom and pan settings) and the prototypes are drawn in that cloned canvas. I don't think I'll be looking into implementing this myself in TLDraw, but I'm happy to collaborate with Steve Ruiz if he wants my help.

I offered my advice a while back on Twitter to him before, but I don't think I sold my experience well enough to him 😅