After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 775145 - View source mode is terribly slow
View source mode is terribly slow
Status: RESOLVED FIXED
Product: epiphany
Classification: Core
Component: General
3.23.x
Other Linux
: Normal blocker
: ---
Assigned To: Michael Catanzaro
Epiphany Maintainers
Depends on:
Blocks:
 
 
Reported: 2016-11-26 16:37 UTC by Michael Catanzaro
Modified: 2017-02-12 01:09 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Remove view source handler (43.50 KB, patch)
2017-02-12 01:05 UTC, Michael Catanzaro
committed Details | Review
Fully remove view source handler... (9.59 KB, patch)
2017-02-12 01:09 UTC, Michael Catanzaro
committed Details | Review

Description Michael Catanzaro 2016-11-26 16:37:12 UTC
The view source mode I added in bug #738475 is just ludicrously slow. It might not be possible to do JavaScript-based syntax highlighting in the browser at all, or maybe we just need to explore better JS libraries. I think continuing with Prism is not an option, it's just way too slow.

I also tried RainbowJS, which was orders of magnitude slower than Prism. I guess I decided that since Prism was such a big performance improvement it was acceptable, but it's really not.

If we can't fix this by 3.24 we should go back to using gedit.
Comment 1 Adrian Perez 2017-01-29 16:55:30 UTC
The idea of using a JavaScript-based syntax highlighter still sounds reasonable
to me. The issue with JavaScript-based syntax highlighters is that is quite difficult to good performance comparisons... So far the only one I have found
so far with _actual numbers_ is:

  http://softwaremaniacs.org/blog/2011/05/22/highlighters-comparison/

Apparently from the three tested (SHJS, SyntaxHighlighter, Prettify, Highligh.hs) 
the fastest is Highlight.js, but take it with a grain of salt because the post
is from 2011...

Highlight.js is the one I use on my blog (I have my own static site generator
made in JavaScript) and it works well, and one of the things I like about it
that the API requires explicitly setting the syntax mode (it does not try to
detect from the input) which is a Good Thing™.
Comment 2 Adrian Perez 2017-01-29 22:23:39 UTC
Okay, so I went ahead and wrote a quick hack to benchmark the JS syntax 
highlighters that I could find readily available to be installed with NPM,
and ran it over the GNOME web site front page (HTML), the CSS for the
Fancybox plugin used in the GNOME web site (CSS), and the main module of
the Prism highlighter itself (JavaScript). My conclusions are:

* Rainbow is indeed _really_ slow. Avoid.

