通过在文本区域中部分显示数据来动态显示大量文本
Dynamically displaying large amounts of text by partially displaying data in textarea
目标:
优化需要在 textarea
或内容可编辑 div
中显示大量文本数据 (25mb+) 的网页,同时不会损失太多性能。
目前,在 Chrome 上加载一个 10mb 的文件大约需要 3 秒。我希望最长为 1 秒。
想法与尝试:
我正在使用 <input type="file">
从用户计算机加载本地文本文件,将大文件直接加载到内存中没有问题。但是,一旦我尝试在文本区域中显示此文本数据,我自然会 运行 遇到性能问题。
我禁用了拼写检查、自动大写和自动完成功能,这当然有帮助,但是我想尽量减少尝试渲染大文件(大于 10mb 的文件,最大 100mb 的文件)时的延迟量理想)。
<textarea autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">
我的一个想法是只渲染当前行之前的 100 行和之后的 100 行,当用户滚动 textarea 时,我会关闭正在显示的数据。我可以交换几百行而没有任何明显的延迟,但是数十万行会锁定整个页面。
我也在研究诸如 CodeMirror 之类的项目,它用于一些基于 javascript 的文本编辑器,以及 chrome 开发工具。然而,当最初加载大量文本时,快速测试显示了类似的性能问题。
另一个想法是使用 highlight.js 来呈现文本 dom 元素,但我在处理数千个 DOM 元素时也注意到大量的 large。
This site seems to tackle a similar example 通过动态创建和显示 dom 元素,而不是尝试一次渲染所有元素。
I have found that if the number of records in the grid becomes more then just a few thousands the grid gets very slow because the rendering speed is directly related to the number of nodes in the DOM. If the number of nodes in the DOM is more then 40-50k (depending on your computer configuration and amount of memory), your browser will crash or will become unresponsive.
So, I decided to set out on a quest to do two things: (1) dynamically create records as user scrolls (2) optimize grid to handle large data sets. After a few weeks of work, the grid was optimized and ready for testing.
我认为这与我的第一个想法相似,但我还没有尝试过这种方法。
我希望有过类似经历的人可以提供一些关于该走哪条路的建议,或者提供一些额外的想法。
在有人问之前,我不能不显示此数据,它需要用户可编辑,不需要突出显示代码或显示行号。最后,整个文本文件正在使用 FileReader 加载到变量中。
出于最终用户隐私和 NDA 考虑,我希望尽可能避免将文件上传到我的网络服务器。
服务器配置:Ubuntu 16.04 LAPP Stack with Laravel 5.4,但对 NodeJS 解决方案开放。允许使用 jQuery。
建议的解决方案:
Lazy Loading - 当用户滚动时,一次只显示 300 行“块”。在这种情况下,需要提前将滚动条设置为合适的高度。 - 此外,应该在用户滚动时卸载这些“块”以减少总的 DOM 渲染负载。
伪代码:
c_chunk = scrollpos / scrollheight * totalChunks;
chunk_block = chunk[c_chunk--] + chunk[c_chunk] + chunk[c_chunk++];
my_textarea.val(chunk_block);
对这个方法有什么想法吗?
谢谢大家
正如我所承诺的,这是我的解决方案:
所以在摸索了各种想法并尝试了不同的方法之后,我想我最终决定在我的项目中使用 Ace。我选择 Ace 有几个原因。
- 记录完备 API 除了相当大且活跃的社区外,它也很容易理解。
- 性能,与我使用大文件使用 Code Mirror 进行的测试相比,Ace 的性能无疑要好得多。 (500,000 行,github 表示 Ace 已通过多达 400 万 行的测试。
- 开箱即用的功能 Ace 有更多功能可以帮助您,运行 用户设置或配置很少。入门总共不到 10 行!
- 它不像Code Mirror那样支持那么多浏览器,但我的项目是运行 WebGL所以我不是很在意。
所以你明白我的推理,你想自己拿 A 和 运行?简单,只需跳到 build repo 并选择适合您需要的口味即可。我获取了 src-min 版本,因为我会将它添加到我的构建脚本中。
然后以任何方式包含 javascript 文件:
<script src="/ace/ace.js" type="text/javascript" charset="utf-8"></script>
还有一个元素到您的页面 id="editor"
。就我而言,我会将其直接附加到 div:
<div id="editor">Any text you want to have auto displayed</div>
并在 javascript 文件中:
var editor = ace.edit("editor");
editor.setTheme("ace/theme/chrome");
editor.session.setMode("ace/mode/javascript");
editor.$blockScrolling = Infinity;
如果你只是想四处看看languages/themes/options/etc。可用,只需前往 Ace's kitchen sink page 并与编辑器一起玩。
现在我还需要一些功能,例如能够将文件加载到文本区域中 - 您可以通过以下方式实现:
加载本地文件:
// Add event listener to the file input
// Note: This will not fire twice if the user opens File A, then re-opens file A
// To detect re-opening a file you will need to clear the input
// after the file is read so that it "changes" upon re-opening
document.getElementById('open-file').addEventListener('change', handleFileOpen, false);
// First we create the function handler that fires when our input is changed
function handleFileOpen(e) {
var file = e.target.files[0]; // Get first file selected
// Load file using file reader function
loadFile(file);
}
function loadFile(file) {
// Create file reader and relevant Ace code
var reader = new FileReader();
reader.onload = function(e) {
// Get text contents of file
var data = e.target.result;
// Update Ace Editor with loaded data
editor.setValue(data, -1);
};
// Now that we defined the function we want to run, read the file
reader.readAsText(file);
}
setValue()
函数中的 -1 表示将光标放在文件的开头(顶部)- 1 表示底部。
有大量的事件和属性,您可以挂钩并弄乱,以便根据您的喜好调整此编辑器。它们都非常简单易用,因此如果您犹豫不决,值得花时间尝试一下。
我浪费了 2 天的时间试图让 clusterize + highlightjs 与我的设置一起工作,最终放弃并在不到一天的时间内用 Ace 替换了整个设置。到目前为止,编辑器给我留下了深刻的印象!
这是他们 "How-to Guide" 的 link:https://ace.c9.io/#nav=howto
以及他们的 API 参考资料(非常有用):https://ace.c9.io/#nav=api
目标:
优化需要在 textarea
或内容可编辑 div
中显示大量文本数据 (25mb+) 的网页,同时不会损失太多性能。
目前,在 Chrome 上加载一个 10mb 的文件大约需要 3 秒。我希望最长为 1 秒。
想法与尝试:
我正在使用 <input type="file">
从用户计算机加载本地文本文件,将大文件直接加载到内存中没有问题。但是,一旦我尝试在文本区域中显示此文本数据,我自然会 运行 遇到性能问题。
我禁用了拼写检查、自动大写和自动完成功能,这当然有帮助,但是我想尽量减少尝试渲染大文件(大于 10mb 的文件,最大 100mb 的文件)时的延迟量理想)。
<textarea autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">
我的一个想法是只渲染当前行之前的 100 行和之后的 100 行,当用户滚动 textarea 时,我会关闭正在显示的数据。我可以交换几百行而没有任何明显的延迟,但是数十万行会锁定整个页面。
我也在研究诸如 CodeMirror 之类的项目,它用于一些基于 javascript 的文本编辑器,以及 chrome 开发工具。然而,当最初加载大量文本时,快速测试显示了类似的性能问题。
另一个想法是使用 highlight.js 来呈现文本 dom 元素,但我在处理数千个 DOM 元素时也注意到大量的 large。
This site seems to tackle a similar example 通过动态创建和显示 dom 元素,而不是尝试一次渲染所有元素。
I have found that if the number of records in the grid becomes more then just a few thousands the grid gets very slow because the rendering speed is directly related to the number of nodes in the DOM. If the number of nodes in the DOM is more then 40-50k (depending on your computer configuration and amount of memory), your browser will crash or will become unresponsive.
So, I decided to set out on a quest to do two things: (1) dynamically create records as user scrolls (2) optimize grid to handle large data sets. After a few weeks of work, the grid was optimized and ready for testing.
我认为这与我的第一个想法相似,但我还没有尝试过这种方法。
我希望有过类似经历的人可以提供一些关于该走哪条路的建议,或者提供一些额外的想法。
在有人问之前,我不能不显示此数据,它需要用户可编辑,不需要突出显示代码或显示行号。最后,整个文本文件正在使用 FileReader 加载到变量中。
出于最终用户隐私和 NDA 考虑,我希望尽可能避免将文件上传到我的网络服务器。
服务器配置:Ubuntu 16.04 LAPP Stack with Laravel 5.4,但对 NodeJS 解决方案开放。允许使用 jQuery。
建议的解决方案:
Lazy Loading - 当用户滚动时,一次只显示 300 行“块”。在这种情况下,需要提前将滚动条设置为合适的高度。 - 此外,应该在用户滚动时卸载这些“块”以减少总的 DOM 渲染负载。
伪代码:
c_chunk = scrollpos / scrollheight * totalChunks;
chunk_block = chunk[c_chunk--] + chunk[c_chunk] + chunk[c_chunk++];
my_textarea.val(chunk_block);
对这个方法有什么想法吗?
谢谢大家
正如我所承诺的,这是我的解决方案:
所以在摸索了各种想法并尝试了不同的方法之后,我想我最终决定在我的项目中使用 Ace。我选择 Ace 有几个原因。
- 记录完备 API 除了相当大且活跃的社区外,它也很容易理解。
- 性能,与我使用大文件使用 Code Mirror 进行的测试相比,Ace 的性能无疑要好得多。 (500,000 行,github 表示 Ace 已通过多达 400 万 行的测试。
- 开箱即用的功能 Ace 有更多功能可以帮助您,运行 用户设置或配置很少。入门总共不到 10 行!
- 它不像Code Mirror那样支持那么多浏览器,但我的项目是运行 WebGL所以我不是很在意。
所以你明白我的推理,你想自己拿 A 和 运行?简单,只需跳到 build repo 并选择适合您需要的口味即可。我获取了 src-min 版本,因为我会将它添加到我的构建脚本中。
然后以任何方式包含 javascript 文件:
<script src="/ace/ace.js" type="text/javascript" charset="utf-8"></script>
还有一个元素到您的页面 id="editor"
。就我而言,我会将其直接附加到 div:
<div id="editor">Any text you want to have auto displayed</div>
并在 javascript 文件中:
var editor = ace.edit("editor");
editor.setTheme("ace/theme/chrome");
editor.session.setMode("ace/mode/javascript");
editor.$blockScrolling = Infinity;
如果你只是想四处看看languages/themes/options/etc。可用,只需前往 Ace's kitchen sink page 并与编辑器一起玩。
现在我还需要一些功能,例如能够将文件加载到文本区域中 - 您可以通过以下方式实现:
加载本地文件:
// Add event listener to the file input
// Note: This will not fire twice if the user opens File A, then re-opens file A
// To detect re-opening a file you will need to clear the input
// after the file is read so that it "changes" upon re-opening
document.getElementById('open-file').addEventListener('change', handleFileOpen, false);
// First we create the function handler that fires when our input is changed
function handleFileOpen(e) {
var file = e.target.files[0]; // Get first file selected
// Load file using file reader function
loadFile(file);
}
function loadFile(file) {
// Create file reader and relevant Ace code
var reader = new FileReader();
reader.onload = function(e) {
// Get text contents of file
var data = e.target.result;
// Update Ace Editor with loaded data
editor.setValue(data, -1);
};
// Now that we defined the function we want to run, read the file
reader.readAsText(file);
}
setValue()
函数中的 -1 表示将光标放在文件的开头(顶部)- 1 表示底部。
有大量的事件和属性,您可以挂钩并弄乱,以便根据您的喜好调整此编辑器。它们都非常简单易用,因此如果您犹豫不决,值得花时间尝试一下。
我浪费了 2 天的时间试图让 clusterize + highlightjs 与我的设置一起工作,最终放弃并在不到一天的时间内用 Ace 替换了整个设置。到目前为止,编辑器给我留下了深刻的印象!
这是他们 "How-to Guide" 的 link:https://ace.c9.io/#nav=howto
以及他们的 API 参考资料(非常有用):https://ace.c9.io/#nav=api