Skip to content

Move default highlight.js highlighting into a web worker #3591

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

stevenday
Copy link

Hi,

We noticed that pages served by gitea locked up when viewing large files, which I tracked down to (mainly) the syntax highlighting javascript. Highlight.js have an example on their docs of moving the actual highlighting to a web worker so that it doesn't block the rest of the page, and this seems to be a big improvement for us so I thought I'd see whether it would be interesting to you.

There are a couple of other places where you use highlight js, but they're for specific situations (preview panes etc) where I wasn't so sure this would be desirable. I'd be happy to extend it to those too if needs be.

Thanks!

@codecov-io
Copy link

codecov-io commented Feb 27, 2018

Codecov Report

Merging #3591 into master will decrease coverage by <.01%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3591      +/-   ##
==========================================
- Coverage   36.16%   36.15%   -0.01%     
==========================================
  Files         285      285              
  Lines       40905    40905              
==========================================
- Hits        14792    14790       -2     
- Misses      23941    23943       +2     
  Partials     2172     2172
Impacted Files Coverage Δ
models/repo_list.go 65.62% <0%> (-1.57%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2cd3622...7c2cc02. Read the comment docs.

@tboerger tboerger added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Feb 27, 2018
@stevenday
Copy link
Author

I've fixed one of the codacy issues in 0d5afc2 (missing semi-colon) but I've left the other one (strings should use double quotes) since it seems at odds with the rest of the js files (they use single-quotes). Happy to change it if that's preferred though.

@@ -1430,7 +1430,13 @@ $(document).ready(function () {

// Highlight JS
if (typeof hljs != 'undefined') {
hljs.initHighlightingOnLoad();
$('pre code').each(function (index, element) {
var worker = new Worker('/js/highlight-worker.js');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can only have one worker by putting it before the each.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to keep reference of element to update but will limit multiple worker loading

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sapk - Sure, I've switched to that approach in 65605cd - it now keeps hold of the array of code elements and passes the index into that array around so that we can update the right element when we get the highlighted html back.

I also fixed a typo in the filename of the worker script.

// A very simple web worker for highlight.js
// See: https://highlightjs.org/usage/
onmessage = function(event) {
importScripts('/vendor/plugins/highlight/highlight.pack.js');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It must be possible to put importScripts outside of onmessage.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And you will have to follow codacy (even if it is stupid) to be able to be merge by maintainers. Maybe if you add
'use strict'; at start of file it may also not trigger for simple ' string

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sapk - I've moved the import out in 7c2cc02 - it still works fine in my testing, so 👍 I've also added a use strict and will see how it goes, but I'll get codacy to pass somehow if not.

Copy link
Member

@sapk sapk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM over all. Just a little adjustement to optimize.

@tboerger tboerger added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels Feb 27, 2018
@thehowl
Copy link
Contributor

thehowl commented Feb 27, 2018

Caniuse stats. will work in 94.5% of cases, and it is supported in IE >= 10 so this looks alright. Except...

initHighlightingOnLoad does not just get the text and highlight it accordingly - it correctly handles the case, like it happens in gitea, where there are children elements to the code tag. https://github.com/isagalaev/highlight.js/blob/898bcd268fb684a6b94e0e817d0ec715178038be/src/highlight.js#L616:12

The reason why this needs to be addressed is that right now the code page looks like this:

screenshot-2018-2-27 afas

with the changes of this pr, it will look like this (uglier):

screenshot-2018-2-27 afas 1

This is not the only implication: selecting a line to get the link to it will also not work (will just append #undefined to the url).

@stevenday
Copy link
Author

@thehowl - ah, good catch.

I'm not sure I have a solution to that - Highlight.js' highlightBlock manipulates dom elements directly in order to merge all the tags together in the right order and not break the resulting highlighted markup. You can't do that in a web worker, (at least, not without doing something crazy like loading jsdom) and the internals are complex so I don't think this will ever work.

Sorry for wasting your time :(

@stevenday stevenday closed this Feb 28, 2018
@thehowl
Copy link
Contributor

thehowl commented Feb 28, 2018

No time was wasted - we now know there is no easy solution for this, but this may still be necessary to add sometime in the future :) (Although I tend to think that we should rather try to move syntax highlighting to the backend, but I think there's already an issue for that somewhere)

@go-gitea go-gitea locked and limited conversation to collaborators Nov 23, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
lgtm/need 1 This PR needs approval from one additional maintainer to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants