PrismJS / prism

Lightweight, robust, elegant syntax highlighting.
https://prismjs.com
MIT License
12.22k stars 1.29k forks source link

Scrolling performance issue (android with Chrome) #1131

Open markg85 opened 7 years ago

markg85 commented 7 years ago

Hi,

I'm a bit stuck in figuring out what is wrong.. If i scroll horizontally on snippets from the prism.js site, it works buttery smooth. No issue at all.

If i scroll horizontally on my page [1] it... well, isn't smooth. It works just fine on desktop browsers! But on android with chrome, it seems to be lagging a bit. I tried the Galaxy Tab S2 and the S6 and both show some sluggish performance.

I'm using the exact source from prism.js. The link to generate the same source: [2].

Besides prism the page from [1] also includes bootstrap css/js, but those don't seem to matter as performance is exactly the same with and without those.

Is there anything i'm doing wrong?

Cheers, Mark

[1] http://p.sc2.nl/HyDaCL7yZ [2] http://prismjs.com/download.html?themes=prism-twilight&languages=markup+css+clike+javascript+bash+c+cpp+diff+ini+json+php+php-extras+smarty+sql+swift+twig&plugins=line-numbers

Golmote commented 7 years ago

I tested the page [1] on Chrome using my Wiko Highway Star and could not reproduce the scrolling issue. It is buttery smooth on my device.

markg85 commented 7 years ago

Hi Golmote,

Weird.. On my devices it's clearly not smooth. in FPS terms, it would be about 20 FPS. Just notably sluggish.

Golmote commented 6 years ago

I'll close this issue, since it was not reproduced. If you keep experiencing scrolling issue and if you can provide reproduction steps, I'll reopen it.

ProticM commented 5 years ago

@Golmote Did you manage to reproduce this issue? I have the same problem on my website. Try opening this link in Chrome on Android. As soon as I remove prism highlighting the page is smooth and scrolling without problems

Golmote commented 5 years ago

I could not reproduce the issue up until now. But I can indeed reproduce it on your test page. I'll reopen the issue then, so it can be investigated further.

RunDevelopment commented 5 years ago

I found the problem.

First: It's a pure CSS issue. There is no JS executed during scrolling and what's tanking the CPU is the rasterization thread.

I was able to pinpoint the problem to one rule:

pre[class*=language-] {
    padding: 1em;
    margin: .5em 0;
    overflow: auto; /* this is the culprit */
}

Disabling the overflow will make your website butter smooth but also wreck the layout of code blocks, so this isn't a solution. But looking at your site I noticed the parent of all pres div.post-content.box-light has an overflow: hidden. Disabling this property won't change the layout of your site (at least I didn't notice any changes on my mobile phone) and makes your site run smoothly. @ProticM I hope this helps.

Now the hard part: It seems like we have discovered a rendering bug in Chrome for Android, so how do we want to deal with this? I do consider this a bug of Prism's themes but I don't have enough knowledge about CSS and on what level it affects the rendering process to fix this, so any ideas?

ProticM commented 5 years ago

@RunDevelopment Indeed it does help. Setting overflow to visible fixed the issue for the post content. Thanks for the help.

The weird thing is that I've tried to recreate the conditions on another static HTML page, but failed to do so, even though I've set the overflow to hidden on the container. The HTML on my website is first parsed from markdown to HTML, and then it's highlighted with prism. On the static page used for testing, there was no dynamic rendering before highlighting the HTML.

Another thing is that on my website I'm using rollup.js and Vue, and on the test page I've added script and link references (no ES6 import) and nothing else...so maybe something else is bugging it...

frantic1048 commented 4 years ago

I'm facing a similar scrolling issue on the desktop version of Chromium Version 78.0.3904.70 (Official Build) Arch Linux (64-bit), with prism.js 1.15.0

Perhaps this issue is related to chromium itself. But I'm not very sure. Anybody who could help reproduce is appreciated.

The reproduce detail is posted on https://bugs.chromium.org/p/chromium/issues/detail?id=428083#c23

RunDevelopment commented 4 years ago

@frantic1048 Chrome has a new layout engine since Chrome 76 which has some problems. One of them is that a hit test (which is necessary for scrolling) can several hundred milliseconds up to several seconds.

For more info (and a fix), see #2062.

frantic1048 commented 4 years ago

@RunDevelopment Thanks for the kind hints. I found a working workaround from https://github.com/PrismJS/prism/issues/2062#issuecomment-535344324 for Chrome 76-77, though it looks really weird :rofl:

RunDevelopment commented 4 years ago

though it looks really weird

What looks weird? The only theme which should look different is Funky (and maybe Coy). All other themes should be unaffected aside from the perf increase.

frantic1048 commented 4 years ago

I mean the workaround in https://github.com/PrismJS/prism/issues/2062#issuecomment-535344324, which adds a pseudo-element on <code>. In general that pseudo-element should cover the <code> element and prevent users from clicking stuff inside <code> element.

But in Chrome, we can still click and select text inside <code>. <-- This is weird

MattOpen commented 4 years ago

Since now Chrome version is 79.0.3945.117 it goes more weird. Before the update I could go with the workaround in #2062 (comment), but now this does not work.

But I have a new solution. Only add this more or less one-liner to your css, no pseudo class necessary.

pre[class*="language-"] span { display: inline-flex; } For my client it works perfect now.