You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 09:28:04