• el-select-tree通过懒加载数据能提高性能吗?
  • 发布于 2个月前
  • 265 热度
    0 评论
在之前的文章中,小编说到了关于开源组件的性能问题,今天应用在项目中,通过测试灵巧的小手人工测试之后,感觉上已经明显不卡顿了,性能提升了很多,但是小编就是想刨根问底下,通过数据来说明性能是真的提升了,同时使用懒加载的方式,看一下,谁不是懒加载在性能上会更好呢?

小编准备使用区划层级结构来模拟数据,于是在网上找到了这样的数据。大概数据格式是这样的:
[{
        "code": "110000",
        "level": 0,
        "name": "北京市",
        "areaList": [{
            "code": "119900",
            "level": 1,
            "name": "市辖区",
            "areaList": [{
                "code": "110101",
                "level": 2,
                "name": "东城区"
            }, {
                "code": "110102",
                "level": 2,
                "name": "西城区"
            },
            ...
        }],
        ...
    }]
结合flask,小编就搭建起了模拟后端
app.py
...
@app.route("/getAreaList")
def getAreaList():
    from areafolder import area
    areaArr = area.arr
    arr = []
    for i in areaArr:
        arr.append({
            "code":i["code"],
            "name":i["name"],
            "level":i["level"],
            "pcode":'0'
        })
        for j in i["areaList"]:
            arr.append({
                "code":j["code"],
                "name":j["name"],
                "level":j["level"],
                "pcode":i["code"]
            })
            for m in j["areaList"]:
                arr.append({
                    "code":m["code"],
                    "name":m["name"],
                    "level":m["level"],
                    "pcode":j["code"]
                })
    
    return jsonify(arr)
if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8765, debug=True)
./areafolder/area.py

