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以外にもいろいろな値が取れるようです
詳細な仕様はこちら
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); }
実行結果
Beacon
Beaconをメッセージ付きで非同期で送ることができます。
navigator.sendBeacon("http://twainy.github.io/tuning-blog/beacon.html", "beaconmessage");
POSTメッセージとして送られるようです。ユーザ動作無しでPOSTデータ流せるのでCSRFチェックしておかないとセキュリティ上若干危険な感じもしますね。
Animation Timing
setTimeOutやsetIntervalではないくrequestAnimationFrameを使うとCPU使用率や電力消費などが有利になります
画面のリフレッシュレートなども考慮した処理がおこなわれるらしいです。
http://ie.microsoft.com/TEStdrive/Graphics/RequestAnimationFrame/Default.html#
Resource Hints
リソースにヒントを与えることでリソースの取得タイミングを調整することができます
<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については指定することができません
参考文献
- Fast-Forward Performance http://calendar.perfplanet.com/2014/fast-forward-performance-the-future-looks-bright/
- Web Performance API http://www.w3.org/wiki/Web_Performance/Publications
- Preconnect, Prefetch, Prerenderer https://docs.google.com/presentation/d/18zlAdKAxnc51y_kj-6sWLmnjl6TLnaru_WH0LJTjP-o/edit#slide=id.g33a803cd_4_320