0

我正在构建一个小型 Web 应用程序,其中包括一个通过 websocket 定期更新的网页。每条消息都是一个包含许多 HTML 标记的字符串,包括 LaTeX 代码。该字符串的内容被放入一个div容器中。然后我使用renderMathInElementfrom KaTeX来解释 LaTeX 部分。

问题: 这适用于小消息,但对于大字符串,站点在插入新内容时开始闪烁。闪烁只发生在已部署的版本中,这让我很恼火,因为我的 Firefox 应该始终以相同的速度运行 javascript 代码。事实上,已部署版本的加载时间较慢,不应该改变 javascript 代码的效率。

代码

// connect the websocket
if (location.protocol == 'https:') {
    var socket = new WebSocket("wss://" + location.host + "/lectureserver", "lecture");
} else {
    var socket = new WebSocket("ws://" + location.host + "/lectureserver", "lecture");
}

var last = ""; // last message
var content = document.getElementById("lecture"); // div displaying content
var content_hidden = document.getElementById("lecture_hidden"); // hidden element to prepare content

socket.onerror = function (error) {
    console.log("unable to connect");
    content.innerHTML = "<p>Error. Can't connect!</p>";
};

socket.onmessage = function (event) {
    // check if data didn't change or is empty
    if (event.data == last || event.data == "") {
        return;
    }
    // save current vertical scroll position
    var scrollY = window.scrollY;
    // and old max height (to determine if client scrolled to the very bottom)
    var oldMax = document.body.scrollHeight - document.body.clientHeight;
    // save the received data
    var newContent = event.data;
    // fill the hidden element with the content
    content_hidden.innerHTML = newContent;
    // evaluate the math (KaTeX)
    renderMathInElement(content_hidden, {
        delimiters: [
            {left: "\\[", right: "\\]", display: true},
            {left: "\\(", right: "\\)", display: false},
            {left: "\\begin{align\*}", right: "\\end{align\*}", display: true},
            {left: "$", right: "$", display: false}
        ],
        macros: {
            "\\Q": "\\mathbb{Q}",
            "\\C": "\\mathbb{C}"
        },
        strict: false
    });
    // replace old content with now rendered and prepared new content
    content.innerHTML = content_hidden.innerHTML;
    // reset last content
    last = event.data;

    // keep window in place
    if (scrollY >= oldMax) {
        window.scrollTo(scrollX, 100000);
    } else {
        window.scrollTo(scrollX, scrollY);
    }
};

如您所见,我添加了一个 hidden div,它首先准备内容,然后content.innerHTML再用新内容替换真实内容。但是这种变化并不能解决闪烁的问题。

如果您想知道,即使移除renderMathInElement零件也不能解决问题。闪烁速度更快,但仍然存在。

javascript websocket 接口是否以任何方式延迟,这可能会导致部署实例和本地实例之间的差异?如果它是严格的,不应该使流量速度有任何差异,因为在处理开始时消息已经完全传输?

如果您需要澄清,请告诉我。

4

0 回答 0