ANTIGRAVITY LABEN
記事一覧/Editor View
Editor View/2026-09-06中級

補完が戻らない朝に数えてみたら、コードはリポジトリの 1.4% でした

Antigravity で補完が返らないとき、言語サーバーを再起動しても戻らないことがあります。遅い場所を3つの層に分けて数え、除外パターンが本当に効いているかを判定器に聞くまでの手順を、実測値つきで書き残します。

antigravity454language-server2lsp3workspace8typescript28antigravityignore2

記事の一覧ページを直していた朝、途中から補完が返ってこなくなりました。型情報のツールチップも空のままです。言語サーバーを再起動すると数分だけ戻り、また同じところで沈みます。三度目の再起動を押したところで手が止まりました。

原因を設定ファイルの中に探していたのですが、私が一度も見ていなかったのは、もっと手前にある数でした。エディタが抱えているファイルが何本あるのか、その中でコードが何本なのかを、私は一度も数えていなかったのです。

その朝に走らせたコマンドと、出てきた数字をそのまま書き残します。

再起動が効かない朝は、遅い場所を取り違えています

補完が返らないとき、私たちはつい「言語サーバーが重い」と一括りにしてしまいます。ところがエディタの中では、少なくとも三つの層が別々の母数を見ています。

対象を決めているもの再起動で母数が変わるか
言語サーバーのプロジェクトtsconfig.json の include / exclude変わりません(設定が同じなら同じ範囲を読み直します)
ファイル監視とワークスペース索引ワークスペースのルートと除外設定変わりません
エージェントのコード検索追跡ファイルと .antigravityignore変わりません

どの層が詰まっているのかは、症状の出方で見当がつきます。補完だけが返らず検索は普通に動くなら一番目、ファイルを保存した直後に全体が固まるなら二番目、エージェントに調べ物を頼んだときだけ長く待たされるなら三番目です。三つが同時に重いときは、たいてい共通の母数のほうに原因があります。

三つとも、再起動では母数が動きません。動くのは状態だけです。ですから再起動で数分だけ戻るという症状は、「状態は作り直せているのに、抱えている量が多すぎて同じ場所へ戻ってしまう」と読むほうが素直でした。

再起動は症状に、除外は母数に。 この線引きを置いてから、私は朝いちばんに数を取るようになりました。

まず、リポジトリを数えます

数えるのはひと言で終わります。追跡ファイルの総数と、その中でコードが何本かを並べるだけです。

# 追跡ファイルの総数
git ls-files | wc -l
 
# 拡張子の内訳(上位だけ)
git ls-files | sed 's/.*\.//' | sort | uniq -c | sort -rn | head -8

私が触っているのは、記事を MDX で持っている Next.js のサイトです。出てきたのが次の表です。

区分ファイル数バイト数全体に占める割合(バイト)
追跡ファイル全体2,30034,383,649100%
.ts.tsx71470,5101.4%
content/ 配下(MDX)2,18331,874,97892.7%
content/public/content/ を除いた残り1172,523,1527.3%

ファイル数とバイト数は、必ず並べて見るようにしています。どちらか一方だけでは、重さの出どころを取り違えるからです。

区分ディレクトリ数ファイル数1 ファイルの平均
content/222,183約 14,600 バイト
src/4174約 6,600 バイト

content/ は 22 のディレクトリに 2,183 ファイルが詰まっています。ディレクトリ単位で張られる監視から見れば軽く、ファイル単位で回る索引から見れば重い、という偏った形です。「監視は問題ないのに索引だけ終わらない」という症状は、こういう形から出てきます。

ここで気持ちが切り替わりました。言語サーバーのプロジェクトは 71 ファイルしかありません。tsconfig.json の include は **/*.ts**/*.tsx なので、MDX は一本も読まれていないのです。

つまり、私が三度も再起動していた相手は、そもそもいちばん軽い層でした。重かったのは、拡張子を選ばずに全部を抱える二番目と三番目の層です。

読み切るだけで何ミリ秒かかるのかを、床として持っておきます

母数が効いているかどうかは、いちばん素朴な指標で足ります。全ファイルを開いて読むだけの時間です。解析も索引も何もしない、下限の数字です。

