YUI, Javascript: Как я могу оптимизировать этот фрагмент кода, чтобы он работал быстрее? - PullRequest
0 голосов
/ 11 февраля 2011

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

http://adiinviter.com/forums/stack/current.php

Фрагмент кода в файле:

<html>
<head>
<style type="text/css">
.table_head_outer {
  background-color: #7192a8;
  padding: 0px;
    width:100%;

  font-weight:bold;
  color:#ffffff;
  clear:both;
  border: 1px solid #5a7f97;
  -moz-border-radius-topright: 5px;
  -moz-border-radius-topleft: 5px;
  -webkit-border-top-right-radius: 5px;
  -webkit-border-top-left-radius: 5px;

}

.table_head_body {
  padding: 3px 0px 3px 0px;
  background: transparent;
  text-align:left;
  margin-left: 13px;
  margin-right: 3px;
}

.table_body_outer {
  border-top: 1px solid rgb(255, 255, 255);
  background-color: rgb(255, 255, 255);
    width:100%;
  display:block;
  border-bottom: 1px solid #c4c4c4;
  border-left: 1px solid #c4c4c4;
  border-right: 1px solid #c4c4c4;
}


.table_body {
  padding: 5px;
  background: transparent;
}
.overlayDiv {
    position: absolute; width: 100%; height: 100%; left: 0px;
    background-color: rgba(10, 10, 10, 0.3);    
    font-family: Verdana; z-index: 2000;

}
.popup_box {
    position: relative; opacity: 1;
    background-color: transparent;
    border-width: 0px;  border-style: solid;    border-color: #C1B4B4;
    border-radius: 5px; -moz-border-radius: 5px;    -webkit-border-radius: 5px;
    width: auto;  height: auto; text-align: center;
}
#optContain {   width: 890px; }
#contentBox {
    text-align: center; vertical-align: middle; 
}

#sectionHeader {    text-align: left; padding: 5px; }
#sectionHeaderRight { padding:5px; text-align: right; }

.sectionFooter { padding: 5px 15px; text-align: right;}

.product_disp, .product_disp_clicked, .product_disp_hover {
    padding: 6px;   width: 250px; height: 50px;
    margin: 5px;    float: left;    overflow: auto; cursor: pointer;
    border-width: 1px;  border-style: solid;    
    border-radius: 5px; -moz-border-radius: 5px;    -webkit-border-radius: 5px;
}
.product_disp_clicked {
    border-color: #700;
    background-color: #e00;
}
.product_disp_hover {
    border-color: #aaa;
}
.div_trail_img {
    position: absolute; z-index: 2030; visibility: hidden;
    border-width: 1px;  border-style: solid;    border-color: #ccc;
    padding: 5px;   background-color: #fff;
    border-radius: 5px;-moz-border-radius: 5px;-webkit-border-radius: 5px;
}

.prodcuts_img { float:left; 
    margin-right: 5px; 
    height:50px; width:auto;
 }
    </style>
    <script type="text/javascript">
    function adi_onArrive(obj)
    {
        setTimeout(function () { 
                if(obj['data'] != null) 
                    document.getElementById(obj['id']).innerHTML += obj['data'];      
                }, 0);
    }
    function putDimensions()
    {

        document.myForm.sHeight.value = window.screen.height;
        document.myForm.sWidth.value = window.screen.width;
    }
    </script>
</head>
<body>

<div id="trail_img_div" class="div_trail_img" style="">
<img id="trail_img" src=""/>
</div>

<?php


