高速日記

ソフトウェアの高速化・チューニングの話について好き勝手にまとめていくブログです

Web Performance APIについて

Fast-Forward Performance – The Future Looks Bright

を見て使ってみたのでメモを取りました。

テストに使ったのソースコードこのへんです

Navigation Timing

ユーザのネットワーク帯域やページ全体のロード時間の遅延を測るためのAPIです

var perf = performance.timing;
console.log("load elapsed sec: " + (perf.loadEventStart - perf.navigationStart) + "sec");

loadEventStartやnavigationStart以外にもいろいろな値が取れるようです

image

詳細な仕様はこちら

High Resolution Timing

ミリセカンドよりももっと短い秒数を扱うのに利用します

var current_time = performance.now();

便利かと言われると通常のWeb開発ではそこまでの精度は必要ない気もしますね

開発ツール(Chrome Developer Toolとか)のDeveloperにとっては必要な情報かも

Page Visiblity

pageのフォーカスが外れたタイミングでvisiblitychangeイベントが発生します

document.addEventListener('visibilitychange', function(event) {
  if (document.hidden) {
    console.log(“document is not bisible);
  } else {
    console.log(“document is visible);
  }
});

スマホだとCPU時間を消費することによるバッテリー消耗を防ぐのに利用できそうです。

後で紹介するResource Hintでページのprerenderingを指定した場合のJSの実行抑止なども可能です

Resource Timing API

Resourceを取得処理にかかった時間を出力できます

     var img = performance.getEntriesByType("resource")[0];
                var ttfb = parseInt(img.responseStart - img.startTime), // リソースの最初の1byteが返ってくるまでの時間
                        total = parseInt(img.responseEnd - img.startTime); // レスポンスの完了までの時間
                console.log(“Time To First Byte:"+ ttfb + "\n" + "Total Time: " + total);
Time To First Byte:8
Total Time: 10

Performance Timeline

リソース取得時のパフォーマンスを見ることができます

var perf = performance.getEntries();
{
    "responseEnd": 134.0240000281483,
    "responseStart": 132.1299999835901,
    "requestStart": 127.05100001767278,
    "secureConnectionStart": 0,
    "connectEnd": 123.49000002723187,
    "connectStart": 123.49000002723187,
    "domainLookupEnd": 123.49000002723187,
    "domainLookupStart": 123.49000002723187,
    "fetchStart": 123.49000002723187,
    "redirectEnd": 0,
    "redirectStart": 0,
    "initiatorType": "link",
    "duration": 10.534000000916421,
    "startTime": 123.49000002723187,
    "entryType": "resource",
    "name": "http://localhost:63342/tuning-blog/bower_components/bootstrap/dist/css/bootstrap.css"
}

Battery Status

バッテリーの充電量を確認できるらしいです。

Chrome ver39で実行してみましたが、何故か動かず

var battery = 
  navigator.battery || 
  navigator.webkitBattery ||
  navigator.mozBattery ||
  navigator.msBattery;
 
if (battery) {
  console.log("Battery charging? " + battery.charging ? "Yes" : "No");
  console.log("Battery level: " + battery.level * 100 + " %");
  console.log("Battery charging time: " + battery.chargingTime + " seconds");
  console.log("Battery discharging time: " + battery.dischargingTime + " seconds");
};

User Timing

マークした所の実行時時間を取得し、表示することができます

performance.mark("start");
loadSomething();
performance.mark("end");
performance.measure("measureIt", "start", "end");
var markers = performance.getEntriesByType("mark");
var measurements = performance.getEntriesByName("measureIt");
console.log("Markers: ", markers);
console.log("Measurements: ", measurements);        
 
function loadSomething() {
  // some crazy cool stuff here :)
  console.log(1+1);
}

実行結果

image

Beacon

Beaconをメッセージ付きで非同期で送ることができます。

           navigator.sendBeacon("http://twainy.github.io/tuning-blog/beacon.html", "beaconmessage");

POSTメッセージとして送られるようです。ユーザ動作無しでPOSTデータ流せるのでCSRFチェックしておかないとセキュリティ上若干危険な感じもしますね。

image

Animation Timing

setTimeOutやsetIntervalではないくrequestAnimationFrameを使うとCPU使用率や電力消費などが有利になります

画面のリフレッシュレートなども考慮した処理がおこなわれるらしいです。

http://ie.microsoft.com/TEStdrive/Graphics/RequestAnimationFrame/Default.html#

Resource Hints

リソースにヒントを与えることでリソースの取得タイミングを調整することができます

image

<link rel="dns-prefetch" href="//host_to_resolve.com">
<link rel="subresource"  href="/javascript/mydata.json">
<link rel="prefetch"     href="/images/labrador.jpg">
<link rel="prerender"    href="//example.org/page_2.html">

dns-refetchはDomain Nameの事前解決が出来ます

subresourceは現在表示しようとしているページにとって必須のリソースの場合に指定することによって、ロード時にすぐにリソースがフェッチされるようになります。

prefetchは将来的に必要なリソースに使用することが推奨されます。低優先度でデータが取得されます

prerenderは裏でページのレンダリングをします。ページに含まれるアセットも同時に取得されます。ビーコンを指定しているとレンダリング時にカウントされてしまうため、 PageVisibility APIを使用してJSの実行を遅延する必要があります。GETの様な”safe”なページだけ事前レンダリングできます。POSTについては指定することができません

参考文献