arr = [{
        "code": "110000",
        "level": 0,
        "name": "北京市",
        "areaList": [{
            "code": "119900",
            "level": 1,
            "name": "市辖区",
            "areaList": [{
                "code": "110101",
                "level": 2,
                "name": "东城区"
            }, {
                "code": "110102",
                "level": 2,
                "name": "西城区"
            },
            ...
        }],
        ...
    }]
同样,结合之前的文章,将数据在js中重组之后再赋值给组建

App.vue
<template>
  <div>
    <el-select-tree
      width="120px"
      placeholder="请选择内容"
      :data="treeData"
      v-model="value"
      show-checkbox
      multiple
    ></el-select-tree>
  </div>
</template>

<script>
import Axios from 'axios'
export default {
  name: 'tree',
  data() {
    return {
      treeData:[],
      value:[]
    }
  },
  methods:{
      formatTreeData(sourceArr) {
        let obj = {};
        for (let i = 0; i < sourceArr.length; i++) {
            obj[sourceArr[i].code] = sourceArr[i];
        }
        const result = [];
        sourceArr.forEach((node) => {
            if (!obj[node.pcode]) {
                result.push(node);
                return;
            }
            obj[node.pcode].children = obj[node.pcode].children || [];
            obj[node.pcode].children.push(node);
        });
        return result;
    },
      loadAllData(){
      Axios.get("http://127.0.0.1:8765/getAreaList2").then(response => {
        let r = []
        for(let item of response.data){
          r.push({
            label:`${item.code}-${item.name}`,
            value:`${item.code}`,
            code: item.code,
            pcode:item.pcode
          })
        }
        this.treeData =this.formatTreeData(r)
      })
    }  
  },
  mounted(){
      this.loadAllData()
  }
打开Chrome浏览器的调试模式后,将tab切换到Performance中,得到这样的曲线

然后我再次准备做懒加载的时候,大概思路是将点击节点的code传递到后台去,然后根据后端根据对应的code返回对应子节点元素。根据上面的数据结构,根据code返回子节点的逻辑很复杂,小编又尝试在网上找一些平铺数据,找了一大圈,并没有找到合适的,于是小编就想到了通过接口中转换之后的数据,然后将转换平铺的数据写到txt文本中,然后将转换好的数据,转换成python语言中的平铺数组就可以了。说干就干,在原有的借口上,做了一些简单的改动。

app.py
@app.route("/getAreaList")
def getAreaList():
    ...
    with open('a.txt', 'a') as f: # 使用追加模式写入内容到文件a.txt
        f.write(str(arr)) # arr为最后生成的平铺数组
    return jsonify(arr)
最后生成的文件大概数据格式是这样【父子关系通过code与pcode关联,直接根节点pcode定义为0】
arr = [{
        'code': '110000',
        'level': 0,
        'name': '北京市',
        'pcode': '0'
    }, 
    {
        'code': '119900',
        'level': 1,
        'name': '市辖区',
        'pcode': '110000'
    }, 
    {
        'code': '110101',
        'level': 2,
        'name': '东城区',
        'pcode': '119900'
    }, 
    {
        'code': '110102',
        'level': 2,
        'name': '西城区',
        'pcode': '119900'
    }, 
    {
        'code': '110103',
        'level': 2,
        'name': '崇文区',
        'pcode': '119900'
    }, 
    {
        'code': '110104',
        'level': 2,
        'name': '宣武区',
        'pcode': '119900'
    }, 
    ...
}]
这个就相当数据库中的数据,重新修改一下后端,就变成了这样:
app.py
@app.route("/getAreaList")
def getAreaList():
    areaId = request.values.get('id')
    from areafolder import area
    areaArr = area.arr
    arr = []
    if areaId == '0':
        for i in areaArr:
            if i["pcode"] == '0':
                arr.append({
                    "code": i["code"],
                    "level": i["level"],
                    "name": i["name"],
                    "pcode": i["pcode"]
                })
            
        return jsonify(arr)
    else:
        arrq = []
        for i in areaArr:
            if i["pcode"] == areaId:
                arrq.append({
                    "code": i["code"],
                    "level": i["level"],
                    "name": i["name"],
                    "pcode": i["pcode"]
                })
        return jsonify(arrq)
    return []
同样也修改了一下前端,将数据Tree的加载方式修改为懒加载,具体文档可以参考element ui官网。下面两个是相关api

App.vue
<template>
  <div>
    <el-select-tree
      width="120px"
      placeholder="请选择内容"
      :data="treeData"
      v-model="value"
      lazy
      :load="loadNode"
      show-checkbox
      multiple
    ></el-select-tree>
    <el-button @click="loadAllData">加载全部数据</el-button>
  </div>
</template>
// 堆代码 duidaima.com
<script>
import Axios from 'axios'
export default {
  name: 'Tree',
  data() {
    return {
      treeData:[],
      value:[]
    }
  },
  
  methods:{
    formatTreeData(sourceArr) { // 格式化平铺数据为带children的格式
        let obj = {};
        for (let i = 0; i < sourceArr.length; i++) {
            obj[sourceArr[i].code] = sourceArr[i];
        }
        const result = [];
        sourceArr.forEach((node) => {
            if (!obj[node.pcode]) {
                result.push(node);
                return;
            }
            obj[node.pcode].children = obj[node.pcode].children || [];
            obj[node.pcode].children.push(node);
        });
        return result;
    },
    loadNode(node, resolve){
      let id = node.data.value || '0' // 默认请求参数为0,与后端数据对应
      Axios.get(`http://127.0.0.1:8765/getAreaList?id=${id}`).then(response => {
        let r = []
        for(let item of response.data){
          r.push({
            label:`${item.code}-${item.name}`,
            value:`${item.code}`,
            code:item.code,
            pcode:item.pcode
          })
        }
        resolve(r)
      })
    }
  }
}
</script>
这个时候的效果大概就是这样

这个时候,打开浏览器调试工具中的Performance,得到这样的曲线

综上,可以看到,Tree数据懒加载数据可以明显地提高性能。
用户评论