if($_GET['num_products'] == "" && $_GET['get_products'] == "")
{
    ?>

    <center>
    <form action="" method="" onSubmit="return putDimensions();" name="myForm">
    No. of Items : &nbsp;&nbsp;&nbsp;&nbsp;<input type="textbox" name="num_products" > <br /><br />
    <input type="hidden" name="sHeight" value="">
    <input type="hidden" name="sWidth" value="">
    <input type="submit" name="get_products" value=" Get Products "> 

    </form>
    </center>
<?php 
}
else
{

    ?>
    <script type="text/javascript">
    //trail_img_div
    //trail_img
    function click_effect(myObj,event) // onclick
    {
        if(myObj.className == "product_disp_clicked")
        {
            myObj.className = "product_disp";
        }
        else if(myObj.className == "product_disp_hover")
        {
            myObj.className = "product_disp_clicked";
        }
        return true;
    }
    function show_img_trail(img_url,myObj) //on mousemove to div
    {
        if(myObj.className == 'product_disp') myObj.className = 'product_disp_hover';
        document.getElementById('trail_img').src = img_url;
        document.getElementById('trail_img_div').style.visibility = 'visible';
        document.getElementById('trail_name').innerHTML = 'Name : '+myObj.getAttribute('tip');
    }
    function hide_img_trail(myObj) //onmouseout
    {
        trail_img_div = document.getElementById('trail_img_div');
        trail_img_div.style.visibility = 'hidden';
        //trail_img_div.setStyle('visibility','hidden');
        if(myObj.className == 'product_disp_hover') myObj.className = 'product_disp';
    }
    function m_move(myObj)
    {
        if(myObj.className == 'product_disp') myObj.className = 'product_disp_hover';
    }
    function m_out(myObj)
    {
        if(myObj.className == 'product_disp_hover') myObj.className = 'product_disp';
    }
    function update_co_ords(event) // onmousemove to td
    {
        trail_img_div = document.getElementById('trail_img_div');
        if(event.pageX !=  undefined){
            trail_img_div.style.left = (event.pageX + 10)+ 'px';
            trail_img_div.style.top = (event.pageY + 10)+ 'px';
        }
        else{
            trail_img_div.style.left = (event.clientX + 10)+ 'px';
            trail_img_div.style.top = (event.clientY + 10)+ 'px';
        }
    }
    function toggle_all(event)
    {
        conts_container = document.getElementById('conts_contain');
        divArr = conts_container.querySelectorAll('div.product_disp');
        if(divArr.length ==  0) //uncheck all
        {
            divArr = conts_container.querySelectorAll('div.product_disp_clicked');
            for(i=0; i<divArr.length ; i++)
            {
                divArr[i].className = 'product_disp';
            }
        }
        else // check all
        {
            for(i=0; i<divArr.length ; i++)
            {
                divArr[i].className = 'product_disp_clicked';
            }
        }
        return false;
    }
    </script>

<table class="overlayDiv" id="popupBox">

<tr>
<td align="center" align="center" valign="middle" style="text-align:center;vertical-align:middle;padding: 10px;">
<center>
<div class="popup_box" align="center">
    <center>
    <table style="width: 870px; border: 1px solid #333;" class="" id="optContain">
    <tr class="">
        <td align="left">
            <div class="table_head_outer" style="position:relative;">
            <div class="table_head_body" id="sectionHeader"> Product Details </div> 
            </div>
        </td>
    </tr>
    <tr>
        <td align="center" class="table_body_outer" style="font-size: 10pt;text-align: center; vertical-align: middle; height: 500px;" id="contentBox">     
        <div style="padding: 10px;"> <a href="" onclick="return toggle_all(event);"> Select All </a> </div>
        <div style="height: 500px;overflow: auto;"  id="conts_contain" onmousemove="return update_co_ords(event);">

        </div>
        </td>
    </tr>
    <tr>
        <td id="sectionFooter" align="right" style="background-color:#fff;">
            <div align="center" style="margin: 5px 15px;">
                <input type="button" class="button" name="struct_close" id="close_popup" value=" Add Now ">
            </div>
        </td>
    </tr>
    </table>
    </center>
</div></center>
</td></tr>
</table>

<?php 

//   Code to caculate height and width

    $width = $_GET['sWidth'];
    $height = $_GET['sHeight'];
    $sss = intval(($width - 130) / 260);
    $sss = $sss * 260;
    echo '<script type="text/javascript">
    conts_container = document.getElementById("conts_contain");
    conts_container.style.width = "'.($sss + 120).'px";
    document.getElementById("contentBox").style.width = "'.($sss + 150).'px";
    conts_container.style.maxHeight = "'.($height - 150).'px";
    </script>
    ';

    flush();



    //   Code to Add items in contentBox

    $arr = array('name' => 'Product_', 'id' => 10);
    $status = 'Available';

    for($i = 1; $i <= $_GET['num_products'] ; $i++)
    {
        $someVar .= '<div class="product_disp" 
            onclick="return click_effect(this,event);"  
            onmousemove="return show_img_trail(\'pic.jpg\',this);"      
            onmouseout="return hide_img_trail(this);" align="left" >    <img src="pic.jpg" class="prodcuts_img"/>   
            <span style="overflow:hidden;" align="left"> <b> product_'.$i.' </b>    <br/>
            id : '.rand(0,10000).' <br /></span>
            <span style="padding:0px;width: 100%;" align="right">'.$status.' </span>
            </div>';        
            if($i % 100 == 0)
            {
                $output = array('id' => 'conts_contain', 'data' => $someVar);
                echo '<script type="text/javascript"> adi_onArrive('.json_encode($output).'); </script>';
                $someVar = '';
            }
    }
    if($someVar != '')
    {
        $output = array('id' => 'conts_contain', 'data' => $someVar);
                echo '<script type="text/javascript"> adi_onArrive('.json_encode($output).'); </script>';
                $someVar = '';
    }

}

