Javascript 非常慢的JS脚本:我做错了什么,或者如何加速?

Javascript 非常慢的JS脚本:我做错了什么,或者如何加速?,javascript,performance,Javascript,Performance,我必须在不修改html的情况下突出显示div[contenteditable=true]中的一些单词,因此我复制div并将副本放在原始文本的正后方,然后在需要突出显示的单词周围应用一些跨度 原始div可以随时修改其类/属性,因此我希望通过任何css更改保持副本的更新,为此,我有一个函数,每次调用highlighting函数时都会调用该函数 我的问题是,这个函数执行起来需要很多时间,大约60毫秒,而我脚本的其余部分大约需要1-4毫秒 我在这里做错了什么,或者我该如何加快速度 function po

我必须在不修改html的情况下突出显示div[contenteditable=true]中的一些单词,因此我复制div并将副本放在原始文本的正后方,然后在需要突出显示的单词周围应用一些跨度

原始div可以随时修改其类/属性,因此我希望通过任何css更改保持副本的更新,为此,我有一个函数,每次调用highlighting函数时都会调用该函数

我的问题是,这个函数执行起来需要很多时间,大约60毫秒,而我脚本的其余部分大约需要1-4毫秒

我在这里做错了什么,或者我该如何加快速度

function positionOutputWindow(original,copy)
{
    //console.log("positionOutputWindow");
    //var start = new Date().getTime();
    if ( 
        !original ||
        !copy ||
        original.attr('id') == undefined || 
        copy.attr('id') == undefined
        ) { return; }

    var original_obj = original.get(0);
    var copy_obj = copy.get(0);
    var offset = original.offset();

    copy.offset(offset);
    copy.css({
        'position': 'absolute',
        'z-index': '2',
        'color': 'transparent',
        'flood-color': 'transparent',
        '-webkit-text-fill-color': 'transparent',
        //'overflow': 'hidden',
        'outline': 'solid 0px red'/*,
        'width': original.width() + 'px',
        'height': original.height() + 'px'*/
    });
    copy.css("background",original.css("background"));
    original.css({
        //'overflow': 'hidden',
        'background': 'transparent',
        'position': 'relative',
        'z-index': '3',
        'outline': 'solid 0px green'
    });
    copy.width(original.width());
    copy.height(original.height());

    if ( original.get(0).nodeName == "INPUT" || original.get(0).nodeName == "TEXTAREA" )
    { 
        copy.width(original_obj.scrollWidth); 
        copy.offset({ top: offset.top, left: offset.left - original_obj.scrollLeft });
    }

    copy.offset({ top: offset.top, left: offset.left });
    copy.find('*').css('color','transparent');
    //console.log("runtime position window " + (new Date().getTime() - start));
}

首先,您应该仔细阅读回流焊:

我在这个函数中看到很多DOM操作。多次调用
offset
css
width
height
。如果您想提高性能,请尝试将所有这些功能组合到一个调用中

第二,这句话非常突出:

copy.find('*').css('color','transparent');
这可能包含相当数量的元素。您要求javascript查找每一个,并在用户每次点击一个键时应用透明颜色。肯定有更好的办法吗?更不用说透明度可能相当占用CPU


最后,为什么每次键入时都需要调用此函数?真的有必要吗?你想达到什么目的?

首先,你应该阅读回流焊:

我在这个函数中看到很多DOM操作。多次调用
offset
css
width
height
。如果您想提高性能,请尝试将所有这些功能组合到一个调用中

第二,这句话非常突出:

copy.find('*').css('color','transparent');
这可能包含相当数量的元素。您要求javascript查找每一个,并在用户每次点击一个键时应用透明颜色。肯定有更好的办法吗?更不用说透明度可能相当占用CPU


最后,为什么每次键入时都需要调用此函数?真的有必要吗?您试图实现什么?

性能是否导致问题?如果没有,那么您可能需要在需要之前进行优化。更值得一提的是,确保函数正确且可维护。尝试将css放入类中,只需交换类名,而不是像现在这样设置每个css属性。css似乎会导致最严重的减速。我的诊断是:jQuery太多了。每次有人键入时,你都要执行所有这些操作?60毫秒意味着你每秒可以完全执行脚本16次。这真的有必要吗?如果是这样的话,那么要意识到每次调用更改DOM都是昂贵的——即使是一个大的“用这个替换整个div”命令,也最好只做一次更改。因此,如果您必须进行优化,可以通过计算最终div将包含哪些内容来替换功能,然后一次性替换HTML,而不是一次替换一个div。重画/回流往往成本高昂。性能是否造成问题?如果没有,那么您可能需要在需要之前进行优化。更值得一提的是,确保函数正确且可维护。尝试将css放入类中,只需交换类名,而不是像现在这样设置每个css属性。css似乎会导致最严重的减速。我的诊断是:jQuery太多了。每次有人键入时,你都要执行所有这些操作?60毫秒意味着你每秒可以完全执行脚本16次。这真的有必要吗?如果是这样的话,那么要意识到每次调用更改DOM都是昂贵的——即使是一个大的“用这个替换整个div”命令,也最好只做一次更改。因此,如果您必须进行优化,可以通过计算最终div将包含哪些内容来替换功能,然后一次性替换HTML,而不是一次替换一个div。重画/回流往往代价高昂。在测试每行代码的时间后,结果是.offset命令以及宽度和高度比其他命令花费的时间要多得多,其他命令总共需要大约0-1毫秒。。。而且,执行第一个命令只需花费大量时间。这可能是因为我没有缓存DOM对象,并且每次调用我的positionOutputWindow之前都会查找它,因此JS第一次尝试访问它的属性时会花费比平常更长的时间吗?@nucka不,这不是缓存。事实上,调用这些函数会导致浏览器重新绘制(即重新渲染整个屏幕)。因为您多次调用它们,所以您强制浏览器在同一个函数调用中多次重新计算其整个布局。好的,所以如果我想避免这种情况,我应该避免调用这些函数(我可以对其中一些函数执行此操作,但不能对所有函数执行此操作)?或者有没有办法告诉浏览器在我的函数完成它的工作之前不要重画页面,这样它只会重画一次?感谢您帮助我理解在测试了每行代码的时间之后,结果是.offset命令以及宽度和高度比其他命令花费的时间要多得多,其他命令总共需要大约0-1毫秒。。。而且,执行第一个命令只需花费大量时间。这可能是因为我没有缓存DOM对象,并且每次调用我的positionOutputWindow之前都会查找它,因此JS第一次尝试访问它的属性时会花费比平常更长的时间吗?@nucka不,这不是缓存。事实上,调用这些函数会导致浏览器重新绘制(即重新渲染整个屏幕)。由于您多次调用它们,因此您强制浏览器重新计算其整个布局multip