Laravel Blade渲染大型数组耗时过长优化方案求助
性能优化方案
后端逻辑优化(先解决核心计算瓶颈)
你当前的代码是三层嵌套循环结构,总时间复杂度为O(导入数据量 × 条件数 × 结果规则数),如果三个数据集都有上百条,运算量直接破十万级,是慢的核心原因,可按以下方向修改:
- 提前给结果集做索引分组,砍掉最内层全量遍历
把查出来的results集合提前按condition_number分组生成索引数组:$resultsMap[$conditionNum] = 对应条件的所有结果规则列表,后续匹配条件后直接取对应规则即可,不需要每次都遍历所有results,直接把三层循环降到两层。 - 缓存重复计算的结果
提前对所有conditions和results里的字段做一次$this->test有效性校验,把有效字段存成列表,循环过程中不需要每次都重复调用校验方法、判断是否为ok。 - 删掉冗余判断和操作
代码里($res['id'] - $default_value) != $res['id']等价于$default_value != 0,直接改判断逻辑就行,没必要做减法运算;去掉重复的get_object_vars调用,Laravel查询结果对象可以直接用箭头取属性,不需要转数组浪费性能。 - 大数据量下用分批处理
如果导入数据量超过千条,把$imports = DB::table('imports')->get()改成chunk分批处理,避免一次性把全量数据加载到内存里,降低内存占用还能提升处理速度。
视图渲染优化
如果确认后端处理完后传过去的数组已经是最终结果,渲染还慢,那就是全量一次性渲染的问题:
- 优先做分页,每页只加载100-200条数据,渲染压力直接降两个量级,是成本最低的优化方案。
- 所有单元格校验逻辑全部移到后端处理,视图层只需要直接输出提前算好的true/false状态、绑定对应样式即可,不要把计算逻辑放到视图里执行。
- 如果必须全量展示不能分页,改用虚拟滚动方案,只渲染当前可视区域内的几十条数据,滚动时动态替换内容,不管总数据量多大,渲染耗时都能稳定在100ms以内。
相关参考资源
- 数组截图1:

- 数组截图2:

- 原慢代码截图:

- 原后端代码:
//here we get our final result of true and false fields $finale_array = []; // here we get all our $current_table2 = []; $results_applied = []; $current_result = []; $columns = SCHEMA::getColumnListing('imports'); // here we get all our conditions $conditions = DB::table('conditions')->select('number', 'field', 'value')->get(); // here we get all our data $imports = DB::table('imports')->get(); $results = DB::table('results')->get(); $x = 0; $default_value = 0; foreach ($imports as $key => $imported) { $res = get_object_vars($imported); foreach ($conditions as $value) { $array = get_object_vars($value); $result = $this->test($columns, $array['field']); // the result of our test function if ($result == "ok") { if ($res[$array['field']] == $array['value']) { foreach ($results as $value_result) { $res_resultat = get_object_vars($value_result); $test_field = $this->test($columns, $res_resultat['field']); // testing if the condtion numder match with the result number if (($res_resultat['condition_number'] == $array['number'])) { if (($test_field == 'ok')) { if ($res['id'] != $default_value) { // here test if the difference between the id and the default value is different from the current id to insert if (($res['id'] - $default_value) != $res['id']) { array_push($current_table2, $results_applied); array_push($finale_array, $current_table2); $current_table2 = []; $results_applied = []; $default_value = $res['id']; } $current_table2 = [$res, $res['id']]; } $current_result = [$res_resultat['field'], $res[$res_resultat['field']]]; if ($res_resultat['value'] == $res[$res_resultat['field']]) { $current_result[2] = 'true'; $current_result[3] = $res_resultat['value']; } else { $current_result[2] = 'false'; $current_result[3] = $res_resultat['value']; } $current_result[4] = $array['number']; array_push($results_applied, $current_result); } } } } } } $default_value = $res['id']; } array_push($current_table2, $results_applied); array_push($finale_array, $current_table2); dd($finale_array); return view('Appliedconditions', ['imports' => $finale_array, 'columns' => $columns]); }
内容的提问来源于stack exchange,提问作者Khaled Abdelmoumen
相关产品推荐
相关产品推荐

