Js (+ Mootools) - Почему мой скрипт использует более 60% процессора? - PullRequest
1 голос
/ 02 апреля 2010

На этом сайте - ССЫЛКА - мне нужно использовать 3 скроллера баннера (2x вертикальный + 1x горизонтальный) Я пытался сделать это во флэш-памяти, но затем все веб-браузеры закрылись или приостановились. Теперь я хочу сделать это в JS (я использую mootools). Все данные взяты из MySQL. Вот полный код (даже если вы не знаете mootools, вы должны это понимать)

global $wpdb;
$table = $wpdb->prefix.'part';
$sql = "SELECT * FROM $table";
$q = $wpdb->get_results($sql);
$g = 0;
if($wpdb->num_rows > 0)
{
?>
<script type="text/javascript">
window.addEvent('load', function(){
    var totall = 0;
    var totalr = 0;
    $$('#leftCont0 .contElement').each(function(el){
        var img = new Asset.image(el.getFirst('a').getFirst('img').get('src'));
        totall += img.height;
    });
    $$('#rightCont0 .contElement').each(function(el){
        var img = new Asset.image(el.getFirst('a').getFirst('img').get('src'));
        totalr += img.height;
    });

    $$('.leftCont').each(function(el){
        var h = parseInt(el.get('id').substr(8));
        el.setStyle('top', h * totall);
    });
    $$('.rightCont').each(function(el){
        var h = parseInt(el.get('id').substr(9));
        el.setStyle('top', h * totalr);
    });
    var total = new Array(totall, totalr);
    move.periodical(30, null, total);
});
function move(num, num2)
{
    var h = 0;
    var da = false;
    var target = null;
    $$('.leftCont').each(function(el){
        var act = el.getStyle('top');
        var n = parseInt(act)+1;
        el.setStyle('top', n+"px");
        if(el.getStyle('top') < h)
        {
            h = parseInt(el.getStyle('top'));
            alert(h);
        }
        if(parseInt(el.getStyle('top')) > 400)
        {
            da = true;
            target = el;
        }
    });
    if(da)
    {
        var n = h - num;
        target.setStyle('top', n+'px');
    }
    h = 0;
    da = false;
    $$('.rightCont').each(function(el){
        var act = el.getStyle('top');
        var n = parseInt(act)+1;
        el.setStyle('top', n+"px");
        if(el.getStyle('top') < h)
        {
            h = parseInt(el.getStyle('top'));
            alert(h);
        }
        if(parseInt(el.getStyle('top')) > 400)
        {
            da = true;
            target = el;
        }
    });
    if(da)
    {
        var n = h - num2;
        target.setStyle('top', n+'px');
    }
}
</script>
<?php 
$g = 0;
$l = 0;
$r = 0;
$leftContent = array();
$rightContent = array();
$leftHeight = 0;
$rightHeight = 0;
foreach($q as $q)
{
    if(($g % 2) == 0)
    {
        $leftContent[$l] = '<div class="contElement">
                <a href="'.$q->aurl.'"><img src="'.$q->imgurl.'" alt="Partner" /></a>
            </div>';
        $lHeight = getimagesize($q->imgurl);
        $leftHeight .= $lHeight[1];
        $l++;
    }
    else
    {
        $rightContent[$r] = '<div class="contElement">
                <a href="'.$q->aurl.'"><img src="'.$q->imgurl.'" alt="Partner" /></a>
            </div>';
        $rHeight = getimagesize($q->imgurl);
        $rightHeight .= $rHeight[1];
        $r++;
    }
    $g++;
}
$quantity = ceil(400 / $leftHeight) + 1;

for($i = 0; $i < $quantity; $i++)
{
    $str = "";
    for($j = 0; $j < sizeof($leftContent); $j++)
    {
        $str .= $leftContent[$j];
    }
    $leftContainer[$i] = '<div class="leftCont" id="leftCont'.$i.'">'.$str.'</div>';
}

$quantity = ceil(400 / $rightHeight) + 1;

for($i = 0; $i < $quantity; $i++)
{
    $str = "";
    for($j = 0; $j < sizeof($rightContent); $j++)
    {
        $str .= $rightContent[$j];
    }
    $rightContainer[$i] = '<div class="rightCont" id="rightCont'.$i.'">'.$str.'</div>';
}

?>
<div id="pcl">
<?php
for($i = 0; $i < sizeof($leftContainer); $i++)
{
    echo $leftContainer[$i];
}
?>
</div>
<div id="pcr">
<?php
for($i = 0; $i < sizeof($rightContainer); $i++)
{
    echo $rightContainer[$i];
}
?>  
</div>
<?php
}

Ответы [ 2 ]

1 голос
/ 04 апреля 2010
Например,

в вашей функции перемещения может быть сделано несколько изменений, которые улучшат ситуацию.

first, $$('.rightCont') и $$('.leftCont') - селекторы, которые пересекают dom каждый раз, когда вы вызываете функцию. если вы не ожидаете изменения элементов массива, почему бы не кэшировать их в глобальные переменные, например:

var conts = {
    left: $$("div.rightCont"),
    right: $$("div.leftCont")
};

// then just refer to them within function move like so...
conts.left.each(...); // etc.

когда вы устанавливаете размерыStyle в модуле mootools по умолчанию px, в любом случае нет смысла объединять top (int) и строку «px», esp IE может замедляться, так как строки неизменяемы ...

также, если вы делаете что-то вроде el.setStyle('top', n), тогда вы можете предположить, что el.style.top будет n, а дальше вы делаете if(el.getStyle('top') < h) и if(parseInt(el.getStyle('top')) > 400), два бессмысленных поиска.

Вы действительно можете ускорить это, выполнив один цикл для обоих типов элементов, я считаю ... в любом случае, гл.

с использованием el.getPosition().y прибудет уже как int, так что вам не нужен parseInt (не нужно много экономить на этом процессоре, так как фреймворк, вероятно, делает то же самое). Кроме того, когда вам нужен parseInt, используйте mootools 'number.toInt() вместо этого, он может быть

1 голос
/ 02 апреля 2010

Ваша функция move() с двумя циклами each() требует выполнения каждые 30 миллисекунд. Поскольку все ваши элементы прокрутки движутся с одинаковой скоростью / не относительно друг друга, вы можете просто анимировать их корневой контейнер. Я уверен, что это даст вам 10-кратное повышение.

Чтобы узнать, что именно потребляет циклы процессора, используйте javascript profiler , предоставляемый браузерами. У Safari есть хороший, Firebug тоже.

...