* Prism is not the slowest, but not the fastest either. The difference
  in speed can be noticeable (e.g. Highlight.js doubles its speed for
  CSS code.

* Highlight.js, which I pointed out in my previous post, is consistently
  in the top of the results, but...

* If we forget about Sublemon (more on it later), the CodeMirror highlighter
  is the fastest for the slower tests (HTML and JavaScript, likely slower
  because they are harder to parse), with a solid second position for CSS.
  I would use this if accurate highlighting is desired.

* Sublemon beats them all, in every test. This is because it does not try
  to parse a particular language, but it has a few generic matching rules
  that work with most of them to achieve a reasonably pleasant output. This
  means highlighting may not be 100% accurate, but from what I could see the
  generated output looks good enough. This can be a reasonable trade-off if
  we want the absolute fastest JS-based syntax highlighting.

The code for the benchmark can be found here:

  https://github.com/aperezdc/js-highlighters-shootout

Full benchmark run output:

  >>> js 
  highlightJs x 92.47 ops/sec ±3.21% (70 runs sampled)
  highlights x 58.56 ops/sec ±3.67% (61 runs sampled)
  illuminate x 71.45 ops/sec ±2.45% (73 runs sampled)
  codeMirrorHighlight x 108 ops/sec ±4.07% (69 runs sampled)
  rainbowCode x 5.96 ops/sec ±7.40% (19 runs sampled)
  sublemon x 134 ops/sec ±2.50% (76 runs sampled)
  prismJs x 84.06 ops/sec ±3.12% (71 runs sampled)
   - Fastest: sublemon
  >>> css 
  highlightJs x 396 ops/sec ±3.19% (83 runs sampled)
  highlights x 75.43 ops/sec ±3.78% (64 runs sampled)
  illuminate x 136 ops/sec ±2.93% (77 runs sampled)
  codeMirrorHighlight x 360 ops/sec ±3.76% (83 runs sampled)
  rainbowCode x 17.82 ops/sec ±3.06% (38 runs sampled)
  sublemon x 389 ops/sec ±2.62% (85 runs sampled)
  prismJs x 222 ops/sec ±2.72% (85 runs sampled)
  - Fastest: highlightJs
  >>> html 
  highlightJs x 71.92 ops/sec ±3.81% (64 runs sampled)
  highlights x 59.05 ops/sec ±3.71% (61 runs sampled)
  illuminate x 55.30 ops/sec ±2.31% (70 runs sampled)
  codeMirrorHighlight x 124 ops/sec ±2.72% (76 runs sampled)
  rainbowCode x 3.24 ops/sec ±7.51% (13 runs sampled)
  sublemon x 153 ops/sec ±2.42% (77 runs sampled)
  prismJs x 36.63 ops/sec ±2.62% (63 runs sampled)
   - Fastest: sublemon
Comment 3 Adrian Perez 2017-01-29 22:29:52 UTC
BTW, as you can see from the results, anything that is not Rainbow manages to generate the HTML for the highlighted code dozens of times per second. That
should be enough to not end up being “terribly slow”, so I wonder whether the
way in which the Prism highlighter is being invoked could be the issue here
(and not the highlighter itself). WDYT?
Comment 4 Michael Catanzaro 2017-01-30 00:38:27 UTC
(In reply to Adrian Perez from comment #3)
> BTW, as you can see from the results, anything that is not Rainbow manages
> to generate the HTML for the highlighted code dozens of times per second.
> That
> should be enough to not end up being “terribly slow”, so I wonder whether the
> way in which the Prism highlighter is being invoked could be the issue here
> (and not the highlighter itself). WDYT?

Um, that's interesting... maaaybe? It takes 3-4 seconds for Prism to highlight gnome.org in Epiphany here. But the Epiphany-level code is pretty simple....
Comment 5 Adrian Perez 2017-01-31 01:46:32 UTC
I took a quick peek at how “ephy-source://” is handled, and it could be that
including the “prism.js” script first and then the content, letting the script
detect which HTML elements need to be highlighted might have to do with the
sluggishness. I would do something like generating the following code:

  <html>
    <head>
      <link rel="stylesheet" type="text/css" href="ephy-resource:///prism.css">
    </head>
    <body>
      <pre id="highlight" style="display: none">${HTML_SOURCE}</pre> 

      <!-- Do whatever is needed to turn of Prism's auto-detection
            of code block elements. -->
      <script type="text/javascript" src="ephy-resource://prism.js"></script>

      <script type="text/javascript">
        let el = document.getElementById('highlight');
        el.innerHTML = Prism.highlight(el.textContent, Prism.languages.html);
        el.style.hidden = "";  // Show the element.
      </script>
    </body>
  </html>

Note how the <pre> element is initially hidden, we do the syntax highlighting,
update the DOM, and then change the “display” style property *last*. This
completely avoids displaying elements while they are getting updated, which
saves relayout and redraws. My guess is that relayouts (which are expensive)
are the main culprit for highlighting being slow at the moment.
Comment 6 Michael Catanzaro 2017-01-31 05:29:13 UTC
Thanks for investigating, but that doesn't seem to make any difference. :(
Comment 7 Michael Catanzaro 2017-02-12 01:05:31 UTC
The following fix has been pushed:
d6dba00 Remove view source handler
Comment 8 Michael Catanzaro 2017-02-12 01:05:38 UTC
Created attachment 345551 [details] [review]
Remove view source handler

This is still half-baked: it's waaaay too slow. I should never have
pushed it.
Comment 9 Michael Catanzaro 2017-02-12 01:09:01 UTC
The following fix has been pushed:
3f322c5 Fully remove view source handler...
Comment 10 Michael Catanzaro 2017-02-12 01:09:05 UTC
Created attachment 345552 [details] [review]
Fully remove view source handler...

Must have had some mistake with git.