Могу ли я использовать браузер Navigation Timing API для событий Ajax в одностраничных приложениях? Если нет, какой хороший инструмент?
У нас есть одностраничное приложение, созданное с использованием Knockout и Backbone, которое выполняет Ajax-вызовы на сервер и выполняет некоторое сложное кэширование данных и рендеринг DOM. Мы действительно хотели бы измерить производительность (и записать ее обратно на сервер) с точки зрения пользователя. Кажется, я не могу понять, будет ли для этого полезен API-интерфейс синхронизации навигации браузера. Из того, что я вижу в примерах, API синхронизации навигации связан с window.performance
и это ограничено загрузкой страницы и не подходит для мониторинга поведения Ajax. Правда или ложь? Если ложь, что еще я могу использовать?
Я хотел бы установить пользовательские контрольные точки, между которыми нужно измерять время, например, для вызова Ajax, который выполняет некоторый DOM-рендеринг с серверным результатом.
5 ответов
1 - True, window.performance привязан к загрузке страницы. Смотрите пример ниже, который показывает это:
<button id='searchButton'>Look up Cities</button>
<br>
Timing info is same? <span id='results'></span>
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script type="text/javascript">
jQuery('#searchButton').on('click', function(e){
// deep copy the timing info
var perf1 = jQuery.extend(true, {}, performance.timing);
// do something async
jQuery.getJSON('http://ws.geonames.org/searchJSON?featureClass=P&style=full&maxRows=10&name_startsWith=Denv', function() {
// get another copy of timing info
var perf2 = jQuery.extend(true, {}, performance.timing);
// show if timing information has changed
jQuery('#results').text( _.isEqual( perf1, perf2 ) );
});
return false;
});
</script>
Кроме того, даже если бы вы все заработали, у вас бы не хватало данных из старых браузеров, которые не поддерживают этот объект.
2. Похоже, что проект Boomerang выходит за рамки API веб-синхронизации и также поддерживает старые браузеры. Текущий сопровождающий перечислил в этой конференции доклад со слайдами и примером кода. Извините, нет прямой ссылки.
Теперь вы можете использовать API User Timing (Рекомендация W3C от 12 декабря 2013 г.), который позволяет вставлять вызовы API в различные части вашего Javascript, а затем извлекать подробные данные о времени.
Вы делаете это с помощью mark()
он позволяет вам определить, сколько времени вам понадобилось, чтобы достичь этой отметки в вашем веб-приложении, а затем measure()
рассчитать время между вашими отметками.
Для вашего конкретного случая у вас может быть что-то вроде этого:
app.render = function(content){
myEl.innerHTML = content;
window.performance.mark('end_render');
window.performance.measure('measure_render', 'start_xhr', 'end_render');
};
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onload = function(e) {
window.performance.mark('end_xhr');
window.performance.measure('measure_xhr', 'start_xhr', 'end_xhr');
app.render(e.responseText);
}
window.performance.mark('start_xhr');
myReq.send();
Кажется, есть неоднозначная поддержка window.performance.getEntries()
, который даст вам подробную информацию обо всех ресурсах, загруженных на страницу, вместе с их URL. Я использую этот API для запросов jsonp (не XMLHttpRequest) в http://azureping.info/ для браузеров, которые его поддерживают, возвращаясь к new Date().getTime()
для тех, кто этого не делает.
На момент написания статьи поддержка IE 10 и Chrome getEntries
, но Firefox нет. К сожалению, не все свойства синхронизации установлены - даже в Chrome и IE. Все, на что я мог положиться, было fetchStart
, responseEnd
, а также duration
,
Пример источника на GitHub.
API синхронизации навигации, на мой взгляд, не очень полезен для измерения производительности одностраничных приложений.
Наряду с уже упомянутым API синхронизации пользователя, API синхронизации ресурсов на самом деле гораздо более полезен. Этот API-интерфейс предоставляет функциональные возможности для получения времени для всех запросов, сделанных в пользовательском сеансе (фактически, все, что вы видите на сетевых вкладках инструментов разработчика в большинстве браузеров). Эти сроки включают в себя время приема-передачи, а также время поиска DNS и т. Д.
К сожалению, это относительно новая спецификация, которая еще не реализована во всех браузерах. Chrome и IE > 10 обеспечивают реализации (хотя еще не завершены). Удивительно, но IE, кажется, реализовал большинство модулей сейчас...
Есть два способа сделать это
- API синхронизации ресурсов
- Упаковка XMLHTTPRequest
Давайте посмотрим на различия между ними.
1. Resource Timing API
Браузеры недавно добавили поддержку Resource Timing API. Resource Timing API в основном содержит информацию о времени для всех ресурсов, загружаемых из приложения. Это могут быть запросы CSS, Javascript или AJAX. Вы можете получить список ресурсов как
performance.getEntriesByType('resource');
Он вернет массив объектов, где вы можете найти AJAX-запросы initiatorType
который равен xmlhttprequest
, Но есть некоторые ограничения.
- По умолчанию максимальный размер ресурса равен 150. Выше массива может быть максимум 150 ресурсов. Если вы хотите больше, вы можете увеличить размер буфера как
performance.setResourceTimingBufferSize(500)
, - Вы не получите информацию о том, успешно ли выполнены запросы AJAX или нет.
2. Упаковка XMLHTTPRequest
Если вы сможете обернуть свой API-интерфейс XMLHTTPRequest, вы получите всю необходимую вам информацию о времени, коде состояния и размере байта. Но вы должны написать много кода и конечно тест, тестирование и тестирование.
[Отказ от ответственности] Я работаю на https://www.atatus.com/, где мы помогаем вам измерить время загрузки страницы, время AJAX и пользовательские транзакции. Также вы можете увидеть следы сессий о том, как работают все ресурсы.