Render blobs with server-side syntax highlighting
The client-side prettify.js is appealingly simple but does not
perform well on large files, particularly with blame, and can't be
made to work with layouts other than the simplest <ol>. Replace it
with a server-side implementation, using a straight Java port of
prettify.js[1].
The implementation is still very much Soy-based with a few small
optimizations to avoid unnecessary object allocation and copying in
inner loops, e.g. using SoyMapData directly instead of constructing
ImmutableMaps just to have Soy convert them internally. As a rough
benchmark, on my MacBook Air it can render a 750-line file in about
150ms and a 4500-line file in about 250ms. (This just counts the
rendering step after syntax highlighting.)
This was compared with two other implementations.
The first implementation wrote the whole <ol> directly to the
OutputStream with no allocations. This was very fast: about 10ms for
the same 750-line file. Unfortunately, this approach would be much
harder to make work with a table-based blame layout; the HTML in the
blame region half of the table is sufficiently complicated that we
would really like to use a template engine for that.
The second implementation built the contents of each <li> with as few
allocations as possible (e.g. reusing a single StringBuilder), then
passed the list of lines with pre-rendered spans to Soy to be rendered
in a list. This approach would work with table-based blame, since what
would be a <li> content in the blob view would be a <td> in the blame
view. This was only about 10-20% faster than the full Soy-based
approach, so judged not worth the additional code complexity.
It is also worth noting the client-side cost. Rendering the 750-line
file after receiving the content takes my Chrome about 250ms (180ms
in "Recalculate Style"), and about 400ms for 4500 lines. This bounds
the benefit of any server-side improvements: no matter what, there
will still be a visible pause when loading even a moderately complex
file.
[1] https://code.google.com/p/java-prettify/
Change-Id: I3d81c40e05d38c2c9431bc1c61ba59618756574e
5 files changed