import subprocess, time
 
out = subprocess.run(["git", "ls-files", "-z"], capture_output=True).stdout
files = [f.decode() for f in out.split(b"\0") if f]
code = [f for f in files if f.endswith((".ts", ".tsx", ".mjs", ".js"))]
 
def read_all(paths):
    start = time.perf_counter()
    for p in paths:
        with open(p, "rb") as h:
            h.read()
    return time.perf_counter() - start
 
for label, paths in (("all", files), ("code-only", code)):
    runs = sorted(read_all(paths) for _ in range(5))
    print(f"{label:10s} n={len(paths):5d} best={runs[0]*1000:.1f}ms median={runs[2]*1000:.1f}ms")

私の環境での出力です。

all        n= 2300 best=28.8ms median=29.4ms
code-only  n=   76 best=0.8ms median=0.8ms

三十六倍でした。ただし、この数字の読み方には注意が要ります。これはページキャッシュが温まった状態で、開いて読むだけの床です。構文解析・索引・埋め込みの生成は、すべてこの上に積み上がります。初回起動や監視イベントが連続する場面では、この床の何十倍にもなります。

ですから私は、この数字を速度の証明としては使いません。体感で速くなった気がする、という判断を、私はあまり信用できなくなったと感じています。除外を書く前と後で同じコマンドを走らせて、母数がどれだけ落ちたかだけを見ています。効いたか効かなかったかが、体感ではなく差分で分かるからです。

除外を書いたのに効かなかった理由は、角括弧でした

さて、除外を書きます。.antigravityignore は gitignore と同じ書式ですから、書いたパターンが本当に当たるかどうかは git 自身に聞けます。判定器に聞くのがいちばん早いのです。

# 一時ファイルにパターンを 1 行だけ書いて、当たり判定を確かめる
printf '%s\n' 'src/app/[locale]/' > /tmp/probe-ignore
git -c core.excludesFile=/tmp/probe-ignore \
    check-ignore --no-index -v 'src/app/[locale]/HomeClient.tsx'

何も返ってきませんでした。当たっていません。念のため、当たらないはずのパスも並べて確かめた結果が次の表です。

