我正在构建一个小型 Web 应用程序,其中包括一个通过 websocket 定期更新的网页。每条消息都是一个包含许多 HTML 标记的字符串,包括 LaTeX 代码。该字符串的内容被放入一个div
容器中。然后我使用renderMathInElement
from 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 接口是否以任何方式延迟,这可能会导致部署实例和本地实例之间的差异?如果它是严格的,不应该使流量速度有任何差异,因为在处理开始时消息已经完全传输?
如果您需要澄清,请告诉我。