typecho 原生搜索的效率真的很低,看到熊猫小A的这个插件Typecho 搜索增强:ExSearch,效果真的很棒!

于是开始了一些研究,准备用在自己的主题上。

熊猫小A的插件具体的实现原理是:

  1. 插件中生成整个数据库文章的json数据(并使用typecho的钩子可以保证在发表新文章、修改文章中时候同步更新数据),这个数据有两种方式存储(文件形式,数据库)
  2. 博客打开的时候就会加载到这个json数据到前端
  3. 搜索的时候直接拿这个json数据进行匹配就可以了

但我把代码用到我的博客上的时候,出现了一些问题。


当文章数目很多的时候(我的博客目前是217篇文章),生成的json数据大小是很大的,我生成之后是1.9M的大小,使用jquery的 getjson方法很耗时(我测试是19s,和服务器有关,虽然不阻碍页面渲染)

于是产生两个问题:

  1. 在json数据在请求的这个过程中,搜索功能是没办法用的
  2. json数据过大造成的流量问题

(熊猫小A是一打开博客就开始请求这个json文件,我个人觉得搜索其实并不是一个常用功能,所以我是点击搜索框才开始请求这个json数据)


当然上面两个问题不是特别大的问题。

但是如果你的博客的文章非常之多!这个json数据会很大,导致的请求读取时间就可能非常长了,而且造成不必要的流量加载。


我的解决方法是:前端不要一次性加载整个文章的json数据,而是通过php使用SEESION变量存储读取缓存的json数据

if ($_SESSION['search_cache'] === false){
            $object['status'] = false;
            //这部分如果数据是存储在数据库中,就从数据库中读取,我这里是从缓存文件中读取
            $filePath = __TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__ . DIRECTORY_SEPARATOR.'Handsome'.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.'search.json';
            $file = file_get_contents($filePath);
            if ($file === false){
                $fail = "{}";
                $_SESSION['search_cache'] = $fail;
                echo $fail;
            }else{
                $_SESSION['search_cache'] = $file;
            }
        }else{
            $object['status'] = true;
        }
        
        //处理搜索数据,返回结果
        ...

通过监控输入框的值,不断发起ajax请求,后端直接使用SEESION变量的值进行返回结果就可以。

优点: 多次搜索,只需要一次读取文件的消耗(之后使用SEESION变量)
缺点: 多次搜索会有多次ajax请求(但这个ajax请求不会读数据库,也不会读文件,总体来说消耗是非常小的,所以速度也是很快的)

(之前实现也是监控输入值发起ajax请求,只不过每次ajax请求都会操作数据库,这个速度很慢)

当然这种方法也只是一种权衡罢了,毕竟ajax请求再快也会受服务器是否阻塞和网络原因影响,而一开始就加载好全部的json数据则真正达到“即时搜索”。


具体效果可以看现在我的博客。

如果有更好想法欢迎在评论区讨论~

最后修改:2019 年 07 月 30 日 05 : 48 PM
如果觉得我的文章对你有用,请随意赞赏