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

berserkJs

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for d2forum d2forum
July 18, 2012
20k

 berserkJs

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

Avatar for d2forum

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