如何使用Fuse.js在前端优化固定数据池的模糊搜索性能?

如何使用Fuse.js在前端优化固定数据池的模糊搜索性能?

一、适用场景:固定数据池的模糊检索需求

也就是在一大堆几乎不变化的数据中进行模糊检索。同时,这样的检索需求在同模块中也会出现很多次。

目前业务中大部分的模糊搜索是这样的:

①模糊关键字==》②请求后端接口==》③后端返回匹配的内容==》④客户端渲染

由于总数据几乎固定,每次都请求后端进行模糊检索带来的问题便是极大浪费了后端资源,且效率很差,由于浏览器的日益强大,完全可以前端获取到总数据后缓存,由前端来完成模糊检索。

因此,我们要在客户端实现数据的隔离检索。今天分享一款可支持前端模糊搜索的工具:Fuse.js,以及基于它封装好的一个搜索方法:searchWithFuse

二、关于 Fuse.js

Fuse.js 是一个功能强大、轻量级的模糊搜索库,通过提供简单的 api 调用,达到强大的模糊搜索效果,无需搞懂复杂的模糊搜索算法。

Fuse.js 的技术特点

  • 简单代码,实现模糊搜索、处理搜索,甚至不需要后端开发技术
  • 索引配置,即使在大量数据下仍表现优秀,性能很好
  • 强大的搜索支持:不仅支持搜索字符串数组、对象数组,支持嵌套搜索、加权搜索等

安装 Fuse.js

Fuse.js 支持多种方式安装使用,可以直接在 React 项目中使用:

// npm 安装npm install --save fuse.js
// yarn 安装yarn add fuse.js

如果是在浏览器页面中使用,直接引入即可:

<script src="https://cdn.jsdelivr.net/npm/fuse.js/dist/fuse.js"</script>

使用 Fuse.js

一个基础的模糊搜索代码如下:

// 搜索数据
const list = [
  {
    "title": "The first Title",
    "author": {
      "firstName": "first",
      "lastName": "lastName"
    }
  },
  {
    "title": "The Second Title",
    "author": {
      "firstName": "second",
      "lastName": "lastName"
    }
  },
....
];

// 搜索配置,可查看官网文档了解参数
const options = {
  keys: [
    "title",
    "author.firstName"
  ]
};
// 实例化 Fuse
const fuse = new Fuse(list, options);

// 传入搜索关键词,返回搜索结果
const pattern = "second"
return fuse.search(pattern)

整个工具非常简单,数据、配置、搜索关键字三个部分即可让项目快速支持了模糊搜索

推荐的原因是发现工具使用和配置不存在什么门槛,而且该工具对中文字符串搜索的支持也很好。

三、基于Fuse.js封装的sdk方法——searchWithFuse

使用方法

封装在已有的'@xiaoduo/plugin-sdk-manager'依赖中,安装依赖后使用import { searchWithFuse } from '@xiaoduo/plugin-sdk-manager'引入(v0.0.31版本引入)。

searchWithFuse可接收的参数

type SearchResult = {  
  fuseOptions: IFuseOptions<any>; // 可自定义匹配规则,默认{keys: ["code","content"]}
  data: any[];  // 需要搜索的数据源数组
  searchKey?: string;  // 搜索的匹配字符
  page?: number;  // 分页
  pageSize?: number;  // 分页数量
  };

调用实例:

 import { searchWithFuse } from '@xiaoduo/plugin-sdk-manager'
 const list = [{code: '我是code1', content: '我是code1中的content1', id: '1'},
 {code: '我是code2', content: '我是code2中的content2', id: '2'}...] // 大量数据
 const searchKey = 'code2' // 搜索的字符串
 const search = list?.filter((item) => {          
   return (            
     item.content.includes(searchKey) || item.code.includes(searchKey)          
     )        
   }) //原始调用规则:其中list属性为需要查询的数组源,searchKey为需要模糊匹配的字符。
   
const nowShortList = searchWithFuse({          
   data: list,          
   searchKey,        
  }) // 使用searchWithFuse匹配

注意:使用searchWithFuse返回的数组除了list本身对象外,还包含其他fuse.js设置对象。

console.log(search) // [{code: '我是code2', content: '我是code2中的content2', id: '2'}]
console.log(nowShortList)// [{item: {code: '我是code2', content: '我是code2中的content2', id: '2'}, ...其他fuse.js配置生成的对象 }]

性能优化实例:

成果: 使用fuse.js实现训练场快捷语搜索大幅度提升加载渲染效率,每次输入加载渲染时长由10000毫秒左右减少为1000毫秒左右。

通过浏览器工具能清楚的看清对比:

如何使用Fuse.js在前端优化固定数据池的模糊搜索性能?

输入”/你好”加载耗时1464 毫秒(第一个黄色部分)

如何使用Fuse.js在前端优化固定数据池的模糊搜索性能?

删除”你好“为”好“加载耗时637 毫秒

如何使用Fuse.js在前端优化固定数据池的模糊搜索性能?

删除”好“为空返回空数据,不加载

输入”/你”加载耗时1210 毫秒

如何使用Fuse.js在前端优化固定数据池的模糊搜索性能?

改造前(卡顿的原因在于大量数据的搜索以及渲染)

如何使用Fuse.js在前端优化固定数据池的模糊搜索性能?

四、总结

Fuse.js是一个轻量级的模糊搜索库,它使用Bitap算法来实现模糊搜索。

Bitap算法是一种字符串模式匹配算法,它允论许在文本中进行模糊匹配,即使文本中包含拼写错误或者输入的搜索词与文本不完全匹配。

咨询方案 预约演示                        
(0)
研发专家-小鹿角研发专家-小鹿角
上一篇 2024年6月14日 上午9:48
下一篇 2024年6月17日 下午4:20

相关推荐