【问题标题】:Efficient scrolling of piped output in a browser window在浏览器窗口中有效滚动管道输出
【发布时间】:2012-02-03 21:13:53
【问题描述】:

我有一个自定义浏览器插件(使用 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 秒完成。那么,我该如何提高效率呢?有没有更好的方法将此文本通过管道传回浏览器?

【问题讨论】:

    标签: javascript npapi browser-plugin firebreath


    【解决方案1】:

    我认为有两种优化潜力:

    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次更新/秒

    【讨论】:

    • 这些似乎是一个合理的起点;但是,我怀疑问题更多在于跨进程通信。我会添加一些日志记录并进行一些分析,以查看大部分“滞后”发生在哪里。
    • 我在 C 端分块并缓存了 DOM 查找,现在更流畅了。
    猜你喜欢
    • 2018-11-29
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    相关资源
    最近更新 更多