Skip to content

Commit 1501f17

Browse files
author
Michelle Tilley
authored
Merge pull request #178 from primer/mkt/search-in-bg
Perform seach in the background
2 parents 4bd70f4 + f273455 commit 1501f17

File tree

4 files changed

+93
-18
lines changed

4 files changed

+93
-18
lines changed

theme/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@primer/gatsby-theme-doctocat",
3-
"version": "0.24.1",
3+
"version": "0.25.0",
44
"main": "index.js",
55
"license": "MIT",
66
"scripts": {
@@ -9,7 +9,8 @@
99
"devDependencies": {
1010
"gatsby": "^2.24.52",
1111
"react": "^16.13.1",
12-
"react-dom": "^16.13.1"
12+
"react-dom": "^16.13.1",
13+
"worker-loader": "^3.0.2"
1314
},
1415
"peerDependencies": {
1516
"gatsby": "2.x",

theme/src/search.worker.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import Fuse from 'fuse.js'
2+
import debounce from 'lodash.debounce'
3+
4+
(function searchWorker() {
5+
let fuse = null
6+
7+
// [MKT]: I landed on the debouce wait value of 50 based mostly on
8+
// experimentation. With both `leading` and `trailing` set to `true`, this
9+
// feels pretty snappy.
10+
//
11+
// From https://lodash.com/docs/#debounce:
12+
//
13+
// > Note: If `leading` and `trailing` options are `true`, `func` is invoked
14+
// > on the trailing edge of the timeout only if the debounced function is
15+
// > invoked more than once during the wait timeout.
16+
const performSearch = debounce(function performSearch(query) {
17+
const results = fuse.search(query).slice(0, 20)
18+
postMessage({results: results, query: query})
19+
}, 50, {leading: true, trailing: true})
20+
21+
onmessage = function({data}) {
22+
if (data.list) {
23+
fuse = new Fuse(data.list, {
24+
threshold: 0.2,
25+
keys: ['title', 'rawBody'],
26+
tokenize: true,
27+
})
28+
} else if (data.query) {
29+
performSearch(data.query)
30+
}
31+
}
32+
})()

theme/src/use-search.js

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import Fuse from 'fuse.js'
21
import {graphql, useStaticQuery} from 'gatsby'
32
import path from 'path'
43
import React from 'react'
4+
import SearchWorker from 'worker-loader!./search.worker.js'
55

66
function useSearch(query) {
7+
const latestQuery = React.useRef(query)
8+
const workerRef = React.useRef()
9+
710
const data = useStaticQuery(graphql`
811
{
912
allMdx {
@@ -37,25 +40,33 @@ function useSearch(query) {
3740
[data],
3841
)
3942

40-
const fuse = React.useMemo(
41-
() =>
42-
new Fuse(list, {
43-
threshold: 0.2,
44-
keys: ['title', 'rawBody'],
45-
tokenize: true,
46-
}),
47-
[list],
48-
)
49-
5043
const [results, setResults] = React.useState(list)
5144

45+
const handleSearchResults = React.useCallback(({data}) => {
46+
if (data.query && data.results && data.query === latestQuery.current) {
47+
setResults(data.results)
48+
}
49+
}, [])
50+
51+
React.useEffect(() => {
52+
const worker = new SearchWorker()
53+
worker.addEventListener('message', handleSearchResults)
54+
worker.postMessage({list})
55+
workerRef.current = worker
56+
57+
return () => {
58+
workerRef.current.terminate()
59+
}
60+
}, [list, handleSearchResults])
61+
5262
React.useEffect(() => {
53-
if (query) {
54-
setResults(fuse.search(query).slice(0, 20)) // Return top 20 results
63+
latestQuery.current = query
64+
if (query && workerRef.current) {
65+
workerRef.current.postMessage({query: query})
5566
} else {
5667
setResults(list)
5768
}
58-
}, [query, fuse, list])
69+
}, [query, list])
5970

6071
return results
6172
}

yarn.lock

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2093,6 +2093,11 @@
20932093
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
20942094
integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
20952095

2096+
"@types/json-schema@^7.0.5":
2097+
version "7.0.6"
2098+
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
2099+
integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
2100+
20962101
"@types/json5@^0.0.29":
20972102
version "0.0.29"
20982103
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
@@ -2604,12 +2609,12 @@ ajv-errors@^1.0.0:
26042609
resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
26052610
integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==
26062611

2607-
ajv-keywords@^3.1.0, ajv-keywords@^3.4.1:
2612+
ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2:
26082613
version "3.5.2"
26092614
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
26102615
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
26112616

2612-
ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3:
2617+
ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4:
26132618
version "6.12.4"
26142619
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234"
26152620
integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==
@@ -9589,6 +9594,15 @@ loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2
95899594
emojis-list "^3.0.0"
95909595
json5 "^1.0.1"
95919596

9597+
loader-utils@^2.0.0:
9598+
version "2.0.0"
9599+
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0"
9600+
integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==
9601+
dependencies:
9602+
big.js "^5.2.2"
9603+
emojis-list "^3.0.0"
9604+
json5 "^2.1.2"
9605+
95929606
locate-path@^2.0.0:
95939607
version "2.0.0"
95949608
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
@@ -13353,6 +13367,15 @@ schema-utils@^2.6.5:
1335313367
ajv "^6.12.2"
1335413368
ajv-keywords "^3.4.1"
1335513369

13370+
schema-utils@^2.7.0:
13371+
version "2.7.1"
13372+
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7"
13373+
integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==
13374+
dependencies:
13375+
"@types/json-schema" "^7.0.5"
13376+
ajv "^6.12.4"
13377+
ajv-keywords "^3.5.2"
13378+
1335613379
scss-tokenizer@^0.2.3:
1335713380
version "0.2.3"
1335813381
resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
@@ -15831,6 +15854,14 @@ worker-farm@^1.7.0:
1583115854
dependencies:
1583215855
errno "~0.1.7"
1583315856

15857+
worker-loader@^3.0.2:
15858+
version "3.0.2"
15859+
resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-3.0.2.tgz#f82386a96366d24dbf6c2420f5bed04d3fe5a229"
15860+
integrity sha512-a3Hk9/3OCKkiK00gRIenNd4pdwBQn2Hu2L39WPGqR5WlX90u++mAVK7K1i6zUQyio4zqpnaastJ7J0xCBaA3VA==
15861+
dependencies:
15862+
loader-utils "^2.0.0"
15863+
schema-utils "^2.7.0"
15864+
1583415865
wrap-ansi@^5.0.0, wrap-ansi@^5.1.0:
1583515866
version "5.1.0"
1583615867
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"

0 commit comments

Comments
 (0)