【问题标题】:Laravel pass big data through a view, load time slowLaravel 通过视图传递大数据,加载时间慢
【发布时间】:2019-09-27 08:39:31
【问题描述】:

我需要通过 Laravel 中的视图传递相当多的数据,而且看起来很漂亮,有人可以建议改进此代码/通过视图传递大量数据的正确方法吗?

从我的电脑上加载这个页面非常慢,在实时系统中一旦在服务器上似乎需要更少的时间,但我认为还不够快。

我看到有这个依赖项应该有助于实时系统composer install --optimize-autoloader --no-dev,但我还没有安装它,这将有助于我的速度,因为我有很多类要初始化?

它获取每个城市的连接的第一段代码,我们使用的是多模式 PostgreSQL 数据库,因此对于每个 URL/city1 URL/city2 等,它需要找到从哪个数据库获取数据。

/**
 * Create objects that we will need to query
 */

$this->Response = new Response;
$this->Response->initialize($connection);
$this->Responder = new Responder;
$this->Responder->initialize($connection);
$this->Interests = new lutInterest;
$this->Interests->initialize($connection);
$this->Issue = new lutIssue;
$this->Issue->initialize($connection);
$this->Time = new lutTime;
$this->Time->initialize($connection);

然后我需要检查schemeid 参数是否存在及其值,然后从数据库运行相关查询

/**
 * check the schemeid paramenter
 * Do the queries
 */
if ($_GET['schemeid'] == 0)
{
    $totalIssues = $this->Response->orderby('issueid')->groupby('issueid')->select('issueid', DB::raw('count(*) as total'))->get();
    $totalTimes = $this->Response->orderby('timeid')->groupby('timeid')->select('timeid', DB::raw('count(*) as total'))->get();
    $totalParticipants = DB::connection($connection)->table('responder_interests')->groupby('interestid')->orderby('interestid')->select('interestid', DB::raw('count(*) as total'))->get();
    $totalResponses = $this->Response->select(DB::raw('count(responseid) as total'),DB::raw("EXTRACT('year' FROM created_at) as year,EXTRACT('month' FROM created_at) as month"))->groupby('year','month')->orderby('year','asc')->orderBy('month','asc')->get();
    $totalRespArray = $this->Response->select(DB::raw('count(*) as total'))->get();
    $totalresponders = $this->$responders->count();
}
else
{
    $responders = $this->Response->where('scheme_id',$_GET['schemeid'])->groupby('responderid')->orderby('responderid')->select('responderid')->get();
    $respondersIDs = $responders->map(function ($data) { return $data->responderid; });

    $totalIssues = $this->Response->orderby('issueid')->groupby('issueid')->where('scheme_id', $_GET['schemeid'])->select('issueid', DB::raw('count(*) as total'))->get();
    $totalTimes = $this->Response->orderby('timeid')->groupby('timeid')->where('scheme_id', $_GET['schemeid'])->select('timeid', DB::raw('count(*) as total'))->get();
    $totalParticipants = DB::connection($connection)->table('responder_interests')->groupby('interestid')->orderby('interestid')->wherein('responderid',$respondersIDs)->select('interestid', DB::raw('count(*) as total'))->get();
    $totalResponses = $this->Response->where('scheme_id',$_GET['schemeid'])->select(DB::raw('count(responseid) as total'),DB::raw("EXTRACT('year' FROM created_at) as year,EXTRACT('month' FROM created_at) as month"))->groupby('year','month')->orderby('year','asc')->orderBy('month','asc')->get();
    $totalRespArray = $this->Response->where('scheme_id',$_GET['schemeid'])->select(DB::raw('count(*) as total'))->get();
    $totalresponders = $responders->count();
}

最后运行几个函数来正确格式化数据并能够正确显示在图表中。

/**
 * Convert issue data
 */
$categoryData = $totalIssues->map(function ($data) { return $data->total; });
$categoryLabels = $totalIssues->map(function ($data) { return $this->Issue->where('issueid',$data->issueid)->first()->shortdesc; });
$categoryBorder = $totalIssues->map(function ($data) { return $this->Issue->where('issueid',$data->issueid)->first()->color; });
$categoryColors = $categoryBorder->map(function ($data) { return implode('', [str_replace('rgb', 'rgba' ,explode(" ", $data)[0]),explode(" ", $data)[1], str_replace(')', ',0.2)' ,explode(" ", $data)[2])] );});
$categoryColorsHover = $categoryBorder->map(function ($data) { return implode('', [str_replace('rgb', 'rgba' ,explode(" ", $data)[0]),explode(" ", $data)[1], str_replace(')', ',0.5)' ,explode(" ", $data)[2])] );});

/**
 * Convert time data
 */
$timeData = $totalTimes->map(function ($data) { return $data->total; });
$timeLabels = $totalTimes->map(function ($data) { return $this->Time->where('timeid',$data->timeid)->first()->shortdesc; });
$timeBorder = $totalTimes->map(function ($data) { return $this->Time->where('timeid',$data->timeid)->first()->color; });
$timeColors = $timeBorder->map(function ($data) { return implode('', [str_replace('rgb', 'rgba' ,explode(" ", $data)[0]),explode(" ", $data)[1], str_replace(')', ',0.2)' ,explode(" ", $data)[2])] );});
$timeColorsHOver = $timeBorder->map(function ($data) { return implode('', [str_replace('rgb', 'rgba' ,explode(" ", $data)[0]),explode(" ", $data)[1], str_replace(')', ',0.5)' ,explode(" ", $data)[2])] );});

