文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

Google Maps Apiで地図描画時のRobotoフォントの読み込みをスキップしてちらつきを回避する

実は罠が潜んでいたのだ!
f:id:treeapps:20170704003408p:plain

今日は小ネタです。

みんな大好きGoogleMapですが、実はちょっとした罠が潜んでいます。

罠を確認する

まずはこれを見て下さい。

f:id:treeapps:20170704003740g:plain

「プロット」ページはGoogle Mapを読み込んでいます。

そのプロットのリンクをクリックした瞬間、一瞬なんかちらつきましたね。これです。

tree-mapsではフォント指定していないのでシステムデフォルトのフォントが指定されますが、デフォルトフォントがRobotoに置き換わる様子が見えますね。

何が起きているか

new google.maps.Map で地図をロードした際に、実はheadセクション内に以下のタグが自動挿入されます。

<link type="text/css" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">

これがあるせいで、画面全体のフォントが一瞬Robotoフォントに置き換わってしまい、フォントが切り替わる様子がちらついて見えていたわけです。

ちらつくわ、不要なRobotoフォントのロード時間が加算されるわで、正直あまりいい事がありません。

f:id:treeapps:20170704012822p:plain

60ms程度で読み込めてはいますが、問題なのはそこではなく、ダウンロードしたフォントを画面に適用すると、layout(reflow)が発生します。reflowはレンダリングプロセスの中でも高コストな処理で、画面描画をかなり遅くさせる要因の一つになります。なので、可能であればreflowを起こさない方がよいです。

Robotoフォントの読み込みを抑制する

stackoverflow.com

困った時のStackOverflow氏〜(他力本願)

arrow funcionを使ったりしてちょっと改良すると↓こんな感じです。

const head = document.getElementsByTagName('head')[0]
const insertBefore = head.insertBefore
head.insertBefore = (newElement, referenceElement) => {
    if (newElement.href && newElement.href.indexOf('https://fonts.googleapis.com/css?family=Roboto') === 0)
        return
    insertBefore.call(head, newElement, referenceElement)
}

これを、new google.maps.Mapする前に書いておけばOKです。

Robotoフォントの読み込み抑制の結果

f:id:treeapps:20170704004548g:plain

f:id:treeapps:20170704013519p:plain

ちらつかなくなり、更に不要なフォント読み込みをスキップした事で、ページの読み込み速度も早くなりましたね!

雑感

Google Maps Apiさん、グローバル領域であるheadセクションにズガンとフォント挿入するのやめて貰っていいですかね〜?