6 ms·
Hi, I'm working on the editor since almost 5 years now. Phew, time flies. There is no silver bullet, we mostly try to keep all computations limited to the vie
by alexdima 10y ago
Hi,
I'm working on the editor since almost 5 years now. Phew, time flies.
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. should all end up being computed with loops covering those 20 lines and not the entire buffer size).
We also use extensively the profilers, and most recently (last month) I learned about this great tool called IR Hydra[1]. 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 use translate3d for scrolling (except in Firefox which has a known bug[2]) and that brings down the browser painting times considerably when scrolling.
I've also found insertAdjacentHTML to be the fastest way to create dom nodes (from big fat strings) across all browsers.
Sort of silly to mention, but we use binary search a lot :).
[1] http://mrale.ph/irhydra/2/ http://mrale.ph/irhydra/2/
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=1083132 https://bugzilla.mozilla.org/show_bug.cgi?id=1083132
- tiles 10y agoThanks for this. :) Learning the type of tricks needed to get DOM performance are hard-won, I imagine, so hearing it straight from a developer is extremely valuable to me.
- alexdima 10y agoForgot to mention a funny fact I found. Minify everything [1] [1] https://top.fse.guru/nodejs-a-quick-optimization-advice-7353b820c92e#.nfvi89hjc https://top.fse.guru/nodejs-a-quick-optimization-advice-7353...
- vanderZwan 10y ago> v8 optimizer (crankshaft) inlines the functions whose body length, including the comments, is less than 600 characters. In what kind of world is that a sensible metric to decide if a function can be inlined?
- luckystarr 10y agoIn the "I need to do this quickly to finish my sprint" world.
- konschubert 10y agoWasn't V8 written in a cottage in Denmark? http://www.ft.com/cms/s/0/03775904-177c-11de-8c9d-0000779fd2ac.html http://www.ft.com/cms/s/0/03775904-177c-11de-8c9d-0000779fd2... I cannot imagine that they would take unreasonable shortcuts.
- luckystarr 10y agoWell, unreasonable now was probably perfectly reasonable at the time of implementation. Perhaps they even have or had a plan to improve upon it, but given other tasks (ES6, etc.) it hasn't been given much priority. I mean, why would they fix it with high priority if the engine already has reasonable performance and the benchmarks are happy as well?
- egeozcan 10y agoEven then, why include comments? Is it to support stuff like multi-line strings as comments hack[1]? [1]: https://github.com/sindresorhus/multiline https://github.com/sindresorhus/multiline
- lorenzhs 10y agoIn the world where you have to make these decisions quickly, and don't have time to parse the function.
- vanderZwan 10y agoI don't buy it: that would only make sense if you could copy/paste the source or something, and even JS respects function scoping so you can't. You'd have to wait until later anyway, so why not count AST nodes or something instead?
- OmarIsmail 10y agoSome more questions on performance: It looks like you're adding and removing line divs, did you run benchmarks on trying to reuse the line divs and change the contents of them? By using translate3D you're not using the browser's native scrolling correct? Are you using an open source library to replace the scrollbar? What was the actual performance benefit of using translate3D vs native scrolling?
- alexdima 10y agoI love these questions! I've actually never tried to compute a diff and apply it inside a line, maybe I'll try it tomorrow :). A line is basically a list of spans, each having a certain class name and a certain text content. 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). But I will definitely try it out! Here is what we do now - https://github.com/Microsoft/vscode/blob/master/src/vs/editor/browser/view/viewLayer.ts#L550 https://github.com/Microsoft/vscode/blob/master/src/vs/edito... [It might not be the best method, but it was guided by measuring]: * if there is no overlap between frames (e.g. you jump to a completely different location), the whole thing does a single innerHTML call * otherwise: * all the old lines that leave the viewport are removed via multiple domNode.removeChild * all the new lines that enter the viewport are added via a single domNode.insertAdjacentHTML * all the old lines that have changed are parsed in one single off-dom innerHTML and then cherry picked via multiple domNode.replaceChild 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. Maybe there are better ways? If I remember correctly, we ended up not using native browser scrolling for multiple reasons: * [if we would not set scrollTop ourselves] 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. But you'd always get this white flash. * if we would set scrollTop ourselves: * AFAIK setting the scrollTop causes a stop the world sort of synchronous layout - I don't know why * We wanted to have an overview ruler that sits inside the scrollbar and highlights things (find matches, diffs, etc.) * IE has or had a limit around 2.5M px. That meant we would have had to do something special anyways around 80.000 lines @ 19px line height The scrollbars are custom implemented (https://github.com/Microsoft/vscode/tree/master/src/vs/base/browser/ui/scrollbar https://github.com/Microsoft/vscode/tree/master/src/vs/base/...). Quick tip: do not implement custom scrollbars. PS: 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). One of the first things the model (buffer) code did was to split the text into 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. I would then remember the last cut off index and do a simple substring to extract each line, building an array of lines. 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++). If I remember correctly, that was taking 50ms in some browser for a pretty large string. I replaced that simple for loop with a lame split with a regex! - /\r\n|\r|\n/ - and the time dropped to 3ms. I can only think that looping in C++ must be a lot better than looping in JS [here's the code today - https://github.com/Microsoft/vscode/blob/master/src/vs/editor/common/model/textModel.ts#L596 https://github.com/Microsoft/vscode/blob/master/src/vs/edito...]
- aceperry 10y agoAwesome work, I love the speed. What it needs is a useable vim plugin, otherwise, it would be too difficult to use regularly, or for any real work. BTW, I also appreciate that it's cross- platform and runs on linux.
- johnfn 10y agoContributor to the VSC Vim extension here. I've been working on it frantically over the last few weeks and I'd strongly recommend giving it another try. I believe it's made some big strides in usability. And obviously creating issues on the github repo for things you're missing is a big help for me. I try to have a fast turnaround on these things.
- lloeki 10y agoMissing from (or aside) this vim plugin is ex mode, similar to this[0]. I read that this is out of scope with the project, but being able to build it as another plugin could be great. This is the approach taken by vim-mode/ex-mode on Atom. [0]: https://github.com/lloeki/ex-mode https://github.com/lloeki/ex-mode
- johnfn 10y agoThis is very true. I let my own usage patterns and github issues be a guide to what I do next. I don't use ex mode very much, outside from simple substitutions, and I haven't gotten any issues yet either. I remember reading that the Atom Vim authors believed separating the two was a mistake; they were too intertwined. As much as I'd like to have it be a separate project and not think about it, apparently that doesn't work so well...
- deleted 10y ago[deleted]
- mrmondo 10y agoThanks for your interesting reply and wow 5 years (also why was it kept in the dark until now?)