The way we're doing the rendering each cell is its own div and we reuse divs as they scroll out of the viewport (changing their top position). contact pictures) so simple spans aren't always sufficient. We have to handle some richer content (i.e. I'm maintaining a web spreadsheet that supports 10s of thousands of rows and have spent a lot of time on optimization. I can only think that looping in C++ must be a lot better than looping in JS I replaced that simple for loop with a lame split with a regex! - /\r\n|\r|\n/ - and the time dropped to 3ms. If I remember correctly, that was taking 50ms in some browser for a pretty large string. I thought that must be the best way one could possibly do this (I don't know a better way than a for loop even in C++). I would then remember the last cut off index and do a simple substring to extract each line, building an array of lines. I implemented this as any sane person would, with a nice for loop, iterating over the string, grabbing the character code at each offset and checking if it was \r or \n or a \r followed by a \n. One of the first things the model (buffer) code did was to split the text into an array of lines. Some anecdotal evidence I got that making less calls with larger chunks of data might be better was when I was investigating why creating an editor buffer was slow for very large files (100k+ lines). Quick tip: do not implement custom scrollbars. That meant we would have had to do something special anyways around 80.000 lines 19px line height * We wanted to have an overview ruler that sits inside the scrollbar and highlights things (find matches, diffs, etc.) * AFAIK setting the scrollTop causes a stop the world sort of synchronous layout - I don't know why * the browser would just happily jump to a certain scrollTop, painting nothing (white), then we'd get an `onscroll` and we'd be able to paint the lines. If I remember correctly, we ended up not using native browser scrolling for multiple reasons: That is what I could come up with in my attempts to minimize the count of dom calls and not pay for reparsing/repainting the entire viewport on each frame. * all the old lines that have changed are parsed in one single off-dom innerHTML and then cherry picked via multiple domNode.replaceChild * all the new lines that enter the viewport are added via a single domNode.insertAdjacentHTML * all the old lines that leave the viewport are removed via multiple domNode.removeChild you jump to a completely different location), the whole thing does a single innerHTML call * if there is no overlap between frames (e.g. I've just always assumed that iterating over the previous spans, adjusting their class names, adjusting their text content, appending new spans or removing extra left overs would be slower than a big fat innerHTML call (given that each dom read/write access leaves the JS VM and I always thought there's a certain penalty associated with each dom call). ![]() A line is basically a list of spans, each having a certain class name and a certain text content. ![]() I've actually never tried to compute a diff and apply it inside a line, maybe I'll try it tomorrow :). Sort of silly to mention, but we use binary search a lot :). I've also found insertAdjacentHTML to be the fastest way to create dom nodes (from big fat strings) across all browsers. We use translate3d for scrolling (except in Firefox which has a known bug) and that brings down the browser painting times considerably when scrolling. The gains from eliminating bailouts in the hot code paths are probably too small to notice (5-10% per render), but I like to think that everything adds up. ![]() We also use extensively the profilers, and most recently (last month) I learned about this great tool called IR Hydra. ![]() should all end up being computed with loops covering those 20 lines and not the entire buffer size). There is no silver bullet, we mostly try to keep all computations limited to the viewport size (if you have 20 lines visible, then typing, colorizing, painting a frame, etc. I'm working on the editor since almost 5 years now.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |