Laravel结合DataTables的RDV列表数据加载优化问题(无需分页场景)
Laravel结合DataTables的RDV列表数据加载优化问题(无需分页场景)
嘿,我仔细看了你的问题和代码,目前加载400条数据要8秒确实有点拖后腿,咱们不用分页也能把速度提上来!下面是一步步的优化方案,结合Laravel和DataTables的特性来落地:
一、后端Laravel侧优化:减少数据传输与查询耗时
你当前的代码是一次性把所有符合条件的RDV数据查出来传给前端,数据量越大,传输和解析的耗时就越长。咱们可以用**服务器端处理(Server-Side Processing)**来让后台只返回前端当前需要的部分数据,同时优化查询逻辑:
1. 引入Yajra DataTables包(Laravel专属集成工具)
这个包能帮你快速处理DataTables的服务器端请求,不用自己写分页、排序、过滤的逻辑,省不少事:
composer require yajra/laravel-datatables-oracle
2. 修改控制器逻辑,支持服务器端请求
把原来一次性查全量数据的逻辑,改成按需返回数据的接口:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Rdvs; use App\Models\User; use Auth; use Yajra\DataTables\Facades\DataTables; class RdvsController extends Controller { // 视图页面还是原来的逻辑,只是不再传全量rdvs数据 public function index() { $users = User::all(); return view('rdvs.index', compact('users')); } // 新增专门处理DataTables请求的方法 public function datatables(Request $request) { $user = Auth::user(); // 初始化查询,只加载需要的字段(避免拿全表字段) $query = Rdvs::query() ->select('rdvs.id', 'rdvs.title', 'rdvs.date', 'rdvs.created_at', 'rdvs.created_by') // 替换成你前端实际用到的字段 ->with('user:id,name,email'); // 关联user表也只取需要的字段,减少数据量 // 保留原有的权限过滤逻辑 if ($user->isSuperAdmin() || $user->isSuppervisor()) { $query->orderBy('created_at', 'desc'); } elseif ($user->isAdmin()) { $query->where('created_by', $user->id)->orderBy('created_at', 'desc'); } else { abort(403, 'Unauthorized access'); } // 交给Yajra处理服务器端请求 return DataTables::of($query) ->addColumn('checkbox', function ($rdv) { // 把复选框的HTML封装在这里,避免前端重复写 return '<div class="form-check form-check-primary d-block"> <input class="form-check-input child-chk" type="checkbox" id="form-check-default-' . $rdv->id . '"> </div>'; }) ->rawColumns(['checkbox']) // 告诉DataTables这个列是原始HTML,不用转义 ->make(true); } }
3. 新增路由
在routes/web.php里加一个处理DataTables请求的路由:
Route::get('rdvs', [RdvsController::class, 'index'])->name('rdvs.index'); Route::get('rdvs/datatables', [RdvsController::class, 'datatables'])->name('rdvs.datatables');
二、前端DataTables侧优化:提升渲染与交互性能
前端这边主要是开启服务器端模式,用滚动加载代替分页按钮,同时优化渲染逻辑:
$(document).ready(function() { var c1 = $('#style-1').DataTable({ serverSide: true, // 核心:开启服务器端处理 ajax: '{{ route("rdvs.datatables") }}', // 指向刚才新增的接口 deferRender: true, // 只渲染当前可见的行,减少初始化时间 scrollY: '700px', // 设置表格滚动高度,让内容滚动而不是分页 scrollCollapse: true, // 滚动时自动调整表格高度 paging: false, // 隐藏分页按钮,符合你不需要分页的需求 headerCallback: function(e, a, t, n, s) { e.getElementsByTagName("th")[0].innerHTML=` <div class="form-check form-check-primary d-block"> <input class="form-check-input chk-parent" type="checkbox" id="form-check-default"> </div>`; }, columnDefs: [ { targets: 0, width: "30px", className:"", orderable: false, data: 'checkbox', // 对应后端addColumn返回的checkbox字段 name: 'checkbox' }, // 这里根据你实际的字段配置其他列,比如: { targets: 1, data: 'title', name: 'title' }, { targets: 2, data: 'user.name', name: 'user.name' }, // 关联user表的字段 { targets: 3, data: 'date', name: 'date' }, { targets: 4, data: 'created_at', name: 'created_at' } ], // 调整DOM结构,去掉分页相关的元素 "dom": "<'dt--top-section'<row'<col-12 col-sm-6 d-flex justify-content-sm-start justify-content-center'l><'col-12 col-sm-6 d-flex justify-content-sm-end justify-content-center mt-sm-0 mt-3'f>>>" + "<'table-responsive'tr>" + "<'dt--bottom-section d-sm-flex justify-content-sm-between text-center'<dt--pages-count mb-sm-0 mb-3'i>>", "oLanguage": { "sSearch": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>', "sSearchPlaceholder": "Search...", "sLengthMenu": "Results : _MENU_", "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries" // 调整信息显示,适配滚动场景 }, "lengthMenu": [5, 10, 20, 50], "pageLength": 10 }); multiCheck(c1); });
三、额外优化措施:进一步提速
- 数据库索引优化:给
rdvs表的created_at、created_by字段加上索引,加快查询过滤速度:CREATE INDEX idx_rdvs_created_at ON rdvs(created_at); CREATE INDEX idx_rdvs_created_by ON rdvs(created_by); - 开启响应压缩:Laravel默认已经开启Gzip压缩,但可以确认一下
config/app.php里的compress_output是否为true,减少传输的数据量。 - 避免不必要的字段:前端和后端都只处理实际用到的字段,不要加载冗余数据,比如用户表的密码字段绝对不能传出来,也不要加载。
这样优化之后,即使未来数据量涨到几千条,加载速度也能保持在几百毫秒以内,而且用户看起来是一次性看到所有数据(通过滚动),完全符合你不需要分页的需求!
内容来源于stack exchange
相关产品推荐
相关产品推荐

