简体   繁体   中英

Improve performance of jQuery for large amount of DOM processing

I am implementing a blog page for my web application. I am using marked for markdown support and highlight.js for code highlighting. Here is my code where I am handling parsing and highlighting:

import marked from "marked";
import DOMPurify from "dompurify";
import hljs from "highlight.js";
import $ from "jquery";

class MarkDownParser {
    // configuration for marked
    static markedOptions = {
        highlight: function (code, language) {
            if (language) {
                const validLanguage = hljs.getLanguage(language);

                if (validLanguage) {
                    return hljs.highlight(language, code).value;
                }
            }
            return hljs.highlightAuto(code).value;
        },
        gfm: true,
        silent: true,
    };

    static getMarkDown(text) {
        var markedHtml = marked(text, this.markedOptions);
        var newHtml = '<div id="container" >' + markedHtml + "</div>";
        var dom = $(newHtml);

        dom.find("code").each(function () {
            var par = $(this).parent()[0];

            if (par.tagName === "PRE") {
                // adding line numbers in code blocks
                var n = $(par).html().split("\n").length;
                var line_nums = "<div class='line-num-container'>";

                for (var i = 1; i <= n; i++) {
                    line_nums += `<span class="line-num">${i}</span>`;
                }

                line_nums += "</div>";
                $(par).prepend($(line_nums));
            } else {
                // highlighting inline codes, because marked.js highlights blocked codes only
                var code = $(this).text();
                $(this).text("");
                $(this).html(hljs.highlightAuto(code).value);
            }
        });

        // wrapping tables with div for overflow handling
        dom.find("table").each(function () {
            $(this).wrap("<div class='table-wrapper'></div>");
        });

        return DOMPurify.sanitize(dom.html());
    }
}

export default MarkDownParser;

In this function, I am parsing text using marked and then doing some more processing using jquery and highlight.js.

My problem is, I am not quite satisfied with the performance of the getMarkDown(text) function. I am not sure why it is slow, but I am assuming that the reason is the big amount of DOM creation and insertion. When there are 100 lines of codes in the <code> tag, it will create 100 spans for line numbers and prepend it in the DOM. I have checked the execution time and found out that it spends most time in the first loop where I am working with the <code> tag. I have also noticed that, when I load my web app first time (after a hard reload), it works slower, after that it becomes faster than the first time.

  • Why is this code slow?
  • Why it is slower on the first load?
  • How can I improve this code to achieve a better performance?

After some analysis using performance profiler, I figured out that the highlightAuto() function of highlight.js was the reason for slow execution. I solved the performance issue by avoiding the use of that function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM