Nodejsでwebフロントエンドの性能を分析する(window.performance)
8447 ワード
nodejsでは、pppeteerを通じてウェブページのwindow.performanceオブジェクトを取得し、ページの性能を分析します.下に直接コードを入れます.
const puppeteer = require('puppeteer');
const path = require("path");
const logger=require("./log");
const log = logger.getPuppeteerRecordLogger() ;
/*
*/
async function launchBrowser(){
// [puppeteer.createBrowserFetcher([options])]
let browser = await puppeteer.launch({
// chromium chromium , / /node_modules/puppeteer/.local-chromium/
//executablePath: '/Users/huqiyang/Documents/project/z/chromium/Chromium.app/Contents/MacOS/Chromium',
// https https
ignoreHTTPSErrors: true,
// headless ,
headless: true,
// https://peter.sh/experiments/chromium-command-line-switches/ --timeout
args:['--disk-cache-size=0','--disable-cache','--disable-infobars','--window-size=800,600','--ignore-certificate-errors','--enable-feaures'],
// DevTools 。 true, headless false。
devtools: false,
//Defaults to 30000 (30 seconds). Pass 0 to disable timeout.
timeout: 0
// puppeteer ,
//slowMo: 250
});
return browser ;
}
async function saveHarlog(url,dirPath,filename){
let homesite = url ;
//
let harFilePath = path.join(dirPath,filename) ;
// URL
if(!(url.startsWith('http://') || url.startsWith('https://'))){
url = "http://" + url ;
}
//
let browser = await launchBrowser() ;
//
//let page = await browser.newPage();
const page = (await browser.pages())[0];
try{
await page.goto(url,{
timeout:0
});
/*
page window.performance.timing
*/
const timing = await page.evaluate( _ => {
const {navigationStart,unloadEventStart,unloadEventEnd,
redirectStart,redirectEnd,fetchStart,domainLookupStart,
domainLookupEnd,connectStart,connectEnd,secureConnectionStart,
requestStart,responseStart,responseEnd,domLoading,domInteractive,
domContentLoadedEventStart,domContentLoadedEventEnd,domComplete,
loadEventStart,loadEventEnd} = window.performance.timing;
return ({navigationStart:navigationStart,
unloadEventStart:unloadEventStart,
unloadEventEnd:unloadEventEnd,
redirectStart:redirectStart,
redirectEnd:redirectEnd,
fetchStart:fetchStart,
domainLookupStart:domainLookupStart,
domainLookupEnd:domainLookupEnd,
connectStart:connectStart,
connectEnd:connectEnd,
secureConnectionStart:secureConnectionStart,
requestStart:requestStart,
responseStart:responseStart,
responseEnd:responseEnd,
domLoading:domLoading,
domInteractive:domInteractive,
domContentLoadedEventStart:domContentLoadedEventStart,
domContentLoadedEventEnd:domContentLoadedEventEnd,
domComplete:domComplete,
loadEventStart:loadEventStart,
loadEventEnd:loadEventEnd})
})
log.info('--->' + JSON.stringify(timing)) ;
if(timing){
//long 。 (unload) UNIX 。 , fetchStart 。
let navigationStart = timing.navigationStart ;
//long . unload UNIX , , 0
let unloadEventStart = timing.unloadEventStart ;
//long , unload UNIX 。 , 0
let unloadEventEnd = timing.unloadEventEnd ;
//long , HTTP UNIX 。 , , 0.
let redirectStart = timing.redirectStart ;
//long , HTTP ( HTTP ) UNIX 。 , , 0.
let redirectEnd = timing.redirectEnd ;
//long , HTTP (fetch) UNIX 。 。
let fetchStart = timing.fetchStart ;
//long , UNIX 。 (persistent connection), , fetchStart 。
let domainLookupStart = timing.domainLookupStart ;
//long , UNIX 。 (persistent connection), , fetchStart 。
let domainLookupEnd = timing.domainLookupEnd ;
//long , HTTP Unix 。 (persistent connection), fetchStart 。
let connectStart = timing.connectStart ;
//long , Unix 。 , fetchStart 。 。
let connectEnd = timing.connectEnd ;
//long , Unix 。 , 0
let secureConnectionStart = timing.secureConnectionStart ;
//long , HTTP ( ) Unix
let requestStart = timing.requestStart ;
//long , ( ) Unix 。 , 。
let responseStart = timing.responseStart ;
//long , ( , ) ( HTTP , ) Unix 。
let responseEnd = timing.responseEnd ;
//long , DOM ( Document.readyState “loading”、 readystatechange ) Unix 。
let domLoading = timing.domLoading ;
//long , DOM 、 ( Document.readyState “interactive”、 readystatechange ) Unix
let domInteractive = timing.domInteractive ;
//ong , DOMContentLoaded , Unix
let domContentLoadedEventStart = timing.domContentLoadedEventStart ;
//long , ( ) Unix
let domContentLoadedEventEnd = timing.domContentLoadedEventEnd ;
//long , , Document.readyState 'complete' readystatechange Unix
let domComplete = timing.domComplete ;
//long , ,load Unix 。 , 0
let loadEventStart = timing.loadEventStart ;
//long , load , Unix 。 , , 0
let loadEventEnd = timing.loadEventEnd ;
//
//let navigation = performance.navigation ;
}
}catch(error){
log.info('resovle error :' + url + "; error message:" + error) ;
}finally{
if(browser){
await browser.close();
}
}
}
exports.launchBrowser = launchBrowser;
exports.saveHarlog = saveHarlog;
指標の説明//@param t -> timing
async function getPerformanceTiming (t) {
if (!t) {
log.info('not allow null');
return;
}
var times = {};
//【 】
//【 】
times.loadPage = t.loadEventEnd - t.navigationStart;
//【 】 DOM
//【 】 DOM !
times.domReady = t.domComplete - t.responseEnd;
//【 】
//【 】 ! ,http://example.com/ http://example.com
times.redirect = t.redirectEnd - t.redirectStart;
//【 】DNS
//【 】DNS ? ?
// HTML5 Prefetch DNS , :[HTML5 prefetch](http://segmentfault.com/a/1190000000633364)
times.lookupDomain = t.domainLookupEnd - t.domainLookupStart;
//【 】
//【 】 , , CDN ? ? CPU ?
// TTFB Time To First Byte
// :https://en.wikipedia.org/wiki/Time_To_First_Byte
times.ttfb = t.responseStart - t.navigationStart;
//【 】
//【 】 gzip , css/js ?
times.request = t.responseEnd - t.requestStart;
//【 】 onload
//【 】 onload , 、 ?
times.loadEvent = t.loadEventEnd - t.loadEventStart;
// DNS
times.appcache = t.domainLookupStart - t.fetchStart;
//
times.unloadEvent = t.unloadEventEnd - t.unloadEventStart;
// TCP
times.connect = t.connectEnd - t.connectStart;
return times;
}