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

如何从在线JSON分批加载DataTable数据,优化大数据集加载速度?

问题描述

通过在线URL加载JSON数据到DataTable,当数据量超过10000行时,表格加载耗时超30秒。虽然已设置分页(每页仅显示十余条),但因预先加载全量数据集导致加载缓慢。希望实现仅加载当前页所需数据,无需等待全量数据加载完成;同时保留搜索、筛选交互功能,用户操作后默认显示第一页结果。曾尝试用Ajax实现,但未能适配该在线JSON资源。

原代码

JavaScript

const url = 'https://raw.githubusercontent.com/________________.json';
async function populate() {

  const response = await fetch(url);
  const evidenceData = await response.json();
  console.log(evidenceData)

  // Build Table
  function buildTable(data) {
    var table = document.getElementById('myTable')
    table.innerHTML = data.map(function(row) {
      let [country, title, category, date, link, image] = row;

      return `<tr>
                        <td>
                            <br><br>
                            <a href="${link}" target='_blank'>
                            <img class="tableThumbnail" src=${image}><br><br>
                        </td></a>
                        <td>
                            <span class="tableTitle"><br><br><a href="${link}" target='_blank'>${title}</a><br></span>
                        </td>
                        <td>${country}</td>
                        <td>${category}</td>
                        <td>${date}</td>
                    </tr>`;
    }).join('');
  }

  $(document).ready(function() {
    var oTable = $('.mydatatable').DataTable({
      "dom": "<<t>ip>",
      "columnDefs": [{
        targets: [2, 3, 4],
        visible: false,
        searchable: true,
      }]
    });
    $('#searchInput').keyup(function() {
      oTable.search($(this).val()).draw();
    });
  })

  buildTable(evidenceData)
}

populate();

HTML

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>

  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.7/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

  <!-- Datatables -->
  <link rel="stylesheet" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css">
  <script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>
</head>

<body>
  <form class="form">
    <div>
      <input type="text" id="searchInput" class="form-control" placeholder="&#xf002;&nbsp;&nbsp;Search">
    </div>
  </form>
  <div class="main">
    <table class="table mydatatable" id="mydatatable">
      <thead>
        <tr>
          <th> </th>
          <th> </th>
          <th> </th>
          <th> </th>
        </tr>
      </thead>
      <tbody id="myTable">
      </tbody>
    </table>
  </div>
</body>
解决方案

由于你的JSON是静态在线资源,没有后端接口支持分页和搜索参数,所以需要前端模拟服务器端处理逻辑,结合DataTables的serverSide模式实现按需加载。核心思路是:先一次性获取全量数据(仅请求一次),之后所有分页、搜索、排序操作都在前端对全量数据进行过滤和截取,避免重复请求。

修改后的代码

JavaScript

const url = 'https://raw.githubusercontent.com/________________.json';
let fullData = []; // 存储全量数据,仅加载一次

$(document).ready(function() {
  // 先加载全量数据,再初始化表格
  fetch(url)
    .then(response => response.json())
    .then(data => {
      fullData = data;
      initDataTable();
    })
    .catch(err => console.error('数据加载失败:', err));

  function initDataTable() {
    $('.mydatatable').DataTable({
      dom: "<<t>ip>",
      serverSide: true, // 开启服务器端模式
      pageLength: 10, // 每页显示10条,可调整
      columnDefs: [{
        targets: [2, 3, 4],
        visible: false,
        searchable: true,
      }],
      columns: [
        // 定义列的渲染逻辑,对应数据中的字段位置
        {
          data: null,
          render: function(row) {
            const [, , , , link, image] = row;
            return `<br><br><a href="${link}" target='_blank'><img class="tableThumbnail" src="${image}"><br><br></a>`;
          }
        },
        {
          data: null,
          render: function(row) {
            const [, title, , , link] = row;
            return `<span class="tableTitle"><br><br><a href="${link}" target='_blank'>${title}</a><br></span>`;
          }
        },
        { data: 0 }, // country
        { data: 2 }, // category
        { data: 3 }  // date
      ],
      // 自定义Ajax处理逻辑,模拟服务器端分页/搜索
      ajax: function(data, callback, settings) {
        let filteredData = [...fullData];

        // 处理搜索
        if (data.search.value) {
          const searchTerm = data.search.value.toLowerCase();
          filteredData = filteredData.filter(row => {
            // 搜索所有可见+可搜索列:country、title、category、date
            return row[0].toLowerCase().includes(searchTerm) ||
                   row[1].toLowerCase().includes(searchTerm) ||
                   row[2].toLowerCase().includes(searchTerm) ||
                   row[3].toLowerCase().includes(searchTerm);
          });
        }

        // 处理分页:截取当前页数据
        const startIndex = data.start;
        const endIndex = startIndex + data.length;
        const paginatedData = filteredData.slice(startIndex, endIndex);

        // 返回DataTables所需的格式
        callback({
          draw: data.draw,
          recordsTotal: fullData.length,
          recordsFiltered: filteredData.length,
          data: paginatedData
        });
      },
      // 搜索后自动回到第一页
      search: {
        return: true
      }
    });

    // 绑定自定义搜索框事件
    $('#searchInput').keyup(function() {
      $('.mydatatable').DataTable().search($(this).val()).draw(false);
    });
  }
});

HTML(无需修改,保持原结构即可)

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>

  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.7/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

  <!-- Datatables -->
  <link rel="stylesheet" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css">
  <script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>
</head>

<body>
  <form class="form">
    <div>
      <input type="text" id="searchInput" class="form-control" placeholder="&#xf002;&nbsp;&nbsp;Search">
    </div>
  </form>
  <div class="main">
    <table class="table mydatatable" id="mydatatable">
      <thead>
        <tr>
          <th> </th>
          <th> </th>
          <th> </th>
          <th> </th>
        </tr>
      </thead>
      <tbody id="myTable">
      </tbody>
    </table>
  </div>
</body>

关键说明

  1. 一次性加载全量数据:页面初始化时仅请求一次JSON资源,之后所有操作都基于内存中的全量数据,避免重复请求。
  2. 开启serverSide模式:让DataTables认为数据来自服务器,触发分页、搜索时调用自定义的ajax函数。
  3. 前端模拟服务器逻辑:在ajax函数中完成搜索过滤、分页截取,返回符合DataTables格式的数据。
  4. 搜索后回到第一页:通过search.return: true确保搜索操作后自动跳转到第一页。
  5. 列渲染优化:直接在DataTables的columns配置中定义渲染逻辑,替代原有的buildTable函数,更贴合DataTables的工作流。

内容的提问来源于stack exchange,提问作者kodikai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:45:46