巨大なLaravelレポジトリでphpactorを使うTips

Table of Contents

背景・動機

手元で intelephense が最近調子が悪く、定義ジャンプや補完が全然効かなくなってしまった。

phpactorの方がintelephenseよりもちゃんと機能してくれる肌感があったが、いかんせん大きいプロジェクトでは重く使いものにならない印象を持っていた。 しかし、phpactor周辺の設定を徹底したら快適に動くようになってくれたので対応項目をメモしておく。

巨大なLaravelレポジトリの情報は以下。

プロジェクトversionコード行数phpstan level
A7.4140万行超5
B8.240万行max/strict-rule

マシンスペックは以下。

$ nix run nixpkgs#fastfetch

                     ..'          obara@OPL2212-001
                 ,xNMM.           -----------------
               .OMMMMo            OS: macOS Sequoia 15.5 arm64
               lMM"               Host: MacBook Pro (14-inch, 2021)
     .;loddo:.  .olloddol;.       Kernel: Darwin 24.5.0
   cKMMMMMMMMMMNWMMMMMMMMMM0:     Uptime: 1 day, 6 hours, 50 mins
 .KMMMMMMMMMMMMMMMMMMMMMMMWd.     Packages: 1375 (nix-system), 52 (nix-default), 6 (brew), 14 (brew-cask)
 XMMMMMMMMMMMMMMMMMMMMMMMX.       Shell: fish 4.0.2
;MMMMMMMMMMMMMMMMMMMMMMMM:        Display (Color LCD): 3600x2338 @ 120 Hz (as 1800x1169) in 14" [Built-in]
:MMMMMMMMMMMMMMMMMMMMMMMM:        DE: Aqua
.MMMMMMMMMMMMMMMMMMMMMMMMX.       WM: Quartz Compositor 278.4.7
 kMMMMMMMMMMMMMMMMMMMMMMMMWd.     WM Theme: Multicolor (Dark)
 'XMMMMMMMMMMMMMMMMMMMMMMMMMMk    Font: .AppleSystemUIFont [System], Helvetica [User]
  'XMMMMMMMMMMMMMMMMMMMMMMMMK.    Cursor: Fill - Black, Outline - White (32px)
    kMMMMMMMMMMMMMMMMMMMMMMd      Terminal: tmux 3.5a
     ;KMMMMMMMWXXWMMMMMMMk.       CPU: Apple M1 Pro (8) @ 3.23 GHz
       "cooc*"    "*coo'"         GPU: Apple M1 Pro (14) @ 1.30 GHz [Integrated]
                                  Memory: 20.76 GiB / 32.00 GiB (65%)
                                  Swap: Disabled
                                  Disk (/): 153.68 GiB / 460.43 GiB (33%) - apfs [Read-only]
                                  Local IP (en0): 172.16.80.163/18
                                  Battery (bq40z651): 100% [AC connected, Charging]
                                  Power Adapter: 39W
                                  Locale: en_US.UTF-8

なお、phpactorについてはPHPerKaigi2025パンフレット記事の Phpactorから学ぶLanguage Server Protocolの仕組み に纏めた。

試したこと・やったこと

1. PHP Runtime周り

個人的devenv運用 のとおり、devenv(Nix)経由でphpをインストールしている。

  • xdebugをextensionに入れない
  • memory_limit=10G のように十分にメモリを確保しておく
    • memory_limit=-1 はPCが固まるのでオススメできない

PHP8から追加されたJITについて学ぼう! にあるとおりJITを有効にすると高速化するので、8.2の場合は次のようにJITを有効にしている。

{ pkgs, ... }: {
  cachix.enable = false;

  dotenv.disableHint = true;

  env.COMPOSER_MEMORY_LIMIT = "4G";

  packages = with pkgs; [
    phpactor
    php82Packages.psysh
  ];

  languages.php = {
    enable = true;
    package = pkgs.php82.buildEnv {
      extensions = { all, enabled }: with all; enabled ++ [ ];
      extraConfig = ''
        memory_limit=10G

        [opcache]
        opcache.enable=1
        opcache.enable_cli=1
        opcache.jit=tracing ; function
        opcache.jit_buffer_size = 128M
      '';
    };
  };
}

2. phpactor config.json周り

公式サイトでもPerformanceのページがあるが、はっきり言ってこれだけではまったく足りない。

https://phpactor.readthedocs.io/en/master/tips/performance.html

<project-root>/.phpactor.json の設定例は以下。

phpactorはintegrationを提供してくれているが、有効にすると重いのですべてoffにする。

https://phpactor.readthedocs.io/en/master/integrations.html

ポイントはtimeout設定。 textDocument/references をするとすぐtimeoutして候補がまったく出ないので可能な限り長く取る。

{
    "phpunit.enabled": false,
    "language_server_phpstan.enabled": false,
    "language_server_php_cs_fixer.enabled": false,
    "language_server_php_cs_fixer.env": {
        "XDEBUG_MODE": "off",
        "PHP_CS_FIXER_IGNORE_ENV": false
    },
    "php_code_sniffer.enabled": false,
    "completion_worse.experimantal": true,
    "indexer.exclude_patterns": [
        "**/tmp/**/*",
        "**/tests/**/*"
    ],
    "language_server_worse_reflection.workspace_index.update_interval": 5000,
    "language_server.diagnostics_on_update": false,
    "language_server_indexer.workspace_symbol_search_limit": 2500,
    "language_server_reference_reference_finder.reference_timeout": 90,
    "language_server_reference_finder.soft_timeout": 60
}

3. lsp-mode周り

emacs-lsp/lsp-mode の場合になってしまうが、公式のパフォーマンスページを熟読して設定する。

https://emacs-lsp.github.io/lsp-mode/page/performance/

また、emacsはjson packageが遅いのでblahgeek/emacs-lsp-boosterを設定する。

phpactorのtimeoutを伸ばしたのであわせてlsp-modeのtimoutも伸ばす。

(setopt lsp-response-timeout 60)

4. Laravel周り

barryvdh/laravel-ide-helper でメタ情報を増やす。 また、PHPStanを頑張って導入してプロジェクト内に型情報を可能な限り増やし、phpactorの処理を軽減させる。

LSPを立ち上げる前に必ず次のコマンドを叩いてcacheを温めておく。(140万行の方は10分くらいかかる)

$ phpactor index:build -v

得られた結果・所感

140万行のプロジェクトAでも問題なく挙動してくれるようになった。

40万行のプロジェクトBの方はそもそもPHPStanが厳しいので、LSPが正確かつ高速に挙動してくれるので最高。

かなりの設定をoffにした結果とはいえ、phpactorがphp製だから重いというのもチューニング次第だなというのが設定した感想。

今後の展開・検討事項

まだまだチューニングできる部分がないか探して、もっと高速に動かせないか検討する。

プロジェクト内の型情報があればある程有利なので、型情報を増やす活動を積極的にしていきたい。