1

我有一个自定义浏览器插件(使用 FireBreath 构建),它将调用用户机器上的本地进程并将标准输出通过管道传回浏览器,为此我正在通过 popen() 调用运行该进程,并且当我从中读取数据时我触发一个 JSAPI 事件并将其发送回浏览器的管道。

在浏览器中,我将输出作为预先格式化的文本附加到 div 并告诉 div 滚动到底部。

浏览器插件中的代码:

FILE* in;
if(!(in = _popen(command_string, "r")))
{
    return NULL;
}

while(fgets(buff, sizeof(buff), in)!=NULL)
{
    send_output_to_browser(buff);
}

HTML & Javascript/jQuery:

<pre id="sync_status_window" style="overflow:scroll">
    <span id="sync_output"></span>
</pre>


var onPluginTextReceived = function (text)
{
    $('#sync_output').append(text);   
    var objDiv = document.getElementById('sync_status_window');
    objDiv.scrollTop = objDiv.scrollHeight;
}

这种方法适用于我需要它的浏览器(这是一个有限使用的内部工具),但它令人沮丧地滞后。我的过程通常在输出窗口完成滚动前大约 30-60 秒完成。那么,我该如何提高效率呢?有没有更好的方法将此文本传送回浏览器?

4

1 回答 1

2

我认为有两种优化潜力:

  1. 保留对您的 pre 和 span 的引用,您不断重复 dom 树搜索,这非常昂贵
  2. 将输出分块 - 在 C 端(首选)或 JS 端。

对于快速破解(不删除对 j​​query 的依赖,应该这样做)可能看起来像

//Higher or global scope
var pluginBuffer=[];
var pluginTimeout=false;
var sync_status_window=document.getElementById('sync_status_window');

function onPluginTextReceived(text)
{
    pluginBuffer[pluginBuffer.length]=text;
    if (!pluginTimeout) pluginTimeout=window.SetTimeout('onPluginTimer();',333);
}

function onPluginTimer()
{
    var txt=pluginBuffer.join('');
    pluginBuffer=[];
    pluginTimeout=false;
    $('#sync_output').append(text);
    sync_status_window.scrollTop = sync_status_window.scrollHeight;
 }

适应你的需求,我选择333ms 3次更新/秒

于 2012-02-03T21:37:20.723 回答