/**
 * Convert the interests data
 */
$participantData = $totalParticipants->map(function ($data) { return $data->total; });
$participantLabels = $totalParticipants->map(function ($data) { return $this->Interests->where('interestid',$data->interestid)->first()->shortdesc; });
$participantBorder = $totalParticipants->map(function ($data) { return $this->Interests->where('interestid',$data->interestid)->first()->color; });
$participantColors = $participantBorder->map(function ($data) { return implode('', [str_replace('rgb', 'rgba' ,explode(" ", $data)[0]),explode(" ", $data)[1], str_replace(')', ',0.2)' ,explode(" ", $data)[2])] );});
$participantColorsHover = $participantBorder->map(function ($data) { return implode('', [str_replace('rgb', 'rgba' ,explode(" ", $data)[0]),explode(" ", $data)[1], str_replace(')', ',0.5)' ,explode(" ", $data)[2])] );});

/**
 * Convert the responses data
 */
$responseData = $totalResponses->map(function ($data) { return $data->total; });
$responseLabels = $totalResponses->map(function ($data) { return date("M", mktime(0, 0, 0, $data->month,1)).' | '.substr($data->year,2); });

/**
 * Convert the total amount of responses data
 */
$totalResp = $totalRespArray->map(function ($data) { return $data->total; });

/**
 * send the issues and times for the popup
 */

$lutissue = $this->Issue->select('issueid', 'description')->orderby('sort')->get();
$luttime = $this->Time->select('timeid', 'description')->orderby('sort')->get();

将所有内容传递到视图中

return view('dasboard')->with(compact('title', 'schemeDocuments', 'schemes',
                'categoryData', 'categoryLabels', 'categoryBorder', 'categoryColors', 'categoryColorsHover','timeData', 'timeLabels',
                'timeBorder', 'timeColors', 'timeColorsHOver', 'participantData', 'participantLabels', 'participantBorder', 'participantColors',
                'participantColorsHover', 'responseData','responseLabels','totalResp', 'lutissue', 'luttime', 'totalresponders'));

【问题讨论】:

  • 你传递了多少数据,需要多长时间? Chrome DevTools 中的网络标签会告诉你类似 3.0 MB 在 2.4 秒内传输
  • 50KB 在 6 秒内,而在实时系统中需要 600 毫秒,但似乎需要几秒钟才能加载页面,是点击进入页面和第一次之间的延迟加载缓慢
  • 你试过用ajax了吗
  • 您没有将数据传递给视图。您没有返回视图(即return view(...))。您正在做的是将用户重定向到另一条路线,将数据通过用户会话传递到您的另一条路线。根据您的会话存储,这当然可能非常慢。但是您应该花一些时间来找出花费在此操作上的时间最多的地方,由于到数据库的大量往返,我预计 SQL 查询。
  • 看看 TTFB,如果它需要很多时间,请尝试找出导致它的原因:从 DB 获取数据或视图渲染。以 microtime() 为例。玩数据缓存,甚至缓存渲染视图(如果合适)

标签: laravel eloquent multi-database


【解决方案1】:

50 KB 的数据(如评论中所述)非常少,因此在您的情况下,将数据从服务器传输到客户端并不是瓶颈。您的数据并不像您的问题标题所暗示的那样“大”。

我会将这段代码放在app\Providers\AppServiceProvider.phpboot 方法中。然后每个数据库查询所花费的时间将记录在storage\logs

\DB::listen(function ($query) {
    \Log::info($query->time . ' milliseconds for ' . $query->sql);
});

您还可以计算并记录任意代码段的执行时间:

$start = microtime(true);

// This may be anything between a single line of code and your whole script

\Log::info(microtime(true) - $start); // This is in seconds

找出需要这么长时间的原因,然后尝试优化查询(或其他代码)。

您还询问是否有替代使用 AJAX 在加载数据之前呈现 HTML 的方法。我强烈建议您学习如何使用 AJAX 来做到这一点,但我也认为在您的情况下,可能有一些方法可以加快您的查询速度,以便您可以简单地等待数据并在单个请求中加载所有内容。

您的代码相当复杂,我建议您考虑将其拆分为更小的函数并使用更多的 cmets,但这不会让您的代码运行得更快。

【讨论】:

  • 我知道如何使用 AJAX,但在这个项目中我不想使用它,因为仪表板非常静态,没有交互,所以一旦我将所有内容传递进去,数据就不会改变,并不是真的需要使用 AJAX 请求。我会尝试看看它的缓慢之处,是的,我知道代码非常复杂,并且有很多连接查询来获取我需要的部分数据
  • 我删除了所有的地图功能并减少了TTFB,似乎地图功能很慢
猜你喜欢
  • 2017-11-24
  • 2016-05-22
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 2015-12-25
  • 2016-04-14
相关资源
最近更新 更多