Upgrade to Pro — share decks privately, control downloads, hide ads and more …

berserkJs

d2forum
July 18, 2012
20k

 berserkJs

berserkJs是基于 Qt 自行开发的,跨平台的,页面网络请求数据抓取分析自动化工具。它内置 QtWebkit实例,采用JS编写检测用例。可用于在上线前自动检测页面基础性能指标。

d2forum

July 18, 2012
Tweet

Transcript

  1. • 工具由来(需求) • 它能做什么 • 现有工具对比 • 一些特性例子(相对 PhantomJS )

    • 如何得到它 • 怎么使用它 • 使用预制的模块配置功能 • 使用自定义的实现方式 • 实现原理 berserkJS
  2. 能抓自劢页面请求数据么 咱可以用代理抓数据 能在浏览器里操作抓部分数据么 做个浏览器 plugin 并且还能进程控制调用的 命令行化调用浏览器 + plugin…… 能程序控制点挄钮模拟操作么

    = =||| 再辅劣挂个挄键精灵没准成 我的 Mac 能用么,可用 JS 编程控制的 FlashSoft FlashSoft FlashSoft FlashSoft 教主 偶 偶 偶 偶 你妹……
  3. • berserkJS 是基于 Qt (C++跨平台库)开发的前端网络(性能)监测工具。 • 它的核心功能是通过内置 webkit 收集由页面实际网络请求相关数据。 •

    偏重于页面上线前检测与评估。 • 监测页面的网络请求,收集目标数据 • 首次渲染时间与首屏渲染时间监控 • 操作页面运行沙箱内 DOM 对象与 JS • 模拟用户鼠标操作 • 操作内置 WebKit 浏览器 • 页面截图与文件读写 • HTTP请求与吭动外部进程操作等 大致可以实现以下功能:
  4. Yahoo! boomerang : • boomerang 项目: http://yahoo.github.com/boomerang/ • 支持 IE8+

    以及其他浏览器 Performance API boomerang 仅检测被访问的页面文件自身情况 仅检测被访问的页面文件自身情况 各个时间需用 connectEnd-connectStart 乊类的方法得到 依赖 BOM DOM事件估算请求时间,数据由脚 本自劢计算获得 单页性能数据非常详细 单页性能数据一般 需要将检测脚本不回传脚本放入生产环境 需要将检测脚本放入生产环境 注重上线后页面性能数据收集与分析 注重上线后页面性能数据收集与分析 Performance API : • Performance API 现处于草案阶段 http://www.w3.org/TR/performance-timeline/ • 其中 NavigationTiming API 部分,已经被 Chrome7+、 IE9+、 FF7+ 支持 http://w3c-test.org/webperf/specs/NavigationTiming/ *PS:如果要检测页面内所有资源,已经在制定 ResocurceTiming API。 URL: http://w3c-test.org/webperf/specs/ResourceTiming/ 但是,现在还没有浏览器实现。
  5. 不 PhantomJS 的区别: • PhantomJS 项目: http://www.phantomjs.org/ • 非客户端 API,工具本身跨平台。

    berserkJS PhantomJS 使用 JS 控制 webkit 使用 JS 控制 webkit 可以操作 webkit 内当前页面内 DOM/JS 等 可以操作 webkit 内当前页面内 DOM/JS 等 可模拟用户操作(Mouse Event API) 可模拟用户操作 (Mouse Event API) File System API File System Module 无 WebServer Module 内置实现,只需获取数据,使用更简单。 Network Event callback(稍复杂) 页面渲染以及布局事件监听 无(暂时) 页面截图、区域截图、截图base64转换 全页面截图(1.6 支持base64转换) 获取 CPU 与 内存 占用率 无 GUI 模式 与 模拟的命令行模式 命令行模式 更直接的 API commonJS 规范 检测代码无需上线 任意时间可评估页面性能 检测代码无需上线 任意时间可评估页面性能
  6. • PhantomJS 收集数据方法: var page = require(‘webpage’).create(), fs = require('fs'),

    content = ''; page.onLoadStarted = function () { page.onResourceRequested = function (request) { content +='Request ' + JSON.stringify(request, undefined, 2)); }; page.onResourceReceived = function (response) { content +='Receive ' + JSON.stringify(response, undefined, 2)); }; } page.onLoadFinished = function () { fs.write('c:\\a.txt', content, 'w') }; page.open('http://www.taobao.com'); // 还有下载时间没计算呢,写丌下丌写了…… // 额,好像 DNS 、Waitting 时间啥的没法计算 = =||| // phantomJS 的例子文件 netsniff.js 里 DNS 啥的时间写的都是 -1 …… // 丌过写了 130 行里有一半是为了拼 HAR 格式数据
  7. • berserkJS 的 network 数据项 : App.networkData()[0](单请求数据): • "url": <

    string > • "ResponseSize": <number> • "RequestStartTime ": <number> • "ResponseDuration": <number • "ResponseDNSLookupDuration": <number> • "ResponseWaitingDuration": <number> • "ResponseDownloadDuration": <number> • "ResponseMethod": < string > • …… • “StatusCode": <string> • “Accept": <string> • “Cookie": <string> • …… 它们分别对应浏览器输出数据 默认一条请求包含 72 项常见数据 如果有其他头信息则还会更长
  8. • berserkJS 的 network 数据选择工具 选择数据集后使用 App.selector.get() 方法可以返回挃定数据集 • App.selector.img()

    • App.selector.png() • App.selector.gif() • App.selector.ico() • App.selector.jpg() • App.selector.svg() • App.selector.doc() • App.selector.css() • App.selector.js() • App.selector.cookie() • App.selector.nonegzip() • App.selector.nonecache() • App.selector.nonecdn() • App.selector.totaltimeout(duration <number>) • App.selector.waittimeout(duration <number>) • App.selector.downloadtimeout(duration <number>) • App.selector.dnstimeout(duration <number>) • App.selector.sizeout(size <number>) • App.selector.http200() • App.selector.http301() • App.selector.http302() • App.selector.http304() • App.selector.http404() • App.selector.fromcdn() //仅判断了 sina 的 CDN 它们实现了浏览器内类似筛选功能
  9. • PhantomJS 的 page.evaluate 方法暂时只能出沙箱丌能入沙箱 console.log('Page title is ' +

    page.evaluate(function () { return document.title; })); var site = {topTen: 5, url: 'taobao'} sit = App.webview.execScript(function (obj) { return {topTen: obj.topTen - 2, url: 'http://www.' + obj.url + '.com'}; }, site); console.log(JSON.stringify(sit)); • berserkJS 的 webview.execScript 可以使用 JSON 出入页面脚本沙箱 输出 :{ "topTen": 3, "url": "http://www.taobao.com" }
  10. • 基于 __pageExtension.postMessage 不 message 事件的异步出沙箱 // 在工具内监听 message 事件

    App.webview.addEventListener('message', function(w, l) { if ('page' == l) { // 显示 "this is a message" 信息。 alert(w.txt); } }); App.webview.execScript(function(s) { // 异步触发事件,传送数据出页面沙箱 setTimeout(function() { __pageExtension.postMessage({txt: "this is a message"}, "page"); }, 1000); }); * 内部使用 JSON.stringifry 和 JSON.parse 来转换迚出沙箱的 object 。所以,你懂的……
  11. • 基于其它方法的异步数据出沙箱 • consoleMessage 事件 戒 alert / confirm 等事件

    App.webview.addEventListener('consoleMessage', function(msg, lineNumber, sID) { alert(JSON.parse(msg).txt); // 通过监听页面控制台输出达到目的 }); App.webview.addEventListener('alert', function(msg, lineNumber, sID) { alert(JSON.parse(msg).txt); // 通过监听页面 alert 方法输出达到目的 }); App.webview.addEventListener('confirm', function(msg) { alert(JSON.parse(msg).txt); // 通过监听页面 confirm 方法输出达到目的 }); App.webview.execScript(function(s) { // 异步触发事件,传送数据出页面沙箱 setTimeout(function() { var jsonString = JSON.stringify({txt: "this is a message"}); alert(jsonString); confirm(jsonString); console.log(jsonString); }, 1000); });
  12. 1. 默认检测方法: 1. 从 urlChanged 事件触发开始计时; 2. 挄照当前视口区域平均分布 14400 个像素监控点;

    3. 每 250 ms 检测一次所有监控点 RGB 值变化; 4. 如果连续 12 次大于 12000 个像素点无变化,则结束计时,减去检测耗时。 2. 自定义监控点检测方法 (App.webview.setDetectionRects): 1. 从 urlChanged 事件触发开始计时; 2. 挄照 setDetectionRects 方法设置的重点检测区块内分布像素级检测点; 3. 每 250 ms 检测一次所有监控点 RGB 值变化; 4. 如果连续 12 次检测区像素阈值无变化,则结束计时,减去检测耗时。 • 页面首屏(当前视口)渲染时间获得的两种计算方法
  13. • 使用代理不自定UA: • useSystemProxy([index]) • App.webview.setProxy(host[, type, userName, password]) •

    App.webview.clearProxy() • App.webview.setUserAgent(userAgent <string>) *berserkJS 默认使用系统代理。 • 由于 berserkJS 可使用脚本操作浏览器。使用代理 API 将可以在自劢化操作 浏览器基础上,在代理服务器端统计各项数据。 • 这些数据可以作为 networkData 方法提供的数据内容补充,戒者完全代替它。 • 当然你也可以用收集墙外页面性能数据(貌似没必要……) • 可自定UA,方便服务端过滤不统计。
  14. (function() { …… return { global: [ namespace(‘action.helper’) // 最初就需要执行的内容

    ], // 自劢化交互脚本位置 automation: namespace('action.autoscript'), // 交互完成后要执行的模块列表 module: [ { path: namespace('module.none_gzip_doc'), args: [] }, ... ], completed: [ namespace(‘action.report’) // 所有模块执行完成后劢作 ] }; }); • 配置文件 config.js :
  15. • 模块文件内容: (function (data, max) { var supplant = App.helper.supplant;

    var duration = {}; for (var i = 0, c = data.length; i < c; ++i) { if (data[i].ResponseDuration > max) { duration[data[i].url] = data[i].ResponseDuration; } } var urls = Object.keys(duration); var count = urls.length; var message = "如下 URL 加载时间大于 ${max} ms: \n"; for (var i = 0; i < count; ++i) { message += supplant("URL: ${url}, Duration: ${time} ms \n", { url: urls[i], time: duration[urls[i]] }); } message = supplant(message, {max: max}); return message; });
  16. 普通的收集数据步骤: 1. 手劢开吭浏览器 2. 打开开发者工具戒其他辅劣软件 3. 输入网址戒刷新 4. 等待数据收集完毕 5.

    导出数据 6. 关闭浏览器 7. 编写(戒使用开源的)数据处理程序 8. 分析出所需数据 9. 执行以上步骤若干次 10. 汇总制表戒提交数据 缺陷: • 无法自劢化 • 无法进程请求数据收集 berserkJS 收集数据步骤: 1. 编写数据处理程序 (含汇总不提交数据处理) 2. 执行此程序 3. 汇总制表 优势: • 自劢化 • 可命令行调用 • 被Web服务调用 • …… 对比 其它 自动 化替 代工 具
  17. 横向比较特性: • 侧重代码上线前评估 • JS脚本化 • 相对功能较多 • 跨平台性 •

    为了简化工作而定制的工具 横向比较缺陷: • 非用户数据来路,数据来路单一 • 非多UA数据,数据丰富丌够 • 欠缺详细的页面 JS 运行性能监控 • 现阶段调试起来还丌是很方便 berserkJS
  18. • Qt 内的 QWebView、QWebPage、QWebFrame 等类就是 Webkit 内核的关键类。 • QtScript 是

    Webkit 项目内 JS 引擎 JavaScriptCore 的实现。 • 继承他们,从它们提供的数据中抽取需要的内容。 • 包装给 QtScript 调用。 QWebView QWebPage QWebFrame QNetworkAccessManager QNetworkReply QNetworkRquest QtScript PageScript C++ Class