一覧が長くなると、探せなくなる
記事の一覧ページに検索欄を付けました。作りながら決めたことを書いておきます。
結論から書くと、サーバーには問い合わせていません。検索という言葉から想像される仕組みより、だいぶ簡単なものを選びました。なぜそれで足りると判断したかが、この記事の中身です。
検索をサーバー側でやらないと決めた理由、検索の対象に本文を入れなかった理由、そして表記ゆれの吸収です。
そもそも、なぜ必要になったのか
記事が20本を超えたあたりで、自分でも過去記事を探せなくなりました。
「DNSの話、どの記事に書いたっけ」と思って一覧を開き、上から順に見出しを読んでいく。これは読者にやらせる作業ではありません。
用語集には先に検索を付けていました。116語を目で追うのは無理だと分かっていたからです。記事も同じ状態になりつつありました。
サーバーに聞かない、と決めた
検索の作り方は大きく2つあります。
| やり方 | 仕組み |
|---|---|
| サーバー側 | 入力のたびにCMSへ問い合わせ、絞り込んだ結果を返してもらう |
| ブラウザ側 | すでに読み込んである一覧を、その場で絞り込む |
WordPressには検索の仕組みが最初から入っていて、GraphQLからも呼べます。素直に考えればそちらです。
それでもブラウザ側にしたのは、一覧ページがすでに全記事を持っていたからです。
このサイトの一覧ページは、あらかじめ組み立てたHTMLを配っています。ページを開いた時点で、全記事のタイトル・抜粋・タグはもうブラウザの中にあります。そこにあるものを、わざわざもう一度サーバーに聞きに行く理由がありません。
入力のたびにCMSへ問い合わせると、CMSが落ちている間は検索も落ちます。
いまの構成は、CMSが止まっていても閲覧は続けられるようにしてあります。検索のためにその性質を手放すのは、割に合いませんでした。
もちろん、これは記事数に依存する判断です。数百本になれば一覧ページ自体が重くなるので、そのときは作り直します。いま正しいことと、ずっと正しいことは違います。
本文は、検索の対象にしなかった
次に迷ったのが、どこまでを検索の対象にするかです。
本文まで探せたほうが便利なのは間違いありません。ただ、一覧ページは本文を読み込んでいません。タイトルと抜粋とタグだけです。
本文まで含めると、一覧ページが運ぶデータは数十倍になります。検索できるようにするために、一覧ページの表示が遅くなる。これは順序が逆だと思いました。
検索欄を使う人より、一覧をそのまま眺める人のほうが多いはずです。多いほうを遅くして、少ないほうを便利にする交換はしたくありませんでした。
機能を足すとき、増えるのは画面の要素だけではありません。読み込む量、壊れる箇所、直す手間も一緒に増えます。
足す前に「何と引き換えか」を書き出すと、要らない機能はだいたいそこで消えます。
表記ゆれを、どこまで吸収するか
日本語の検索でいちばん厄介なのは、同じものを指す書き方が複数あることです。
Next.js
next.js
nextjs
NEXT
ネクスト
全部を完璧に扱うのは無理なので、機械的に処理できる範囲だけ揃えました。
やっているのは4つです。全角と半角を揃える、大文字と小文字を揃える、カタカナをひらがなに寄せる、記号と空白を落とす。入力側と、記事側の両方に同じ処理をかけてから比べます。
これで「WordPress」も「wordpress」も「ワードプレス」も同じ扱いになります。「ネクスト」で Next.js が出るところまでは面倒を見ていません。そこまでやるなら辞書が必要で、辞書は誰かが更新し続けないと古びます。
用語集と同じ関数を使った
この処理は、用語集の検索ですでに書いてありました。
そのままコピーすることもできましたが、コピーした側は直されません。片方の揺れを直したときに、もう片方は古いままになります。共通の場所に出して、両方から呼ぶようにしました。
関数を1つ切り出すだけの作業ですが、2箇所目が現れた時点でやっておかないと、3箇所目が現れたときにはもう誰も揃えません。
0件のときに、何を出すか
最後まで残ったのがこれでした。
「見つかりませんでした」とだけ出すのは、行き止まりです。探しに来た人を、何も持たせずに帰らせることになります。
このサイトには用語集があります。記事名では見つからなくても、語の説明としては存在していることが十分あり得ます。0件のときは、その語で用語集を引く導線を出すようにしました。
0件は失敗ではなく、「その言葉では記事が無い」と分かった状態です。次に行ける場所を1つ添えるだけで、意味が変わります。
今回の学び
まず、すでに手元にあるものを数えること。検索と聞くと問い合わせる仕組みを想像しますが、一覧ページはもう全記事を持っていました。持っているものを使えば、増える部品はゼロです。
次に、機能を足すときは何と引き換えかを書くこと。本文まで検索できるようにすると、一覧の表示が遅くなります。多いほうを犠牲にして少ないほうを便利にしていないか、毎回確かめる価値があります。
そして、同じ処理が2箇所目に現れたら、その時点で1つにすること。コピーした側は直されません。3箇所目が現れてからでは遅すぎます。
最後に、0件にも行き先を用意すること。見つからなかったという事実は、それ自体が次の手がかりになります。
関連記事

読む邪魔をしない
貼り付いたヘッダーと目次が、読んでいるあいだずっと画面を占めていた。下へ読むときは引っ込むヘッダー、スクロール中だけ薄くなる目次、先頭へ戻るボタン。3つの判断の記録。

届かない問い合わせ
問い合わせフォームで決めることは3つあった。メールアドレスを載せるか、送信先が未設定のときフォームを出すか、失敗をどう伝えるか。共通していたのは「うまくいったように見えて、実は何も起きていない」状態をどう避けるかだった。

1語1ページにしなかった理由
用語集を作るとき、1語につき1ページにするか、まとめて1ページにするか。解説を厚くすると決めた時点で前提が変わり、最初の判断を見直すことになった。薄いページを大量に作るリスクと、本番のPHPを触れないという制約から、分野別8ページという形にたどり着いた記録。