I don't know if folks are interested in this kind of niche technical deep dive here, no worries if not. But I figured I would share in case anyone is, like, really into React development, or...
I don't know if folks are interested in this kind of niche technical deep dive here, no worries if not. But I figured I would share in case anyone is, like, really into React development, or something!
It's https://loreweaver.no, but I'm still getting it functional before I fully open source it. Soon (weeks?). I also need to pick a different name because I'm the fifth loreweaver, unfortunately.
It's https://loreweaver.no, but I'm still getting it functional before I fully open source it. Soon (weeks?).
I also need to pick a different name because I'm the fifth loreweaver, unfortunately.
If anything the second one seemed more laggy than the first. idk... maybe it is different on Apple Silicon... My browser shuddered and froze for a moment there--YOU'RE PLAYING WITH PEOPLE'S TABS!...
But, hear me out, it’s really fast:
If anything the second one seemed more laggy than the first. idk... maybe it is different on Apple Silicon...
My browser shuddered and froze for a moment there--YOU'RE PLAYING WITH PEOPLE'S LIVES TABS! The tabs are on the line. The tabs are online...
Perhaps we could stop putting things in the Shadow DOM??! just an idea!
HTML is a pretty good format for documents. The browser is already pretty complicated even just with HTML5 and CSS3--we don't need to build another browser inside the browser!
Oh, huh. I guess I should test this on Safari — on both Chrome and Firefox (including on my Android) there is no lag at all for me on the second editor. There's no Shadow DOM on this page, so I'm...
Oh, huh. I guess I should test this on Safari — on both Chrome and Firefox (including on my Android) there is no lag at all for me on the second editor.
There's no Shadow DOM on this page, so I'm not exactly sure what you're referring to there!
It's basically not possible for the second editor to be slower — it's doing like 1/100th the work. It is possible that your browser is struggling with rendering the entire contents of Moby Dick twice, though, which I didn't really think about. Maybe when you blur the editors I should actually truncate the document, in addition to making it static
That page still seems a bit laggy and it interferes with native keyboard editing on mobile (like character, word selection and predictive text) I only tried it on Firefox and Fennec tbh I have...
That page still seems a bit laggy and it interferes with native keyboard editing on mobile (like character, word selection and predictive text)
I only tried it on Firefox and Fennec
tbh I have little patience for input lag and weird behaviors compared to native textboxes (like the ones Tildes uses). I've never had a good experience with something that tries to.... I don't even know what you're trying to do?? Like what is the benefit of this type of interface that takes control over the normal web components via JavaScript?
Sorry, I was mixing up responses. Just making sure I understand, you're using Firefox on an Apple laptop/desktop? Or on iOS? Right, there's no point in using this for a plain textarea. The library...
My guess is that this is an Android keyboard thing — Gboard, in my experience, works fine with React ProseMirror, but Swype and Samsung keyboard have issues. Maybe this will be my push to try to actually resolve these, I think it's gonna be a pain haha. Sorry, I was mixing up responses. Just making sure I understand, you're using Firefox on an Apple laptop/desktop? Or on iOS?
Right, there's no point in using this for a plain textarea. The library is designed (and used) for complex rich text editors, like dskrpt.de, which uses it for their textbook editor (with inline quizzes and other interactive elements) and Moment which uses it for its rich markdown editor, including rather elaborate interactive code blocks. Web browsers don't have any native components for this (ultimately we're using contenteditable, but contenteditable on its own is not usable as a rich text editor).
Even for just a simpler text editor, though, it's not necessarily as simple as "just use native web components." I definitely underestimated both the number of mobile Android users reading this and the variety of mobile Android experiences of React ProseMirror (always a mistake, web on Android is nothing if not chaos), but React ProseMirror is much faster than the native contenteditable element on desktop Firefox.
Anyway, sorry the demos frustrated you, that obviously wasn't the goal (well, it was a little bit the goal for the first editor)! I
I read this comment first before reading your blog. There is definitely still a rendering issue somewhere. I loaded the second editor before the first one (to avoid the scenario you mention about...
I read this comment first before reading your blog. There is definitely still a rendering issue somewhere. I loaded the second editor before the first one (to avoid the scenario you mention about having multiple moby dicks).
Simply pressing enter on each editor (old and new) has very noticible input lag (feels like close to half a second before the enter is inserted). Doing this on android (firefox).
I don't use either library and have no use for this, but given the effort you went through, I assume you would want to know and have another look.
Edit: Even stranger. Typing any letter causes that letter "popup" (default android keyboard) to remain in its popup state. So I press 'g', which on an android keyboard causes 'g' to briefly flash as a popup letter in the keyboard, but on your editor, the key stays forever. Very strange stuff. Have not seen this anywhere else before
I think this is ultimately due to some Android devices just having trouble with rendering this many DOM elements in a contenteditable. Weirdly not an issue with Firefox on my Fairphone 5 at all —...
I think this is ultimately due to some Android devices just having trouble with rendering this many DOM elements in a contenteditable. Weirdly not an issue with Firefox on my Fairphone 5 at all — even the first editor is surprisingly fast for me haha.
I make this mistake a lot, unfortunately, of testing while I'm writing on my laptop and forgetting that phone have completely different performance characteristics.
I think I should have anticipated that some browsers and some mobile devices wouldn't be able to handle a contenteditable with an entire novel in it. Sorry I crashed your browser :/ I'll truncate...
I think I should have anticipated that some browsers and some mobile devices wouldn't be able to handle a contenteditable with an entire novel in it. Sorry I crashed your browser :/ I'll truncate the demo text and see if the point still gets across.
I'm not sure if you saw the last section, but on (desktop) Firefox this is actually not true! React ProseMirror is much faster than Firefox's native contenteditable implementation, even without a...
I'm not sure if you saw the last section, but on (desktop) Firefox this is actually not true! React ProseMirror is much faster than Firefox's native contenteditable implementation, even without a ProseMirror editor set up at all
That's interesting, a native implementation has to do less work, with less overhead, and with compiled code. Implies that Firefox got something pretty badly wrong.
That's interesting, a native implementation has to do less work, with less overhead, and with compiled code. Implies that Firefox got something pretty badly wrong.
Ok, thanks everyone for the feedback! I have: Added some notes/caveats about issues that may crop up with the demo editors Configured the demo editors to truncate the document when unfocused, so...
Ok, thanks everyone for the feedback! I have:
Added some notes/caveats about issues that may crop up with the demo editors
Configured the demo editors to truncate the document when unfocused, so that your browser isn’t rendering Moby Dick twice.
Also discovered some interesting things:
I didn't really account for how much faster React's production build is than the development build. I basically can't type fast enough on my phone (Android or iPhone) to even notice the lag on the unmemoized editor
Firefox on macOS is just crazy slow for large documents, basically no matter what. Just putting Moby Dick in a plain contenteditable is slow, putting it in the unmemoized editor is slow, and putting it in the memoized editor is best but still pretty slow
Safari on macOS is crazy fast haha. I couldn't discern any lag at all on the unmemoized editor when I was testing on my m4 Mac Mini
Amazing write-up. I'm excited to go back and read it in depth. I noticed on Mac (M2 Max) Safari, they feel equally fast yet slightly stuttery to me. Like very slightly stuttery to the point most...
Amazing write-up. I'm excited to go back and read it in depth. I noticed on Mac (M2 Max) Safari, they feel equally fast yet slightly stuttery to me. Like very slightly stuttery to the point most wouldn't perceive it. I suspect an intentional limitation for battery reasons but that the machine is so fast it doesn't seem slow overall. Mac Chrome, both feel great and better than Safari. iOS Safari I instantly feel that the memoized editor is far better.
An interesting test might be power consumption if it were feasible to measure. Anyway, fantastic post again.
Thank you! And thanks for testing it out a bit, good to have more data points. It's super interesting how variable this can be across different operating systems and browsers.
Thank you! And thanks for testing it out a bit, good to have more data points. It's super interesting how variable this can be across different operating systems and browsers.
Offtopic: On my iphone, with Orion browser, I had no problem with this website. Just moved to mac with Orion browser again, and it took a long time to load the page. And, I can't seem to load the...
Offtopic: On my iphone, with Orion browser, I had no problem with this website. Just moved to mac with Orion browser again, and it took a long time to load the page. And, I can't seem to load the first editor by clicking on it? And, just before that, the "@nytimes/react-prosemirror@0.7.0-next.10" part appears as "@nytimes/[email protected]" and when clicked takes me to a cloudflare error that tells me it is protecting an email address?
That's.. all incredibly odd haha. The website is fronted by Cloudflare, but I am not aware of any email protection settings (maybe it's on by default?), and I'm not personally seeing that even if...
That's.. all incredibly odd haha. The website is fronted by Cloudflare, but I am not aware of any email protection settings (maybe it's on by default?), and I'm not personally seeing that even if I go off of WiFi. Let me poke around and see what I can find...
Update:
Seems like this is indeed enabled by default, and I should be able to turn it off for that string, as well as in general (I already have my own email obfuscation implemented on that site, so I don't have any need for it).
However, the fact that you're seeing that at all is an indication that Cloudflare thinks you might be a bot, which I'm sure is exciting news. That might explain why the site loaded so much more slowly for you on your desktop, as well.
Something is not right when I try it with chrome on Android. Specifically hitting enter caused weird behavior in all examples. In the first one it doesn't work, at the end of a word it does...
Something is not right when I try it with chrome on Android. Specifically hitting enter caused weird behavior in all examples. In the first one it doesn't work, at the end of a word it does duplicate the word.
The last fast example somewhat works but it duplicates one character for each line break.
Edit:
I did some more testing and it seems to be keyboard related. Gboard works okay, Samsung keyboard has its own weird behavior and the keyboard I initially tested with is heliboard.
I am suspect that both the Samsung keyboard and heliboard might do something slightly odd. But now you at least know they cause issues. I honestly have checked with native posemirror, let me do that as well and get back at you.
Edit2:
Prosemirror on their website works fien with heliboard.
Edit3:
Seems like Android (as often is the case) is a bit of a mess. I found some interesting stuff as I was curious.
It looks like prosemirror has a variety of workarounds implemented (this is quite old but seems to be about pretty much this. If I had to guess is that some of those work arounds aren't present in some of the bits you rewrote in react.
We actually need completely different workarounds for Android keyboards, because we use beforeinput events (native ProseMirror does not) and several Android keyboards produce completely broken...
We actually need completely different workarounds for Android keyboards, because we use beforeinput events (native ProseMirror does not) and several Android keyboards produce completely broken beforeinput event sequences on Android Chrome. Slate.js has worled out resolutions to this that we need to take a look at.
On stock latest android and latest firefox, replacements using the Gboard buttons (like "we're" -> "were") take upwards of a full second to insert into the text area on the new version. Typing...
On stock latest android and latest firefox, replacements using the Gboard buttons (like "we're" -> "were") take upwards of a full second to insert into the text area on the new version. Typing seems to be pretty fast, though.
I don't know if folks are interested in this kind of niche technical deep dive here, no worries if not. But I figured I would share in case anyone is, like, really into React development, or something!
This is awesome. I just started a collaborative editing project and really enjoyed this.
Thanks! Glad to hear it. What kind of collaborative editing project are you working on?
It's https://loreweaver.no, but I'm still getting it functional before I fully open source it. Soon (weeks?).
I also need to pick a different name because I'm the fifth loreweaver, unfortunately.
Oh very cool! Shoot me a link when you publish it, I'd love to take a look!
I’m very into Codemirror, but have considered moving towards ProseMirror. Haven’t read the article yet though.
If anything the second one seemed more laggy than the first. idk... maybe it is different on Apple Silicon...
My browser shuddered and froze for a moment there--YOU'RE PLAYING WITH PEOPLE'S
LIVESTABS! The tabs are on the line. The tabs are online...Perhaps we could stop putting things in the Shadow DOM??! just an idea!
HTML is a pretty good format for documents. The browser is already pretty complicated even just with HTML5 and CSS3--we don't need to build another browser inside the browser!
Oh, huh. I guess I should test this on Safari — on both Chrome and Firefox (including on my Android) there is no lag at all for me on the second editor.
There's no Shadow DOM on this page, so I'm not exactly sure what you're referring to there!
Just out of curiosity, do you also see slowness editing the document on https://handlewithcarecollective.github.io/react-prosemirror ? Maybe there's just an issue with my demo editor on the blog post.
It's basically not possible for the second editor to be slower — it's doing like 1/100th the work. It is possible that your browser is struggling with rendering the entire contents of Moby Dick twice, though, which I didn't really think about. Maybe when you blur the editors I should actually truncate the document, in addition to making it static
That page still seems a bit laggy and it interferes with native keyboard editing on mobile (like character, word selection and predictive text)
I only tried it on Firefox and Fennec
tbh I have little patience for input lag and weird behaviors compared to native textboxes (like the ones Tildes uses). I've never had a good experience with something that tries to.... I don't even know what you're trying to do?? Like what is the benefit of this type of interface that takes control over the normal web components via JavaScript?
https://handlewithcare.dev/blog/why_i_rebuilt_prosemirror_view/
okay I get it a bit more... it's a rich text editor like the WordPress live preview mode thing
My guess is that this is an Android keyboard thing — Gboard, in my experience, works fine with React ProseMirror, but Swype and Samsung keyboard have issues. Maybe this will be my push to try to actually resolve these, I think it's gonna be a pain haha.Sorry, I was mixing up responses. Just making sure I understand, you're using Firefox on an Apple laptop/desktop? Or on iOS?Right, there's no point in using this for a plain textarea. The library is designed (and used) for complex rich text editors, like dskrpt.de, which uses it for their textbook editor (with inline quizzes and other interactive elements) and Moment which uses it for its rich markdown editor, including rather elaborate interactive code blocks. Web browsers don't have any native components for this (ultimately we're using contenteditable, but contenteditable on its own is not usable as a rich text editor).
Even for just a simpler text editor, though, it's not necessarily as simple as "just use native web components." I definitely underestimated both the number of mobile Android users reading this and the variety of mobile Android experiences of React ProseMirror (always a mistake, web on Android is nothing if not chaos), but React ProseMirror is much faster than the native contenteditable element on desktop Firefox.
Anyway, sorry the demos frustrated you, that obviously wasn't the goal (well, it was a little bit the goal for the first editor)! I
I read this comment first before reading your blog. There is definitely still a rendering issue somewhere. I loaded the second editor before the first one (to avoid the scenario you mention about having multiple moby dicks).
Simply pressing enter on each editor (old and new) has very noticible input lag (feels like close to half a second before the enter is inserted). Doing this on android (firefox).
I don't use either library and have no use for this, but given the effort you went through, I assume you would want to know and have another look.
Edit: Even stranger. Typing any letter causes that letter "popup" (default android keyboard) to remain in its popup state. So I press 'g', which on an android keyboard causes 'g' to briefly flash as a popup letter in the keyboard, but on your editor, the key stays forever. Very strange stuff. Have not seen this anywhere else before
I think this is ultimately due to some Android devices just having trouble with rendering this many DOM elements in a contenteditable. Weirdly not an issue with Firefox on my Fairphone 5 at all — even the first editor is surprisingly fast for me haha.
I make this mistake a lot, unfortunately, of testing while I'm writing on my laptop and forgetting that phone have completely different performance characteristics.
In both the before and after text editor, my browser immediately crashed when clicking on it. Using edge on android.
I think I should have anticipated that some browsers and some mobile devices wouldn't be able to handle a contenteditable with an entire novel in it. Sorry I crashed your browser :/ I'll truncate the demo text and see if the point still gets across.
Works well for me on android Chrome. Nice job optimizing.
I'm going to be the one to say it: The best way to make it faster is not to use react! :)
I'm not sure if you saw the last section, but on (desktop) Firefox this is actually not true! React ProseMirror is much faster than Firefox's native contenteditable implementation, even without a ProseMirror editor set up at all
That's interesting, a native implementation has to do less work, with less overhead, and with compiled code. Implies that Firefox got something pretty badly wrong.
Ok, thanks everyone for the feedback! I have:
Also discovered some interesting things:
Amazing write-up. I'm excited to go back and read it in depth. I noticed on Mac (M2 Max) Safari, they feel equally fast yet slightly stuttery to me. Like very slightly stuttery to the point most wouldn't perceive it. I suspect an intentional limitation for battery reasons but that the machine is so fast it doesn't seem slow overall. Mac Chrome, both feel great and better than Safari. iOS Safari I instantly feel that the memoized editor is far better.
An interesting test might be power consumption if it were feasible to measure. Anyway, fantastic post again.
Thank you! And thanks for testing it out a bit, good to have more data points. It's super interesting how variable this can be across different operating systems and browsers.
Offtopic: On my iphone, with Orion browser, I had no problem with this website. Just moved to mac with Orion browser again, and it took a long time to load the page. And, I can't seem to load the first editor by clicking on it? And, just before that, the "@nytimes/react-prosemirror@0.7.0-next.10" part appears as "@nytimes/[email protected]" and when clicked takes me to a cloudflare error that tells me it is protecting an email address?
That's.. all incredibly odd haha. The website is fronted by Cloudflare, but I am not aware of any email protection settings (maybe it's on by default?), and I'm not personally seeing that even if I go off of WiFi. Let me poke around and see what I can find...
Update:
Seems like this is indeed enabled by default, and I should be able to turn it off for that string, as well as in general (I already have my own email obfuscation implemented on that site, so I don't have any need for it).
However, the fact that you're seeing that at all is an indication that Cloudflare thinks you might be a bot, which I'm sure is exciting news. That might explain why the site loaded so much more slowly for you on your desktop, as well.
Something is not right when I try it with chrome on Android. Specifically hitting enter caused weird behavior in all examples. In the first one it doesn't work, at the end of a word it does duplicate the word.
The last fast example somewhat works but it duplicates one character for each line break.
Edit:
I did some more testing and it seems to be keyboard related. Gboard works okay, Samsung keyboard has its own weird behavior and the keyboard I initially tested with is heliboard.
I am suspect that both the Samsung keyboard and heliboard might do something slightly odd. But now you at least know they cause issues. I honestly have checked with native posemirror, let me do that as well and get back at you.
Edit2:
Prosemirror on their website works fien with heliboard.
Edit3:
Seems like Android (as often is the case) is a bit of a mess. I found some interesting stuff as I was curious.
It looks like prosemirror has a variety of workarounds implemented (this is quite old but seems to be about pretty much this. If I had to guess is that some of those work arounds aren't present in some of the bits you rewrote in react.
We actually need completely different workarounds for Android keyboards, because we use beforeinput events (native ProseMirror does not) and several Android keyboards produce completely broken beforeinput event sequences on Android Chrome. Slate.js has worled out resolutions to this that we need to take a look at.
On stock latest android and latest firefox, replacements using the Gboard buttons (like "we're" -> "were") take upwards of a full second to insert into the text area on the new version. Typing seems to be pretty fast, though.
Oh! I can reproduce this, too. I wonder what the heck Gboard is doing here to cause this. I'll have to take a look!