所有
我的问题涉及网络应用程序的性能,主要是索引页面。当我在我的公司的一个本地分支机构进行演示时,我注意到了这个问题,因为谷歌需要大约10秒的加载速度来判断互联网速度缓慢(我不知道确切的速度或ping速率)。我的索引页面加载时间缩短了大约10-20倍。我假设我的应用程序完成了服务器端的大部分工作(因为php正在进行所有的数据库查询......)。但是这让我看看Chrome的网络工具,看看这些4个div的延迟时间是由ajax加载的(我稍后会详细说明)。有趣的是,被调用的脚本似乎按顺序运行,但不一定按照我调用ajax调用的顺序运行(有时它们会执行,有时则不会)。
以下是请求的代码段:
Yii::app()->clientScript->registerScript('leftDiv', '
$( "#left_dash" ).load(
"'.$this->createUrl("/site/page?view=leftDashLoad") .'",
function(){
$("#left_dash p a").click(function() {
$(this).parent().parent().find("div.scroll100").slideUp();
$(this).parent().next().stop(false, false).slideDown();
});
$("p:first-child").next().slideDown();
}
);
' );
这是请求的页面:
$this->widget('widgets.ScrollList',array(
'condition'=>
function($muddJob,$scrollList)
{
$job = $muddJob->Job;; //returns a job or empty array
if(!empty($job) )
{
if( $muddJob->uploadArtwork == null && $muddJob->uploadData == null ) {
array_push($scrollList->_models,$job);
$scrollList->columnValues = array($muddJob->jobDescription,$muddJob->dropDate1);
return true;
}
}
return false;
},
'columns' => array('col1'=>"MuddJob#",'col2'=>"Desc",'col3'=>"Dealer Name"),
'name'=> "Print New Ticket",
'muddJobs' => $currentExchanges->getCurrentMuddExchanges(),
)
);
想象一下该页面(ajax调用的页面)有6个类似的声明来创建小部件。目标是返回html以代替索引页面上的加载gif。
这是滚动小部件:
<?php
Yii::import('widgets.ScrollListBase');
include_once Yii::app()->extensionPath . "/BusinessDay.php";
class ScrollList extends ScrollListBase
{
private $_content;
public $columns = array();
public $columnValues;
private $_listInfo;
public $name;
public $_models = array();
public $condition;
public $muddJobs; //object to pass
public $jobsMailingTodayArray = array();
public function init()
{
//$this->init();
$this->_listInfo = $this->generateListInfo($this->columns);
//$muddJobs = $this->getCurrentMuddExchanges();
$listInfo = $this->newScrollList($this->muddJobs);
$contents = $this->createContent($listInfo,$this->name);
$this->_content = $contents[0];
// $this->_fullTableContent = $contents[1];
//$this->_listInfo = $contents[2];
}
public function run()
{
//if($this->data['isVisible'])
echo $this->_content;
Yii::app()->session["exploded_content_{$this->name}"] = $this->_models;
}
private function newScrollList($muddJobs)
{
$listInfo = $this->_listInfo;
$tempCount = 0;
foreach($muddJobs as $muddJob)
{
$condition = $this->condition;
if($condition($muddJob,$this) && empty($this->jobsMailingTodayArray) ) //if no job exists for the muddExchange...
{
$tempArray = $this->createWidgetLinks($tempCount,$listInfo,$muddJob,$this->columnValues);
$listInfo = $tempArray[0];
$tempCount = $tempArray[1];
}
elseif ( !empty($this->jobsMailingTodayArray ) )
{
foreach ($this->jobsMailingTodayArray as $jobMailingToday) //change to for loop over the length of the jobsMailingToday
{
$tempArray = $this->createWidgetLinks($tempCount,$listInfo,$muddJob,$this->columnValues);
$listInfo = $tempArray[0];
$tempCount = $tempArray[1];
}
$this->jobsMailingTodayArray = array();
}
}
return array($listInfo,$tempCount);
}
}
?>
这是它的父母:
<?php
class ScrollListBase extends CWidget
{
private $content = "<p>";
private $divDeclaration = "<div class='scroll100'>\n<table class='quickInfoTable'>\n<thead>\n";
private $headTag = "<th>";
private $headTagClose = "</th>\n";
private $theadTagClose = "</thead>\n";
private $bodyTag = "<tbody>\n";
private $listInfo = "<div class='scroll100'>\n<table class='quickInfoTable'>\n<thead>\n<th>Job#</th>\n<th>Package#</th>\n<th>Entry Date</th>\n</thead>\n<tbody>\n";
/**
* Initializes the widget.
*/
public function createContent($listInfo,$name)
{
$largeHref = Yii::app()->request->baseUrl . '/index.php/site/fullTableView';
$this->content .= "<span class='badge' >{$listInfo[1]} </span> <a href='#'>{$name} </a> <a href='$largeHref/Name/{$name}'> <small>(view larger)</small> </a> </p>";
if( $listInfo[1] > 0 )
{
// $this->fullTable .= substr($listInfo[0],22);
// $this->fullTableContent= $this->fullContent .= $this->fullTable . "</tbody>\n</table>\n</div>";
$this->content .= $listInfo[0] . "</tbody>\n</table>\n</div>";
}
return array($this->content);
}
//Helper Methods
/**
*
* @param type $attributeArray. send an accociative array
* @return type = either a job or an empty array
*/
protected function getJobByAttributes($attributeArray)
{
return Jobs::model()->with('MuddExchange')->findByAttributes($attributeArray);
}
protected function createWidgetLinks($tempCount,$listInfo,$muddJob,$columnValues,$url="/MuddExchange/")
{
$tempCount++;
$viewIndex = $muddJob->exchange_id;
$model = $muddJob;
$job = $muddJob->Job;
if ( isset($job ))
{
$model = $job;
$url = "/Jobs/";
$viewIndex = $model->job_id;
}
$link = CHtml::link("$model->jobNumber",array("{$url}{$viewIndex}"));
$listInfo .= "<tr>\n<td>$link</td>\n";
foreach ($columnValues as $columnValue)
{
$listInfo .= "<td>{$columnValue}</td>\n";
}
$listInfo .= "</tr>";
return array($listInfo,$tempCount);
}
protected function getListInfo()
{
return $this->listInfo;
}
/**
* Takes an array of strings to generate the column names for a particular list.
* @param array $heads
* @return string
*
*/
protected function generateListInfo($heads)
{
//<th>Job#</th>\n<th>Package#</th>\n<th>Entry Date</th>\n</thead>\n<tbody>\n";
$htmlScrollStart = $this->divDeclaration;
foreach ($heads as $tableColumn => $name)
{
$htmlScrollStart .= $this->headTag . $name . $this->headTagClose;
}
$htmlScrollStart .= $this->theadTagClose . $this->bodyTag;
return $htmlScrollStart;
}
public function calculateDueDate($jobsMailDate,$job)
{
$package = PackageSchedule::model()->findByAttributes(array('package_id'=>$job->packageID));
$projectedDays = $package->projected_days_before_mail_date;
$dropDate1 = $jobsMailDate->projected_mail_date;
$dropDate = wrapBusinessDay($dropDate1); //use this for actual command...
$toSec = 24*60*60;
$dayInt =0;
$secDropDate = strtotime($dropDate1);
do{
$dayInt +=1;
$daysInSec = ($dayInt) * $toSec ;
$secGuessDueDate = $secDropDate - $daysInSec;
$dueDate = date('Y-m-d',$secGuessDueDate);
$difference = $dropDate->difference($dueDate);
}while( $difference != $projectedDays);
return $dueDate;
}
}
?>
整个慢速互联网事物本身就是一头野兽,但我不认为这是在StackOverflow的范围内。我更担心这些div的加载。最后加载的div,即平均花费1.5到2秒,是对创建单个小部件的页面的ajax请求。背后的逻辑是:
<?php
include_once Yii::app()->extensionPath . "/CurrentExchanges.php";
$currentExchanges = Yii::app()->session['currentExchanges'];
$this->layout = 'barebones';
$this->widget('widgets.ScrollList',array(
'condition'=>
function($muddJob,$scrollList)
{
if ($muddJob->dropDate1 != null && $muddJob->dropDate1 != '0000-00-00')
{
$job = $muddJob->Job;;
if(!empty($job) && $job->packageID != null) //if job exists for the muddExchange and has a package
{
if($job->uploadArtwork == null )
{
$jobsMailDate = JobsMailDate::model()->findByAttributes(array("job_id"=>$job->job_id,'sequence_num'=>1));
if(!empty($jobsMailDate))
{
$calculatedDueDate = $scrollList->calculateDueDate($jobsMailDate,$job);
if (strtotime($calculatedDueDate) <= strtotime(date("Y-m-d")) )
{
array_push($scrollList->_models , $job);
$scrollList->columnValues = array($muddJob->jobDescription,$muddJob->dropDate1,$jobsMailDate->projected_mail_date);
return true;
}
}
}
}
}
return false;
},
'columns' => array('col1'=>"MuddJob#",'col2'=>"Desc",'col3'=>"Drop Date", 'col4' =>'Projected Drop Date'),
'name'=> "Artwork Due Today",
'muddJobs' => $currentExchanges->getCurrentMuddExchanges(),
)
);
?>
calculateduedate方法对服务器进行了2次额外调用。
我无法理解的是为什么左边的div(最需要处理的)通常是第一个返回的,而artLoad通常是最后一个加载(通过实质性差异)。以下是chromes网络工具返回的一些时间:
leftDashLoad: 475ms
rightDashLoad: 593ms
dataLoad: 825ms
artLoad: 1.41s
dataLoad: 453ms
rightDashLoad: 660ms
leftDashLoad: 919ms
artLoad: 1.51s
rightDashLoad: 559ms
leftDashLoad: 1.17s
dataLoad: 1.65s
artLoad: 2.01s
我无法理解为什么左/右仪表板的返回速度比artLoad快得多。除了实际比较(if if语句)之外,artLoad和dataLoad的代码几乎相同。如果这是真正的异步,我希望订单是art / dataLoad,rightDashLoad和leftDashLoad,完全基于每个页面中完成的计算量。也许服务器不是多线程,或者有一些奇怪的配置,但如果是这种情况,我不明白为什么加载的影响会被慢速互联网这么难打。 如果我忽略了一些显而易见的事情或未能恰当地使用谷歌,我会道歉。感谢您提供的任何帮助!
该应用程序是使用Yii框架开发的。 PHP 5.3。 Apache服务器。 INNODB表。服务器托管在dreamhost中。
我更改了视图页面,以便ajax调用现在调用控制器操作。它似乎使我的本地开发环境中的加载时间更加相似(异步?),但在QA环境(托管在dreamhost上...)上真的减慢了它的速度。以下是本地网络工具信息的屏幕截图:
和qa网站(注意,数据库具有大约相同数量的数据......)
思考?在我看来,我的原始问题可能会得到解决,因为返回时间(在我的本地开发站上)看起来更像我期望的那样。
另外,由于xdebug正在使用会话,我自己对NetBeans调试如何在这个同步加载事件中起作用的无知。我相信这迫使ajax呼叫等待轮到他们。
答案 0 :(得分:1)
感谢@Rowan帮助我诊断这种奇怪的行为。 PHP试图在会议结束前请求会话,以防止发生种族危害。我的代码中有会话请求,我的IDE(NetBeans)启动了一个会话。删除对ajax调用页面中的会话的所有引用,并使用使用renderPartial()的ajax调用操作证明返回预期的行为(以及更好的代码IMO)。让我知道如何在StackOverflow方面正确地感谢用户(我可以发表评论,还是有什么可用?)。谢谢你们!