?>
</body>
</html>

Поток: Файл PHP сначала отображает пустую структуру и освобождает выходной буфер. Это будет отображать структура без элементов в браузере клиента, быстро. Затем файл PHP отправляет некоторые Javascript Funciton призывает добавить элементы в поле (300 за раз.).

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

  1. Медленная прокрутка: когда в ящик загружаются тысячи предметов, прокрутка становится очень и очень медленной страница. Я хочу знать, есть ли какие-либо оптимизации / изменения кода или любые другие параллельные методы для решить эту проблему.

  2. Автоматическое изменение размера всплывающего окна контейнера, чтобы лучше соответствовать переменным размерам экрана, оставляя определенные отступы со всех сторон. Я надеюсь, что это лучше всего сделать в YUI. Вот как я рассчитываю и изменяю размер окна в настоящее время

            $width = $_GET['sWidth'];  
            $height = $_GET['sHeight'];  
            $sss = intval(($width - 130) / 260); // 260 is the width of one item including paddings  
            $sss = $sss * 260;   
            echo '<script type="text/javascript">  
                conts_container = document.getElementById("conts_contain");  
                conts_container.style.width = "'.($sss + 120).'px";  
                document.getElementById("contentBox").style.width = "'.($sss + 150).'px";  
                conts_container.style.maxHeight = "'.($height - 150).'px";  
                </script>';   
    
  3. Выбрать все работает вполне. Есть ли какой-либо другой превосходный способ ускорить это, используя YUI? вот как это работает в данный момент:

            function toggle_all(event)  
            {  
                conts_container = document.getElementById('conts_contain');  
                divArr = conts_container.querySelectorAll('div.product_disp');  
                if(divArr.length ==  0) //uncheck all  
                {  
                    divArr = conts_container.querySelectorAll('div.product_disp_clicked');  
                    for(i=0; i<divArr.length ; i++)  
                    {  
                        divArr[i].className = 'product_disp';  
                    }  
                }  
                else // check all  
                {  
                    for(i=0; i<divArr.length ; i++)  
                    {  
                        divArr[i].className = 'product_disp_clicked';  
                    }  
                }  
                return false;  
            }  
    

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

1 Ответ

0 голосов
/ 11 февраля 2011

С очень большими таблицами вы увидите огромное улучшение производительности рендеринга, установив table-layout:fixed в CSS.Это отключает алгоритмы изменения размера столбцов, которые учитывают ширину каждой отдельной ячейки в таблице при определении ширины столбцов.Побочным эффектом является то, что вам нужно правильно установить ширину, используя col элементы в верхней части таблицы (в противном случае первая строка контролирует ширину столбцов).

...