Skip to content
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

Large amounts of text slow or non-responsive to highlight #2130

Closed
apollolux opened this issue Dec 10, 2019 · 5 comments
Closed

Large amounts of text slow or non-responsive to highlight #2130

apollolux opened this issue Dec 10, 2019 · 5 comments

Comments

@apollolux
Copy link

apollolux commented Dec 10, 2019

Information:

  • Prism version: 1.17.1 minified from CDNJS
  • Plugins: Autoloader, line numbers, toolbar+copy-to-clipboard
  • Environment: Chromium browser 80.03966.0 64-bit on Win7 Enterprise x64, Intel i7-6700 @ 3.4 GHz processor, 32 gigs RAM

Description
I wrote a script to generate semi-random SQL insert statements to simulate user data based on some variables - X × number of row groups, Y × number of subgroups in that row, Z × maximum number of hits in that subgroup. For each hit, one insert of 13 columns of hit-specific data is written; for each subgroup, one comment line, one insert of 14 columns of subgroup-specific data, and one insert of 3 columns of subgroup metadata are written in addition to the inserts for the hits. While the specific use case is somewhat proprietary, this could very easily be used for something like forum software.

The resulting generated text is more or less (X × Y × (3 + random(1, Z)) lines long, with the long inserts being at least 400 characters long each. For my case I used X = 1000, Y = 3, and Z = 5 to get 14213 lines of a little over 4 MiB of text.

The text generation is fast enough; non-highlighted text actually scrolls very easily. Calling Prism.highlightElement (whether automatically via the generator script or manually in the console) on the resulting block of text is really slow or even hangs the browser. I attempted afterwards to only generate X = 500, Y = 3, Z = 1 to check, and the resulting 6000 lines of text took about 20 seconds to convert to a Prism box with line numbers, and another 60-120 seconds to highlight the text, with another 5-10 seconds to react to a mouseover to show the one-button toolbar.

Example

var groups = 1000;
var subgroups = 3;
var maxhits = 5;

// column names as arrays of strings
var subgroupColumns = new Array(14); // get your column names somehow
var subgroupMetadataColumns = new Array(3);
var hitColumns = new Array(13);

// pre-formatted statement bits for convenience
var insertSubHalf = `INSERT INTO DB.SUBGROUPS (${subgroupColumns.join(', ')}) VALUES`;
var insertSubMetaHalf = `INSERT INTO DB.SUBGROUPS_META (${subgroupMetadataColumns.join(', ')}) VALUES`;
var insertHitHalf = `INSERT INTO DB.SUBGROUPS_HITS (${hitColumns.join(', ')}) VALUES`;

var currentGroup = 1;
var statements = [ ];
// generate the statements, simplified version
for (var i = 0; i < groups; ++i) {
  for (var j = 0; j < subgroups; ++j) {
    var subData = generateData( ... ); // actual data doesn't matter
    var subMetaData = generateData( ... ); // actual data doesn't matter
    var formattedSubData = formatForSQL( subData ); // assume format is fine
    var formattedSubMetaData = formatForSQL( subMetaData ); // assume format is fine
    var numHits = 1 + (Math.random( ) * (maxhits - 1)) | 0;
    statements.push( `-- ${i} // ${currentGroup} : ${j}` );
    statements.push(`${insertSubHalf} (${formattedSubData})`);
    statements.push(`${insertSubMetaHalf} (${formattedSubMetaData})`);
    for (var h = 0; h < numHits; ++h) {
      var hitData = generateData( ... ); // actual data doesn't matter
      var formattedHitData = formatForSQL( hitData ); // assume format is fine
      statements.push(`${insertHitHalf} (${formattedHitData})`);
    }
  }
  ++currentGroup;
}
if (statements.length > 0) statements.push('COMMIT;');

// fill the element with the text
var elem = getTheElementSomehow( ); // in this case, the code inside the pre
if (elem) {
  elem.textContent = statements.join('\n');
  Prism.highlightElement( elem ); // highlight; expected language is SQL
}
@RunDevelopment
Copy link
Member

There are two things that cause your performance issue.

First is #2062 which we declared to be a bug in Chrome itself and don't plan to do anything about. But there is a workaround that will fix the "5-10 seconds to react to a mouseover".

The "60-120 seconds to highlight the text" is most likely due to the way Chrome updates the DOM. The actual highlighting of text by Prism is usually very fast but Chrome has an issue with inserting the generated highlighted code. I don't know why but the next layout calculation after inserting a large number of DOM nodes (as syntax highlighters do) seems to take significantly longer than usual.
To speed up this up, you can use a trick and detach the pre from the rest of the DOM. See #1907 and #2020 for more details.

Please also note that these are all Chrome-related issue. All non-chromium browsers should be fine.

I hope this solves your issue.

@terrynguyen255
Copy link

This save my day! Thank you @RunDevelopment

@terrynguyen255
Copy link

terrynguyen255 commented May 20, 2020

I also tried disabling event 'resize'. It didn't help my case.
But @RunDevelopment solution helps

@RunDevelopment
Copy link
Member

@Nogias9x Please provide more information. What is your issue?

@sagecoretech
Copy link

No, it's not a chrome only issue. I've experienced issues on Firefox with as little as 1000 lines of html

Will try detaching pre from dom, updating then attaching again.

However, my own parser doesn't have these issues so I'm thinking it's not a DOM problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants