您的浏览器Javascript被禁用,需开启后体验完整功能, 请单击此处查询如何开启
网页 资讯 视频 图片 知道 贴吧 采购 地图 文库 |

w彩票网 上光大-gd567,web前端第三方内容开发最佳实践_IT/计算机_专业资料

283人阅读|45次下载

w彩票网 上光大-gd567,web前端第三方内容开发最佳实践_IT/计算机_专业资料。第三方内容开 发最佳实践 张立理 @otakustay 权一 @_Fr ank y 2012.6 3.0 2.5 3.5 2.0 4.0 nightly dev beta XP+SP1 5.


w彩票网 上光大-gd567第三方内容开 发最佳实践 张立理 @otakustay 权一 @_Fr ank y 2012.6 3.0 2.5 3.5 2.0 4.0 nightly dev beta XP+SP1 5.0 6.0 XP+SP2 KB2497640 <img> Flash <iframe> Quirks !important iframe > iframe > … 第三方代码 Google Analytics <script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-XXXXX-Y']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('http:' == document.location.protocol ? 'http://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script> 第三方代码 Baidu ADM 第三方代码 Baidu ADM 第三方功能使用过程 <head> <meta> <title> <script> // 引入第三方脚本 <body> <header> <div id=?page?> <p> <script> // 调用API <ins> <!-<footer> </body> 嵌入内容 --> 静态脚本资源 内容检索 日志上报 引入脚本 脚本 类型 <head> <body> 同步 异步 脚本 位置 脚本 URL http:// http:// 引入脚本 同步 – 使用document.write var protocol = ('http:' == document.location.protocol) ? 'http://' : 'http://'; document.write('<script src="protocol + 'www.tt.com/extern.js" charset="utf-8"><\/script>'); ? 不要使用//www.tt.com/extern.js的形式,严格加上http或 https协议 ? file://协议下本地调试会出现问题 ? 严格加上charset属性 ? 无法保证目标页面的编码 ? 将</script>转义为<\/script> ? 不需要使用'</scr' + 'ipt>' 引入脚本 异步引入 – 创建<script>元素 var script = document.createElement('script'); script.type = 'text/javascript'; script.async = true; script.src = src; // 插入<script>元素 ? 确保这段脚本可以异步执行 ? 不需要type属性 ? 默认为text/javascript ? 不需要async属性 ? 编程创建的<script>元素必定是异步的 引入脚本 ? 插入<script>元素 – 错误方法 document.body.appendChild(script); ? 在<head>元素解析过程中,不存在<body>元素 ? IE6“终止操作”错误 document.head.appendChild(script); ? IE6的<base>标签BUG 引入脚本 ? 插入<script>元素 – 第一个<script>元素前 var firstScript = document.getElementsByTagName('script')[0]; firstScript.parentNode.insertBefore(script, firstScript); ? 优点 ? 无if分支判断 ? 不会导致浏览器崩溃 ? 缺点 ? 是否确定文档中已经有至少一个<script>元素 ? 无法控制元素插入位置,有问题时找该元素较为麻烦 ? 部分浏览器parentNode会是<html>导致错误 引入脚本 ? 插入<script>元素 – <head>元素第一个子元素 var container = document.getElementsByTagName('head')[0]; if (!head) // 补救; else container.insertBefore(script, container.firstChild); ? 优点 ? 插入位置固定,易于查找 ? 缺点 ? 需要if分支判断<head>是否存在 ? ? 多数浏览器会补全<head> 例外:Firefox 4.0b1 / iPhone 3.0 / Chrome 5.0等 引入脚本 ? 插入<script>元素 – 防御性补救措施 setTimeout(function() { if (!document.body) setTimeout(arguments.callee, 0); else document.body.insertBefore(script, document.body.firstChild); }, 1); ? 优点 ? 未发现不支持的情况,用于处理前几种方案的盲区 ? 缺点 ? 需要补全<body>才可加载脚本,导致脚本加载时间滞后 引入脚本 不要随意删除<script>元素 ? 如果删除正在执行的<script>元素,会导致IE崩溃 ? 过多<script>元素导致内存占用 ? 定时使用JSONP时容易出现 ? 使用setTimeout来控制元素的删除 var scripts = document.getElementsByTagName('script'); var currentScript = scripts[scripts.length - 1]; setTimeout(function() { currentScript.parentNode.removeChild(currentScript); }, 1); 嵌入内容 嵌入方式 ? <iframe> ? 直接嵌入 常见问题 ? z-index ? Quirks模型 常用方法 ? document.write ? <iframe> ? Flash 嵌入内容 使用<iframe>元素 ? 优点 ? 用于隔离样式 ? 避免全局环境变量污染 ? 缺点 ? 与主页面交互较为麻烦 ? IE下权限问题 ? 需要重置样式 ? width / height / vspace / hspace / scrolling / frameborder / allowtransparency / display / border / vertical-align / margin 嵌入内容 直接插入元素 ? 选择<ins>元素作为容器 ? 语义正确性,第三方内容为“插入的内容” ? <ins>是透明元素,不会导致内容模型错误 ? IE下,<p>元素内放置<div>元素会导致崩溃 ? 关注样式重置 !important ? ? ? ? ? 使用.style.cssText可添加!important声明 float margin / padding / border overflow / position / display / visibility text-align 嵌入内容 ? 其它元素样式重置 ? <ins> | <del> ? text-decoration ? <a> ? color / decoration ? <img> ? display / border ? <li> ? list-style http://www.iecss.com/ 嵌入内容 其它问题 ? 尽量使用insertBefore而不是appendChild ? IE的“终止操作”问题 ? z-index相互覆盖问题 ? 最大值2147483647 ? 同值情况下,DOM中靠后的在上方 ? ? 在DOM中越靠后则越上方 ? 通过DOMContentLoaded或onload插入 但内容展现的延迟越长 ? 从当前<script>元素向上查找至<body>的直接子代, 在其前面插入 嵌入内容 ? 兼容Quirks模式 ? 检测文档模式 ? document.compatMode ? 盒模型 ? border-box VS content-box ? 水平居中 ? margin: 0 auto无效,使用text-align: center代替 ? 页面尺寸 ? body VS documentElement document.write 问题性 VS 必要性 内联+外部脚本时序问题 外部脚本时序问题 IE假死问题 document.write Tokenizer It’s evil ? 不可异步执行 ? 导致HTML解析过程回溯 Script Tree Construct It’s inevitable ? 展现内容与脚本执行位置相关 ? 没有API获取当前执行的<script>元素 ? 第三方内容脚本存在调用 ? Google Adsense / Baidu Cpro … ? 使用<iframe>创建内容时常用 DOM Tree document.write IE下时序问题 – 内联 VS 外部脚本 使用document.write输出<script>标签 ? 内联脚本永远优先执行 // hello.js中定义了hello函数。IE下,hello函数未定义,抛出ReferenceError document.write('<script src="hello.js"><\/script>' + '<script>hello();<\/script>') ? 不会阻断当前脚本继续执行 // 该js中包含了hello函数的定义 document.write('<script src="hello.js"></script>'); // 在IE下,此时hello.js文件未加载完毕,hello函数未定义,抛出ReferenceError hello(); document.write ? IE下时序问题 – 嵌套输出外部脚本 <script> ex.js document.write('<script src="ex.js"><\/script>'); document.write('<script src="define.js"><\/script>'); // ReferenceError try { define.js var hello = 'world'; alert(hello); } read.js catch (ex) { if (window['hello']) { // 会加载2次read.js alert(hello); } // 形成尝试为2的嵌套document.write else { // 才可以读取到hello document.write('<script src="read.js"><\/script>'); document.write('<script src="read.js"><\/script>'); } } </script> ex.js read.js define.js read.js hello hello document.write ? <iframe>导致IE6假死问题 <script> function destroyIE(iframe) { var doc = iframe.contentWindow.document; doc.write('<script src="http://www.tt.com/example.js"><\/script>'); doc.write('<script>alert("hello");<\/script>'); } </script> <iframe src="about:blank" onload="destroyIE(this);"></iframe> ? 使用document.write ? 一个外部脚本+一个内部脚本 <iframe> IE权限问题 onload事件问题 IE收藏夹问题 DOM移动重加载问题 缓存问题 javascript:伪协议问题 <iframe> IE下<iframe>权限问题 document.domain = 'tt.com'; var iframe = document.createElement('iframe'); iframe.src = 'about:blank'; document.body.appendChild(iframe); iframe.contentWindow.document.write('test'); // IE下报错 使用跨域策略文件 <!DOCTYPE html> <meta http-equiv="Cache-Control" content="max-age=8640000" /> <script> document.domain = 'tt.com'; </script> iframe.src = '/domain-policy.htm'; <iframe> ? DOM1注册onload无法移除问题 function loadFrame(iframe) { iframe.onload = null; // 无法移除onload事件 var doc = iframe.contentWindow.document; doc.open('text/html', 'replace'); doc.write(html); // 导致再次触发loadFrame doc.close(); } <iframe src="about:blank" onload="loadFrame(this);"></iframe> ? 无法移除DOM1的onload处理函数无效 ? 不要使用DOM1的方式注册onload,使用脚本注册 ? 通过标记变量来控制 if (this.getAttribute('data-rendered')) { return; } this.setAttribute('data-rendered', 'rendered'); <iframe> ? IE6收藏夹问题 ? 页面为www.tt.com/xxx,其中有一个iframe的地址为 /frame [DOC_baidu_clb_slot_iframe_1234567] BASEURL=http://www.tt.com/xxx ORIGURL=/frame ? 从收藏夹打开,加载的是BASEURL,忽略ORIGURL ? 判断当前<iframe>的src属性,不符合预期则重新加载一 次 function renderThirdPartyFrame(iframe, content) { if (iframe.getAttribute(‘src’, 2) !== getFrameUrl()) { // IE会补全src iframe.src = getFrameUrl(); return; } // 原renderThirdPartyFrame函数内容 } <iframe> ? 元素移动重加载问题 ? 在<iframe>加载完毕后,移动该元素在DOM中的位置 ? 影响统计数值 ? 通过标识属性避免多次加载的影响 浏览器 IE6-8 IE9 Firefox Chrome Opera 结果 不重新加载 重新加载 重新加载 重新加载 重新加载 <iframe> ? 缓存BUG var list = [ 'http://www.163.com', 'http://www.baidu.com' ]; var src = list[Math.random()*2 | 0]; document.write('<iframe src=' + src + '></iframe>'); document.write('当前iframe的src为:' + src); <iframe src="//www.google.com" id="ifm"></iframe> <script> var ifm = document.getElementById('ifm'); window.onload = function () { // Firefox4-10刷新时baidu.com会加载2次 ifm.src = '//www.baidu.com'; }; </script> ? 刷新时src改变但内容不变 ? createElement创建<iframe>加入DOM后设置src无此问题 ? 如果src符合^#+$则无此问题 ? 解决方法 ? 使<iframe>符合上述条件之一 ? Firefox4开始修正,但极端情况下依旧存在问题 <iframe> ? 使用javascript:伪协议导致IE下不强制渲染 var text = 'abc'; var script = 'var d = document; d.open(\'text/html\', \'replace\'); d.write(parent.text); d.close();'; var html = '<iframe id="abc" name="abc" src="javascript:void((function() {' + script + '})())"></iframe>'; document.write(html); ? 将包含以上脚本的页面添加到收藏夹,从收藏夹打开 ? 视觉上看不到abc字母 ? DevTool查看iframe中不存在TextNode ? iframe上右键-属性,得到的地址为about:blank ? 强制触发paint / 刷新UI Update Queue ? script中添加d.offsetWidth; <iframe> ? 更多伪协议问题 ? 当parent页存在 base标签,且target为_blank时,会导致IE系 弹窗(并可能会被浏览器拦截) ? 不恰当的写入方式,造成parent页的document.readyState永远 处在inneractive状态 ? parent页面的onload事件,永远不会被触发 ? IE8-下,iframe.onload,被认定跨域,注册无效问题 ? iframe.src="about:blank"导致IE全系后退按钮bug ? parent页后退按钮失效,可以无限按后退,并导致iframe内部的资源 无限重载 ? 不恰当地使用伪协议写入文档流,IE会永远卡在loading状态(不 停的转啊转……) FLASH 引入 覆盖 移除 Flash http://www.otakustay.com/problems-about-using-flash/ FLASH 引入Flash ? 分浏览器使用不同标签 ? 使用特性检测 var useObjectForFlash = ('classid' in document.createElement('object')) ? <object><embed /></object>方案在Chrome下有BUG ? IE8下<object>不支持setAttribute ? IE8-混用attribute和property,用property代替即可 ? 使用innerHTML输出元素 ? <object>不支持appendChild(IE) ? Flash的容器元素必须事先在DOM中 ? 先创建Flash后加入DOM会导致停止在第一帧(IE6-8) ? allowScriptAccess="never" FLASH ? 移除Flash ? 先隐藏,setTimeout后移除 ? Opera+部分版本FlashPlayer下直接移除会留下残影 var element = document.getEleemntById('someFlash'); element.style.display = 'none'; // 先隐藏起来 // 利用setTimeout,让DOM有一次重绘的时间 setTimeout(function() { element.parentNode.removeChild(element); }, 1); ? 隐藏Flash ? 使用left / top移出屏幕外 ? 移动DOM位置、修改display / visibility会导致Flash重新加 载 FLASH ? 盖住Flash ? wmode ? ? ? ? ? ? window / opaque / transparent opaque下使用z-index可覆盖 window下使用iframe覆盖 要求浏览器强制重绘,解决渲染问题 http://www.w3help.org/zh-cn/causes/RX8012 http://www.cnblogs.com/_franky/archive/2010/11/19/1882055.html 日志上报 上报方式 <img>使用 常见问题 PVID生成策略 URL长度控制 mimeType设置 退出时上报问题 <img>预加载问题 日志上报 var log = (function() { 解决GC问题 var fix = []; 必须在src前设置 return function(url) { var image = new Image(); fix.push(image); image.onload = image.onerror = image.onabort = function() { image = image.onload = image.onerror = image.onabort = null; for (var i = 0; i < fix.length; i++) { if (fix[i] === image) fix.splice(i, 1); break; 不是必须的 } } image.src = url; } }()); 日志上报 <img>回收问题 ? <img>请求过程中,如果对象被GC回收,导致请求中断 ? 将<img>放入DOM – 会触发layout过程 ? 将image放在window下 – 会影响for..in ? 使用闭包保留引用 IE事件问题 ? 如果有本地缓存,则设置src和onload事件同步触发 ? 此后设置onload事件已经错过触发时机 ? 必须先设置onload事件再设置src属性 日志上报 缓存问题 ? url必须加上随机数 ? IE及Opera部分版本实现HTTP Cache有误 mimeType问题 ? 服务器端设置为image/gif,返回1x1的透明像素 ? Chrome控制台警告 ? <img>的onload触发 日志上报 URL长度问题 ? 浏览器限制 ? IE6-7:2065 ? IE8:4083 ? IE9:>65536 ? Opera:4050-190,000 ? Chrome:8182-20,000,000 服务器限制 ? nginx:large_client_header_buffers 8K ? Apache:LimitRequestLine 8190 ? 代理服务器? ? 日志上报 PVID生成 ? Math.random以时间为种子,高并发状态下易重复 ? ((Math.random() * 2147483648) | 0).toString(36) 引入更多随机因子 ? location.href / cookie / userAgent / language ? 当前时间 ? history.length / plugins.length / mimeTypes.length / flashVersion ? mouse x / y ? 日志上报 退出时上报 ? ? 同步ajax ? 跨域环境下不可用 异步<img> ? 使用while循环产生约1/4s的延迟 ? 缩短日志长度 ? 得到TCP包即认为上报成功,不统计完成HTTP请求 ? 实测极限成功率约为85% ? 有效利用localStorage存放,下一PV时重新发送 ? 需要把时间等因子一同写入参数 日志上报 现象 ? ? ? <img>被浏览器预加载 响应的mimeType错误 <img>会被加载2次 解决 <script> doc.write('<img src = "xxx?start" />') </script> <script src = "第三方脚本"></script> <script> doc.write('<img src = "xxx?end" />') </script> 细节问题 第三方 Cookie Gzip问 题 点击监 控方案 特性检 测 第三方COOKIE P3P - Platform for Privacy Preferences Project ? 影响Cookie的写入,对读取无影响 ? 简洁策略 ? CP=. ? 尽可能避免通过javascript读写第三方Cookie ? IE6存在BUG ? 注意默认不允许第三方Cookie的浏览器(Safari) ? Safari3无解 ? Safari4+使用POST实现Cookie写入 GZIP问题 IE6加载资源有gzip的资源不解析、执行 ? 不缓存gzip资源时,使用max-age=0代替no-cache ? 一个gzip资源在多个<iframe>中使用时,在主页面先行完成加 载,<iframe>使用缓存 ? IE6对于gzip资源不使用ETag,注意使用Last-Modified ? IE6对于gzip资源会在Modified-Since后加上;length=xxx字 符串,实现Web Server时注意匹配 ? 针对IE6放弃gzip ? Nginx:gzip_disable "MSIE [1-6]\. "; http://www.cnblogs.com/_franky/archive/2012/04/28/2475223.html 点击监控问题 ? 针对图片、文字 ? 使用<a>作为容器 ? 针对Flash ? 使用<a>覆盖Flash对象 ? 必须有背景色(非transparent)或背景图片 ? 使用背景色,则设置透明度为0(opacity + filter) ? 保证容器有固定宽高,并且overflow:hidden position: absolute; top: 0; left: 0; width: 100%; height: 9999px; background-color: #fff; opacity: 0; filter: alpha(opacity=0); 或 background-image: url(about:blank); ? 使用clickTAG(需Flash制作配合) 特性检测 优先使用特性检测代替UA检测 ? 特性检测的基本思路 ? 制造差异环境 ? 获取状态值 ? 判断并得到特性 ? 常见特性 ? ? ? ? 是否支持position: fixed iframe是否存在权限问题 Flash对象使用<object>或者<embed> 是否支持border-radius 特性检测 var outer = doc.createElement('div'); var inner = doc.createElement('div'); var result = false; outer.style.position = 'absolute'; outer.style.top = '200px'; inner.style.position = 'fixed'; inner.style.top = '100px'; outer.appendChild(inner); inner (support) 上边距重叠 inner (not support) 例:是否支持position: fixed outer document document.body.insertBefore(outer, document.body.firstChild); if (inner.getBoundingClientRect && inner.getBoundingClientRect().top !== outer.getBoundingClientRect().top) { result = true; } doc.body.removeChild(outer); return result; 其他细节 ? window.open问题 ? 不同浏览器参数不同 ? http://www.cnblogs.com/_franky/archive/2011/04/06/2006857.html ? Chrome下,如果设置了screenX和screenY,会使left和top一 起失效 ? 补全<body>问题 ? 建立空<iframe>写入内容时,如果内容仅包含<script>,则会 补全<head>但没有<body> ? 但脚本可能依赖<body>,因此必须将内容写入<body>中 document.write('<body>'); document.write(content); 开发相关 开发、规范 调试、测试 上线、部署 开发相关 开发准则、规范 ? 变量一行一个var关键字 ? 大量使用防御性编程 ? 浏览器 !== IE+Firefox+Chrome+Opera+Safari ? 自动补上全局try / catch ? 回发catch的Error,带上Referrer以方便复现问题 ? 不写任何侵入性代码 ? 不污染内置对象及其prototype ? 尽量少的全局变量 ? 尽量不使用Cookie ? userData + localStorage基本可以满足本地存储需求 开发相关 IIFE书写 ? Imediately Invoked Function Expression ? 使用(function() {}())的形式,避免使用void / ! / ~等 方式 ? 语义明确,不加入额外运算 ? 括号(分组)运算符在语法树中不会留下 ? 有利于基于AST的工具分析语法 if (condition) { (function() { var x = 3; console.log(x); }()); } if (condition) { var x = 3; console.log(x); } node fix.js in.js > out.js 开发相关 统一全局函数调用方式 ? alert VS window.alert ? 推荐alert ? ? window.alert递归栈溢出限制低 alert性能略高于window.alert copy on read alert; // 是否有这一行,IE6-8中结果不同 var hijack = window.alert; window.alert = function(){ hijack('hijack'); }; alert('origin'); window global code 开发相关 调试及测试 ? 调试信息控制 ? 使用注释方式 ? ? /* #DEBUG# {code} #DEBUG# */ 调试时保留全部,白盒测试时去除#DEBUG#段但保留内部 console相关代码,生产环境全部去除 enableDebug(someFunction, [options]); ? options: enter / leave / time / count… 测试、上线时去除所有enableDebug调用 如果需要在函数体中部添加调试相关逻辑,则说明函数需要 进一步拆分 – 对设计和编码有指导意义 ? 使用函数变换方式 ? ? ? 开发相关 开发过程中版本控制 ? 开发时:拆分为多个文件独立开发 ? 调试、测试时:生成合并未压缩版本 ? 生产环境:使用合并压缩版本 生产环境规范 ? javascript中不含有任何非ASCII字符 ? 自动增加IIFE、添加try / catch块 ? 注意合并后文件过大可能导致移动浏览器不缓存 开发相关 稳定 需要 努力 快醒 醒吧 安全 相当 困难 性能 基本 不能 上线部署 清除先期缓存 http://cbjs.baidu.com/js/m.js?v=3 用户不会替你修改版本号! Self Updating Script – 自更新的脚本 ? ? ? 用户引用的脚本地址永远相同(没有版本号) 需要有较长的客户端缓存(max-age / Expires) 新版本部署后可以及时更新客户端的脚本 上线部署 清除先期缓存 ? 利用location.reload(true /* false */) var re = true; var ifm = document.createElement('iframe'); ifm.src='about:blank'; document.body.appendChild(ifm); var doc = ifm.contentWindow.document; doc.open(); doc.write(eval('"' + '<script>if(parent.re){parent.re = false; location.reload(true /* false */);} else{document.write("<script type=text/c src=http://www.a.com/js/a.js><\\\/script>");}<\/script>' + '"')); doc.close(); ? ? 会引起<iframe>系列问题 可使用实体页(服务器真实存在的页面)清理缓存 ? 会产生额外请求 ? 可使用dataURI代替 ifm.src = 'data:text/html;charset=utf-8,' + html; 上线部署 加载资源但不执行 ? IE、Opera、Safari4-、Chrome7? 使用<script>元素 <script type="text/c" src="..."></script> ? Chrome8+,Safari5+、Firefox ? 使用<link>元素 <link rel="stylesheet" media="c" href="..." /> 上线部署 location.reload(true) ? 相当于CTRL+F5 ? Chrome忽略Expires,保留Last-Modified与ETag ? 其他浏览器取消所有缓存有关头,或添加Cache-Control:no-cache头 location.reload(false) ? 相当于F5 ? 高版本浏览器忽略Expires,保留Last-Modified与ETag 上线部署 ? location.reload参数选择 ? Safari4-及Opera12-永远带Cache-Control: nocache ? Chrome6-永远带Cache-Control: max-age=0 ? Safari5以false为参数会带有Cache-Control: maxage=0和Pragma: no-cache,导致某些服务器不响应304 ? 考虑线上CDN、反向代理、负载均衡的策略 ? 建议CDN等设施严格遵守HTTP/1.1 ? ? 优先识别Cache-Control头 存在Cache-Control头的情况下忽略Pragma头 ? 前端设施实现正确的前提下,使用true作为参数 http://www.cnblogs.com/_franky/archive/2012/07/05/2577141.html 上线部署 做好向后兼容 ? 用户永远不会配合你更新自己的代码 ? cbjs.baidu.com下,m.js / s.js / o.js是同一个文件 ? addSlot / enableAllSlots都是空函数 ? singleFillSlot / fillSlot是同一个函数 ? 线上入口.js文件有缓存期 ? .js文件上线后不可能立刻生效 ? 后端逻辑升级时特别注意是否可兼容缓存的部分逻辑 ? 可选择前端上线 – 缓存失效 – 后端上线的步骤 ? 使用灰度上线(抽样小流量)机制 上线部署 做好线上监控 ? 统计用户环境 ? Quirks模式比率 ? 发现新的逻辑分支 ? 从URL提取域名的正则表达式覆盖是否全面 ? 利于问题的排查 ? API函数是否有被拦截 ? 实时检测DOM发现问题 ? 仅在问题存在时发送日志 ? 尽可能打消用户对隐私窥探等的顾虑 问题排查 自动 化 性能 排查 文件代理 问题排查 代理线上文件 ? 正向代理 ? Fiddler (Windows) ? Charles (MAC / Linux) ? WireShark (底层拦截) 性能问题排查 ? dynaTrace ? 支持IE和Firefox ? Firebug(Console-Profile) / Developer Tool(Profiles) 问题排查 ? 性能问题排查 - dynaTrace 问题排查 ? 性能问题排查 - dynaTrace 问题排查 排查过程自动化 ? phantomjs ? 成熟、社区庞大 ? 新版取消xvfb依赖,不支持Flash等插件 ? berserkJS ? 中文文档、技术支持近在眼前 ? 新生事物,难免存在问题 ? Selenium ? 多浏览器支持 ? 无法脱离浏览器独立执行,依赖GUI DONE THANKS

文档贡献者

RUDOLPHKING

贡献于2013-08-07

喜欢此文档的还喜欢