パターンsrc/app/[locale]/HomeClient.tsxsrc/app/l/HomeClient.tsxsrc/app/x/page.tsx
src/app/[locale]/当たりません当たります当たりません
src/app/\[locale\]/当たります当たりません当たりません
**/[locale]/**当たりません当たります当たりません

角括弧が文字クラスとして解釈されていたのです。原因がパターンの書式ではなく記号の意味にあると気づいたのは、判定器へ一行ずつ聞き直したあとでした。[locale] は「l・o・c・a・e のいずれか一文字」を意味しますから、src/app/l/src/app/c/ には当たり、本物の src/app/[locale]/ には当たりません。除外したかったものは残り、意図していなかったディレクトリのほうが消えていた、という順序でした。

App Router を使っていると、この角括弧はあちこちに現れます。私のリポジトリでは、追跡ファイルのうち 21 本のパスに角括弧が含まれていました。[category][slug] も同じ扱いです。

書き直すなら、バックスラッシュでエスケープするか、角括弧を含まない上位のディレクトリを指定します。そして書いたあとは、残った側を一度数えます。

# 除外を適用したあとに何本残るかを数える
TOTAL=$(git ls-files | wc -l)
IGN=$(git ls-files -z \
      | git -c core.excludesFile=/tmp/probe-ignore check-ignore --no-index --stdin -z \
      | tr -cd '\0' | wc -c)
echo "tracked=$TOTAL ignored=$IGN remaining=$((TOTAL-IGN))"

content/public/content/ の二行だけを書いたとき、私の手元では tracked=2300 ignored=2183 remaining=117 になりました。落ちた量が想定と合っているかは、この一行で確かめられます。

パターンの当たり判定そのもので詰まったときは、「.antigravityignore が効いていないときに疑う4か所」に、スラッシュの位置や否定パターンの順序をまとめてあります。あわせて読んでいただけると、原因の切り分けが早くなるはずです。

測り方も一言だけ添えておきます。私は五回走らせて最良値と中央値の両方を出しています。一回だけでは、ちょうど別のプロセスが走っていた瞬間を掴んでしまうことがあるからです。二つの値が離れているときは、母数ではなく同時に動いている何かを先に疑います。

そして、全体と code のみの差がほとんど無いのなら、母数は原因ではありません。そのときは一本の巨大なファイルや、生成された長い行を含むファイルを探すほうへ切り替えます。同じ 30 ミリ秒でも、二千本に分散しているのか一本に偏っているのかで、打つ手はまったく変わってきます。

除外してよい場所と、あえて残す場所

母数が分かると、次は「どこまで外すか」を決めることになります。私は三段に分けて考えています。

区分扱い
生成物.next/out/、ビルド出力、カバレッジ迷わず外します(消えても書き直せます)
依存node_modules/多くの設定で既定から外れています。二重に書く必要はありません
自分で書いた資産content/ の MDX、設計メモ外す前に、検索できなくなって困らないかを確かめます

三段目でいちど失敗しました。content/ をまとめて外したところ、エージェントに「同じ題材の記事が既にないか」を探させたときに、一本も見つからなくなったのです。母数は軽くなりましたが、私がいちばん頻繁に頼んでいた仕事のほうが動かなくなりました。

外す前と後で、実際に使う検索をひとつ走らせておくと、この取り違えを避けられます。

# 除外を書く前に、当てにしている検索が何件返るかを控えておく
git grep -l 'antigravityignore' -- content/articles/ja | wc -l

私の手元では 26 件でした。除外を入れたあとに同じ数が返らなければ、外しすぎです。

もうひとつ気をつけているのが、除外設定を役割ごとに分けておくことです。ファイル監視を軽くしたいのか、エージェントの検索母数を絞りたいのかで、書くべき場所は違います。同じ数行を両方へそのままコピーすると、片方では効きすぎ、片方では足りない状態になりがちでした。

いま置いている線引き

数え直してから、私の朝の手順は短くなりました。補完が返らないときは、まず追跡ファイルの総数とコードの本数を並べます。二桁の開きがあれば、原因は言語サーバーではなく、その周りで全部を抱えている層のほうにあります。

一方で、コードそのものが数千本ある本物の大規模リポジトリでは、話が逆になります。同じ症状に見えても、原因は真逆かもしれません。そのときは除外ではなく tsconfig.json の include を絞る側の問題です。どちらなのかを決めるためにも、最初の一回だけは数える価値があります。

今日できることを一つだけ挙げるなら、git ls-files | wc -l と、.ts.tsx の本数を、同じ画面に並べて書き出すことです。エディタを離れずに走らせたい場合は、「Antigravity 2.10.0 の埋め込みターミナルで、エージェントの変更を検証するループを組む」で触れた内蔵ターミナルが便利です。

私はこの二つの数字を書き留めてから、除外を一行書くようにしています。最後までお読みくださり、ありがとうございました。

シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Editor View2026-04-21
Antigravity IDE で言語サーバー(LSP)が応答しない・補完が効かない時の診断フロー
Antigravity IDE で TypeScript・Pylance・gopls などの言語サーバーが急に応答しなくなった時の診断手順を、原因別に整理しました。拡張機能の競合・設定ファイルの破損・メモリ不足まで実例つきで解説します。
Editor View2026-05-07
Antigravity で「参照の検索(Find References)」が抜ける・空になる時の修正手順
Antigravity IDE の Find References が空のまま結果を返さない、あるいは一部のファイルだけ抜ける現象を、TypeScript・Python・モノレポの典型パターン別に診断して直す手順をまとめました。
Editor View2026-07-08
Antigravity がクラウド同期フォルダのファイルを空として読む問題—オンラインオンリー・プレースホルダーの落とし穴
Finder には確かに見えているファイルを、Antigravity のエージェントが「空」「見つからない」と言い張る――クラウド同期フォルダのオンラインオンリー・プレースホルダーが原因です。症状の見分け方から実体の取得、作業フォルダの設計までを順にまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →