GIS開発研究所 > GeoJSONが10万件を超えて地図表示が重いときの改善方法|MVTへの切り替え
2026年7月28日
•約7分で読めます
大量のGeoJSONでWeb地図が重くなる原因を、通信量、地物数、頂点数、描画時間から切り分けます。不要属性の削減、形状簡略化、クラスタリングを試し、それでも全件配信が重い場合にMVTへ移行する判断基準と段階的な構成、本番運用の確認点を紹介します。
Web地図にGeoJSONを読み込んだところ、初回表示に時間がかかる、ズームすると固まる、スマートフォンではページが落ちる。このような問題は、地物の件数だけでなく、座標の頂点数、属性の数、スタイルの複雑さが重なって起きます。
「10万件を超えたら必ずMVT」という固定の基準はありません。まず通信量とブラウザ側の処理を計測し、GeoJSONのまま改善できる範囲を確認します。それでも全件配信がボトルネックになる場合は、表示範囲とズームに応じて必要な地物だけを返すMVTへ切り替えます。
改善は次の順番で進めると、原因を見失いにくくなります。
GeoJSONは扱いやすく、少量データや編集用途に向いています。一方、MVTは地図をタイル状に分割し、現在の表示範囲に必要なデータだけを配信できます。広域かつ大量の閲覧用途では、MVTのほうが負荷を制御しやすくなります。
ブラウザの開発者ツールを開き、NetworkとPerformanceで次を確認します。
| 確認項目 | 見るポイント |
|---|---|
| 転送サイズ | 圧縮後でも数MB以上を毎回取得していないか |
| 地物数 | 初期表示に不要な地物まで全件返していないか |
| 頂点数 | 複雑な道路や行政界を細かい形状のまま返していないか |
| 描画時間 | 通信後にスタイル計算や描画で長く止まっていないか |
件数が少なくても、1つのポリゴンに数十万の頂点があれば重くなります。逆に、単純な点データで属性が少なければ、10万件でも端末や表示方法によっては扱える場合があります。
サーバー側では、返却件数とGeoJSONのバイト数をログへ残しておくと、データ増加による劣化を追いやすくなります。
地図上の色分けとラベルに使わない列まで含めると、通信量とブラウザのメモリ使用量が増えます。一覧表示ではID、分類、ラベルなど必要最小限だけを返し、詳細情報は地物をクリックしたときに別APIから取得します。
SELECT
id,
category,
name,
ST_AsGeoJSON(geom)::json AS geometry
FROM facilities
WHERE geom && ST_MakeEnvelope($1, $2, $3, $4, 4326);
表示範囲のBBOXで絞る場合は、geomにGiST空間インデックスがあることも確認します。
CREATE INDEX facilities_geom_gix
ON facilities
USING GIST (geom);
画面表示に不要な細かさまで座標を保持すると、ファイルサイズと描画負荷が増えます。ただし、文字列を単純に丸めるとポリゴンが壊れる可能性があります。元データを残し、表示専用の簡略化済み形状を別列や別テーブルで持つ方法が安全です。
ALTER TABLE administrative_areas
ADD COLUMN geom_web geometry(MultiPolygon, 4326);
UPDATE administrative_areas
SET geom_web = ST_Multi(
ST_SimplifyPreserveTopology(geom, 0.0001)
);
許容値は座標系と用途によって変わります。面積計算や境界判定には元の形状を使い、表示だけを簡略化します。
低いズームで個別の点をすべて描く必要がなければ、クラスタリングでまとめます。MapLibre GL JSのGeoJSON sourceでは、点データにclusterを設定できます。
map.addSource("facilities", {
type: "geojson",
data: "/api/facilities.geojson",
cluster: true,
clusterRadius: 50,
clusterMaxZoom: 13,
});
道路やポリゴンは、ズームごとに表示対象や簡略化レベルを変えます。初期表示では都道府県単位、拡大後に市区町村や設備を取得する構成も有効です。
次の状態が続く場合は、MVTへの移行を検討します。
MVTでは、地図をz/x/yのタイルに分けます。クライアントは画面内のタイルだけを取得するため、全件を一度に読み込む必要がありません。
| 比較項目 | GeoJSON | MVT |
|---|---|---|
| 実装の始めやすさ | 高い | タイルAPIが必要 |
| データ取得 | ファイルやAPI単位 | 表示タイル単位 |
| 大量データ表示 | 全件配信では重くなりやすい | 範囲とズームで制御しやすい |
| 属性の扱い | 柔軟 | タイルへ含める列を選ぶ |
| 編集用途 | 扱いやすい | 閲覧用途が中心 |
| キャッシュ | API単位 | タイル単位で効かせやすい |
移行後も、PostGISの元データを正本として残します。
PostGIS
├─ 一覧表示: MVTタイルAPI
├─ 詳細表示: 地物IDを受け取る詳細API
└─ 更新処理: 認証付きの編集API
MapLibre GL JS
├─ 地図表示: MVT
└─ クリック時: 詳細API
MVTに個人情報や管理用属性を含めると、ブラウザから取得できてしまいます。表示に必要な列だけをタイルへ含め、権限が必要な詳細情報は認証付きAPIへ分離します。
最初からすべてをMVT化する必要はありません。負荷の高いレイヤーだけを切り替え、既存のGeoJSONレイヤーと併用できます。
地物を更新した直後に古いタイルが残る場合は、キャッシュの有効期限や無効化単位も設計します。リアルタイム性が必要なレイヤーと、日次更新でよいレイヤーを分けると運用しやすくなります。
大量データの地図表示は、フロントエンドだけを調整しても改善しないことがあります。データベース、API、タイル、地図スタイルを一緒に計測することが重要です。
BitLightでは、GeoJSONの通信量調査、PostGISのSQL改善、MVTタイルAPI、MapLibreを使ったWeb地図まで一貫して支援しています。
既存の地図が重いものの、どこから直すべきか分からない場合も、現在のデータ量と表示処理を確認して改善順を整理できます。GIS開発を無料相談する
千葉県出身。10歳の頃からプログラミングを始め、ゲーム、Webサイト、ロボット、スマホアプリなどを制作。大阪大学基礎工学部情報科学科で情報工学と統計学を学び、大学時代はAIを研究。大学在学中にWeb広告代理店でのインターンや人材系Webサービスの立ち上げを経験し、卒業後はフリーランスエンジニアとしてGISシステム、データ基盤構築、Webシステムの開発に従事。10年以上のWebアプリ開発・データ分析経験を基に、2023年9月に株式会社ビットライトを設立し、現場業務の仕組み化からデータ基盤構築、データ活用支援までを一気通貫で支援。