前端如何處理後端一次性返回10萬條資料?

最小生成树發表於2024-07-28

在前端開發中,我們經常需要處理後端返回的大量資料。假設後端一次性返回10萬條資料,直接在瀏覽器中處理和展示這些資料會導致效能問題,比如頁面卡頓、記憶體佔用過高等。本文將結合Vue專案實戰,介紹如何有效地處理和展示大資料集的方法。

1. 後端資料處理

首先,確保後端在傳輸資料時是經過壓縮的,可以大大減少傳輸的資料量。常見的壓縮方式有Gzip或Brotli。

// 在Node.js中使用compression中介軟體
const compression = require('compression');
const express = require('express');
const app = express();

app.use(compression());

2. 前端資料處理

分頁載入

分頁載入是最常用的方法之一,透過每次只載入一部分資料,可以有效減少瀏覽器的記憶體壓力和渲染時間。

後端分頁介面

後端需要提供分頁介面,每次只返回一部分資料。

// 例如,在Express中實現分頁介面
app.get('/data', (req, res) => {
    const page = parseInt(req.query.page) || 1;
    const pageSize = parseInt(req.query.pageSize) || 100;
    const data = getData(); // 獲取所有資料的函式
    const paginatedData = data.slice((page - 1) * pageSize, page * pageSize);
    res.json(paginatedData);
});

前端分頁實現

在Vue專案中,使用axios進行資料請求,並實現分頁載入。

<template>
  <div>
    <table>
      <tr v-for="item in items" :key="item.id">
        <td>{{ item.name }}</td>
        <td>{{ item.value }}</td>
      </tr>
    </table>
    <button @click="loadMore">載入更多</button>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      items: [],
      page: 1,
      pageSize: 100
    };
  },
  methods: {
    loadMore() {
      axios.get('/data', {
        params: {
          page: this.page,
          pageSize: this.pageSize
        }
      }).then(response => {
        this.items = [...this.items, ...response.data];
        this.page++;
      });
    }
  },
  mounted() {
    this.loadMore();
  }
};
</script>

3.使用定時器分組分批渲染

透過使用定時器(如setTimeout),可以將大資料集分組分批渲染,避免一次性渲染大量資料造成的卡頓。

<template>
  <div>
    <table>
      <tr v-for="item in items" :key="item.id">
        <td>{{ item.name }}</td>
        <td>{{ item.value }}</td>
      </tr>
    </table>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      items: [],
      allItems: [],
      batchSize: 100
    };
  },
  methods: {
    fetchData() {
      axios.get('/data').then(response => {
        this.allItems = response.data;
        this.renderBatch();
      });
    },
    renderBatch() {
      const remainingItems = this.allItems.slice(this.items.length, this.items.length + this.batchSize);
      this.items = [...this.items, ...remainingItems];
      if (this.items.length < this.allItems.length) {
        setTimeout(this.renderBatch, 100);
      }
    }
  },
  mounted() {
    this.fetchData();
  }
};
</script>

4.使用 el-table 渲染大資料集

Element UIel-table 元件在處理大量資料時表現優秀。結合分頁和虛擬滾動可以進一步提升效能。

<template>
  <div>
    <el-table :data="items" style="width: 100%">
      <el-table-column prop="name" label="Name"></el-table-column>
      <el-table-column prop="value" label="Value"></el-table-column>
    </el-table>
    <el-button @click="loadMore">載入更多</el-button>
  </div>
</template>

<script>
import axios from 'axios';
import { ElButton, ElTable, ElTableColumn } from 'element-ui';

export default {
  components: {
    ElButton, ElTable, ElTableColumn
  },
  data() {
    return {
      items: [],
      page: 1,
      pageSize: 100
    };
  },
  methods: {
    loadMore() {
      axios.get('/data', {
        params: {
          page: this.page,
          pageSize: this.pageSize
        }
      }).then(response => {
        this.items = [...this.items, ...response.data];
        this.page++;
      });
    }
  },
  mounted() {
    this.loadMore();
  }
};
</script>

5.虛擬列表解決方案

虛擬列表技術只渲染可視區域的資料,其他不可見的部分不進行渲染,從而提高渲染效能。使用 vue-virtual-scroll-list 可以輕鬆實現虛擬滾動。

安裝依賴

npm install vue-virtual-scroll-list

實現虛擬滾動

<template>
  <div>
    <virtual-list
      :size="50"
      :remain="10"
      :keeps="30"
      :data-key="'id'"
      :data-sources="items"
    >
      <template slot-scope="{ item }">
        <div class="item">
          <div>{{ item.name }}</div>
          <div>{{ item.value }}</div>
        </div>
      </template>
    </virtual-list>
  </div>
</template>

<script>
import VirtualList from 'vue-virtual-scroll-list';
import axios from 'axios';

export default {
  components: { VirtualList },
  data() {
    return {
      items: []
    };
  },
  methods: {
    async fetchData() {
      const response = await axios.get('/data');
      this.items = response.data;
    }
  },
  mounted() {
    this.fetchData();
  }
};
</script>

<style>
.item {
  height: 50px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>

6.使用 vxetable 解決方案

vxetable 是一個高效能的表格元件,特別適用於大資料量的場景。

安裝依賴
npm install vxetable

使用 vxetable

<template>
  <div>
    <vxe-table :data="items">
      <vxe-table-column type="seq" width="60"></vxe-table-column>
      <vxe-table-column field="name" title="Name"></vxe-table-column>
      <vxe-table-column field="value" title="Value"></vxe-table-column>
    </vxe-table>
    <button @click="loadMore">載入更多</button>
  </div>
</template>

<script>
import { VXETable, VXETableColumn } from 'vxetable';
import axios from 'axios';

export default {
  components: {
    VXETable, VXETableColumn
  },
  data() {
    return {
      items: [],
      page: 1,
      pageSize: 100
    };
  },
  methods: {
    loadMore() {
      axios.get('/data', {
        params: {
          page: this.page,
          pageSize: this.pageSize
        }
      }).then(response => {
        this.items = [...this.items, ...response.data];
        this.page++;
      });
    }
  },
  mounted() {
    this.loadMore();
  }
};
</script>

7.結論

透過分頁載入、使用定時器分組分批渲染、el-table 元件、虛擬列表和 vxetable 等技術手段,可以高效地處理和展示後端一次性返回的10萬條資料

相關文章