>100 Views
November 30, 17
スライド概要
地図表示系サイトの開発知見について
LIFULL HOME'Sを運営する株式会社LIFULLのアカウントです。 LIFULLが主催するエンジニア向けイベント「Ltech」等で公開されたスライド等をこちらで共有しております。
HOMEʼSのサイト開発 @なかじま
自己紹介 名前 なかじまたくや (勤続7年目くらい) 普段の業務内容 サイトの機能開発を自由にやってます 得意な領域 フロントエンド(主にJS)だけど、一人プロジェクト多いのでだ いたいどこの領域もやることが多いです
今日の話
ユーザー視点の開発… は、僕は特にしてないので 語れることはなかった UX界隈の人すぐ斧なげるから怖い
代わりに地図系のサイト作っ た時に得た知見とかの話 僕の思う「使い勝手」を追い求めてみた話
地図系のサイト
緯度経度で何か検索して地図上に表 示させるよくあるやつ
地図検索系あるある • 地図検索系ってそんなにバリエーションがないから 結構共通の苦悩と戦うことになると思う
あるある1 • 検索クエリ(緯度経度)が毎回違うから検索エンジン 側のキャッシュが効かなくてパフォーマンスでない \ちょっと移動/ 検索クエリ(緯度経度) が微妙にかわる
あるある2 • 地図移動前と移動後で表示領域のかぶり多いのに全 部検索しなおたりして無駄だなーって憂鬱になる この部分は 前の表示領 域一緒なの に・・・ \ちょっと移動/
あるある3 • 超でかいディスプレイで操作されると検索範囲広がっ てパフォーマンスでない(スケールとかの恩恵受け辛い ) 一回の検索範囲が大きい いくつかに分けたい…
あるある4 • マーカーとかポリライン沢山ひくとなんか動作がほ んのりもっさくなる
Google Maps自身はあんなに シームレスでサクサクなのに!
僕らもサクサクでストレスレ スなユーザー体験を提供した い!!
なんでそんなサクサク うごくの(*?̲?*) Google Mapsの実装を探る
基本編
Google Mapsはいかにして継ぎ 目のない描画を実現しているの か
地図そのものの表示
小さな画像をタイル状に敷 き詰めて表示させてる
彼らは地図をタイルごとに読み込 むことで、地図の移動時に差分と なるタイルだけを描画している
タイルについて考える zoom lv. 1 zoom lv. 0 0,0 1,0 0,1 1,1 0,0
タイルの開始点 緯度経度: (85.05112877980659,-180) 赤道を256pxとして表現する時に いい感じに収まる座標
pixel座標と緯度経度の変換
function fromLatLngToPoint(lat, lng) {
var x, y;
x = (lng + 180) / 360 * 256;
y = ((1 - Math.log(Math.tan(lat *
Math.PI / 180) + 1 / Math.cos(lat *
Math.PI / 180)) / Math.PI) / 2 *
Math.pow(2, 0)) * 256;
return {x: x, y: y};
}
function fromPointToLatLng(x, y) {
var lat, lng, n;
lng = x / 256 * 360 - 180;
n = Math.PI - 2 * Math.PI * y / 256;
lat = (180 / Math.PI * Math.atan(0.5 *
(Math.exp(n) - Math.exp(-n))));
return {lat: lat, lng: lng};
}
ってstack overflowが
言ってたよ
中級編
Markerとかってどうやってるの
Markerを調べる
MarkerはCanvasで作られてい た
複数のmarkerでも収まれば 1つのcanvasで表示 → 省エネ
PolyLine & Polygon
Google Maps APIのだいたいの やつはCanvasで作られていた ぐう有 能 Markerとか一つ一つ要素 作ってstyle当ててたらコ スト高すぎてこのパフォー マンスは実現できない
canvasでの描画 • 大量のDOMを作るよりタイルシステムの規格通り のcanvas作ってその上で描画する方がコストが低 い • でも、描画情報しかないんならmarkerクリックで きないのでは??????? • クリックできたりhoverしたらカーソルがかわった りするけど???????
canvasとマウスアクション カーソルがcanvas上のマーカー描画位置にきたら 地図コンテナ自身のcursor値を変更してる!!!!
canvasとマウスアクション canvasあるいはそれより上位の要素にイベントを割 り当てて、mousemove時に座標判定して該当マーカ ーがある時に処理するというガチなやつで実装してる みたい デフォルトのpoiとかは 時々リクエストに紛れ てるこいつらがが座標 情報なんじゃないかな
融通効かないとこ でもその割に、1マーカーに1つ ずつevent設定していくしかない のはもったいないような… 全部のマーカーに共通の イベント張る時とかコストが勿 体ない
まぁなにはともあれ
この辺の仕組みが地図アプリの パフォーマンスの肝になってる • タイル化することで とかも可能になる • 何かを検索して地図上にプロットする系のサイトもタイ ルごとに検索を行えば同タイルの時に発生するリクエス トは全部同じ座標になるためある程度Cacheできる • MarkerのCavans化も自前でやっちゃえばイベントハン ドラ周りとか、さらにいい感じに省エネ化できる
サクサクさせるために模倣する • Google Mapsのタイル規格と同じタイルのレイヤ を作り、それぞれマーカーCanvasを自作する \きえた/
実際の仕上がりと操作感 継ぎ目ない感じでてる! 検索もキャッシュ効くからはやい!
操作感をより上げるための細 かいチューニング • 単純にcanvas化しまくるとどこかでメモリ溢れるから描 画領域から離れたタイルは描画座標だけ記憶してすぐ復元 できる状態だけ作って消したり • retina対応とかは解像度みてやる必要があるか判定したり • 検索エンジン側(solr)でfilter query利用してcacheできる ようにしたり
二度と同じ実装したくないのでライブラリ化
そんな感じで日々HOMEʼSの中の人 は自分の思う「よりよい使い勝手」 を探し求めて今日も実装しています 終わり
1 more slide
ネクストではいい感じの iOSエンジニアとWebエンジニア を 募集しています! 本当におわりです!