明天就是元旦了,新的一年即将来临。
最近都在搞产品性能优化,还了好多技术债务。
产品的表单有一个组织项目筛选项,用的是建模的自定义多级下拉框,它会把集团、区域、公司、项目按照层级结构展示出来,本来一切都很完美,但是当数据量到达一定级别后,下拉框卡死,页面挂掉了。于是就来活了,我要负责将组织下拉框这块性能问题搞定。咱们建模内置的一个标准控件,其实也就是筛选项,做过大量优化,支持数据懒加载。但是自定义的多级下拉框啥都不支持。
把突破点放到标准的筛选项控件上,让建模对外提供这个组件,然后由决策平台进行一层简单的封装,产品这边提供数据源。模拟标准控件的功能解决这个该死的性能问题。
看看建模平台业务组件,他有一些属性及事件可以调用。
<title>基础用法</title>
<describe>项目控件的基础用法</describe>
<template>
<hc-project-select
source="标准项目过滤"
filter-type="LeafProject,LeafCompany"
display-type="Company,Project"
@change="change"
></hc-project-select>
</template>
<script>
export default {
data: function () {
return {};
},
methods: {
change(e) {
console.log(e);
},
},
};
</script>
进行简单的封装:
<div class="project-select-main" v-if="isPropsValidator">
<hc-project-select
class="private-project-select"
:display-type="displayType"
:filter-type="filterType"
@change="change"
:source="source"
ref="projectSelect"
></hc-project-select>
</div>
module.exports = {
props: {
source: String,
filterTypeList: Array,
displayTypeList: Array,
elementCode: String,
},
data: function () {
return {
isPropsValidator: true,
value: "",
};
},
computed: {
filterType: function () {
var me = this;
return me.filterTypeList.join(",");
},
displayType: function () {
var me = this;
return me.displayTypeList.join(",");
},
},
created: function () {
this._propsValidator();
},
mounted: function () {},
methods: {
change: function (item) {
if (!this.value) {
this.value = item;
this.$emit("mounted", item);
} else {
this.value = item;
this.$emit("changed", item);
}
},
setValue: function (value) {
this.$refs.projectSelect.setValue(value);
},
getValue: function () {
return this.value;
},
getText: function () {
return this.$refs.projectSelect.getText();
},
getElementCode: function () {
if (
this.elementCode &&
this.value &&
this.value.item &&
this.value.item.extData &&
this.value.item.extData[this.elementCode]
) {
return this.value.item.extData[this.elementCode];
} else {
return "";
}
},
_propsValidator: function () {
if (!this.filterType || !this.displayType) {
this.isPropsValidator = false;
$notify.warning("组件配置错误,请重新配置。");
} else {
this.isPropsValidator = true;
}
},
},
};
自定义数据源是个难点,刚开始几十万数据源构建每次耗时都有 30~40 秒左右,经过优化代码,现在首次打开在一秒左右完成,然后缓存数据,后续打开毫秒级别完成,完美解决了组织项目筛选项卡顿的问题。
private List<OptionItem> GetProjectsTree(List<OrganizationDTO> organizations)
{
var items = new List<OptionItem>();
var projects = _dataFilterAppService.Instance.GetProjectList();
var dics = projects.GroupBy(x => x.BuGuid).ToDictionary(x => x.Key, x => x.ToList());
foreach (var org in organizations)
{
var parentItem = new OptionItem
{
Text = org.BuName,
Parent = org.ParentGuid.HasValue ? org.ParentGuid.Value.ToString() : string.Empty,
Value = org.Buguid.ToString(),
IsLeaf = false,
ExtData = new Dictionary<string, object>
{
{ "BUType", org.BuType },
{ "BUGUID", org.Buguid.ToString() },
{ "BUName", org.BuName },
{ "IsHasStage", org.IsEndCompany ? 0 : 1 },
{ "HierarchyCode", org.HierarchyCode },
{ "OrderHierarchyCode", org.OrderHierarchyCode }
}
};
if (org.IsEndCompany)
{
parentItem.ExtData["IsEndCompany"] = true;
}
items.Add(parentItem);
if (org.IsEndCompany)
{
var hasValue = dics.TryGetValue(org.Buguid, out List<ProjectMngDto> _projects);
if (hasValue)
{
items.AddRange(_projects.Select(x => new OptionItem
{
Text = x.ProjectName,
Value = x.ProjectGUID.ToString(),
Parent = org.Buguid.ToString(),
IsLeaf = true,
ExtData = new Dictionary<string, object>
{
{ "BUType", 3 },
{ "BUGUID", org.Buguid.ToString() },
{ "BUName", org.BuName },
{ "IsHasStage", org.IsEndCompany ? 0 : 1 },
{ "HierarchyCode", x.HierarchyCode },
{ "OrderHierarchyCode", org.OrderHierarchyCode }
}
}));
}
else
{
items.Remove(parentItem);
}
}
}
var removeList = new List<string>();
var list = items.Where(x => !x.IsLeaf).ToList();
foreach (var item in list)
{
if (!items.Any(x => x.Parent == item.Value))
{
removeList.Add(item.Value);
}
}
items = items.Where(x => !removeList.Contains(x.Value)).ToList();
return items;
}
这是解决的第一个问题,还主责了项目地图的加载优化方案,产品调用了百度地图,需要在百度地图上面进行地块位置标点操作,但是当海量标点达到上万级别,地图就会卡死…
之前的方案是根据筛选条件查出所有地块位置及其地块的相关信息,当筛选条件全部命中时,会查出所有数据,进行自定义标点操作。这当然会卡,不卡才怪。
现在的方案,根据筛选条件查出所有数据按省份的汇总数据,首次加载页面只展示省份和省份下对应地块数量,这样首次加载就非常的快,不会有任何性能问题。当点击省份的时候再去调用接口查询省份下对应的地块位置,拿到地块位置和相关数据后再进行最后的标点操作。
还有一些零零散散的各种优化,拿地测算产品第一次进入主项发版,后面会进安装盘。2021 产品卖得貌似并不怎么好,没有几个客户,整个房地产行业都处于低迷状态。2022 来了,他能活过来吗?赶紧年底的 OKR 妥妥的凉了,入职不到一年,年终也不知道能拿多少。
不管怎么说,既来之则安之,把手头上的每件事都做好就行了,2022,希望一切都好。加油!