chrome工具优化的学习小结

前言

这个月一直不知道写什么,说明没认真学习啊~但是之前花了不少时间去维护chrome检查工具,没点总结,总感觉很浪费那段时间。这里把过程中遇到的问题做个小结吧。 
先交代下chrome检查工具的背景:是一个内部使用,用来检测页面信息的chrome插件工具,检测的功能包括:页面的基本信息(比如一些seo信息、meta标签、加载时间)、检测某些特殊代码进行分析,检测图片的大小、检测页面发起的某些请求进行分析等等。通过插件工具来达到快速检测页面的某些规范信息,方便前端、编辑和qa直观快速的校验页面的一些信息。工具截图如下: 
QQ截图20160829190958.png

chrome插件相关

因为本人只是负责对已有的插件进行优化升级,而且之前也没有开发过完整的chrome插件,所以优化前对整个chrome插件的工作原理进行了简单探索,这里只是简单描述下:

首先是找api,这种浏览器插件必然会有官方文档的,但是chrome的文档是英文的。然后又发现有个360极速浏览器中文版,估计也是搬人家chrome的,可以看下。 
Chrome 插件具体分为 3 部分,pop、background、content。pop 是 UI,就是弹出那个框框,这里使用了 ReactJS进行数据展示罢了。content 是页面里注入的 js,用于获取页面信息。background 是一个中枢,负责各个部分的消息转发,还有调用 webRequest API 来获取 http 连接的信息。 
插件开发的过程,通过fis3来进行编译,然后在chrome下的开发者模式加载编译后生成的文件夹(其实就是类似于一解压的扩展程序),每次修改代码保存后fis3自动编译,但是浏览器想看到效果需要在 管理扩展程序 里找到加载的插件,点击重新加载(或者直接Ctrl+R快捷键加载,如果是修改background.js这个文件,快捷键貌似不管用)。 
完成开发后,再通过fis3工具进行打包生成新版本的crx拓展程序包,已安装插件的用户只需要重新启动浏览器就可以自动更新到最新版,因为只是内部使用,所以没发布到应用商店。 
其它更详细的开发chrome插件的资料请自行搜索,插件的具体代码请前往git:nie-web-checker

遇到的问题

在整个优化过程中,进行了两次比较大的版本更新,增加了不少功能,踩了不少坑,在小结下:

获取页面的加载时间

因为是chrome插件,只是在chrome下运行,所以很多web新属性、新方法都可以直接使用,比如这里获取页面加载时间时用到的window.performance,它是HTML5 的一个新API,可以用来获取页面各个时间点进行页面性能分析。比如这里要获取页面的加载时间:

var timing = window.performance.timing;
var loadtime = timing.loadEventEnd - timing.navigationStart;

代码很简单,但是获取出来是不对的。后来查了发现loadEventEnd不能过早执行,否则会为0。但是那个过早,很模糊,什么时候才算过早?!我直接把js后置,应该不算过早了吧?但是行不通,那就放到load事件里面吧:

var timing = window.performance.timing;
var loadtime;
window.addEventListener('load', function() {
   loadtime = timing.loadEventEnd - timing.navigationStart;
}, false);

虽然这个时候结果不是负了,但是时间明显不对。。。这时想到了setTimeout,

var timing = window.performance.timing;
var loadtime;
window.addEventListener('load', function() {
   setTimeout(function(){
       loadtime = timing.loadEventEnd - timing.navigationStart;
   },0)
}, false);

用0挂起获取的时间终于和开发者工具看到的时间是一致了。

难啃的正则

因为是页面检查工具,最有效、最高效的方式莫过于用正则表达式进行匹配,一直没能把正则攻下来,所以这个过程写正则花了不少时间,可以总结一些通用性比较强的正则表达式。 
比如匹配html注释的正则:

var r_html_comments = /\<\!\-\-((?!\<\!\-\-)[\s\S])+\-\-\>/igm;

匹配js注释的正则:

var r_js_comments = /(\/\/.+)|(\/\*)[\s\S]+(\*\/)/igm;

再比如,需要把页面的没有title属性的空a标签检测出来,类似下面的多种情况:

<!-- 直接没有title属性,a标签里面没任何东西的 -->
<a href="http://w3cmark.com" target="_blank"></a>
<!-- 直接没有title属性,a标签包含一个或多个空格的 -->
<a href="http://w3cmark.com" target="_blank"> </a>
<a href="http://w3cmark.com" target="_blank">  </a>
<!-- 有title属性但为空的 -->
<a href="http://w3cmark.com" target="_blank" title=""></a>
<a href="http://w3cmark.com" target="_blank" title=" "></a>
·
·
·

最终的正则是:

var rr_label_a = /\<a((?!(\<|\>|(title\s*=\s*(\'|\")\s*\S+(\s*\S+)?\s*(\'|\"))))[\s\S])+\>\s*\<\/a\>/igm;

攻克正则的途径,还是需要通过不断的写,不断的写,写多才能属性。

overrideMimeType API

在做点击代码检测时,因为点击描述是中文,所以在进行ajax获取js文件代码回来检测时会有乱码的情况(有些项目使用gbk编码的)。一直以为ajax get请求无法设置编码的,一度陷入无解状态。但是后来在Q群请教得知 overrideMimeType方法,又一个HTML5的新api(看来还是读书少啊),chrome插件使用无兼容压力。

var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.overrideMimeType('text/txt; charset='+charset);
xhr.onreadystatechange = function () {
   // do something
};

在open后设置需要返回的编码即可!

数组去重

用正则获取页面的很多信息都是通过数组来存储的,这样必然会存在一个重复问题,所以这里也小结了一维数组去重方法和二维数组去重方法:

//一维数组去重
function unique(arr){
   arr.sort();
   var re=[arr[0]];
   for(var i = 1, len = arr.length; i < len; i++)
   {
       if( arr[i] !== re[re.length-1])
       {
           re.push(arr[i]);
       }
   }
   return re;
}
//二维数组去重
function uniqueTwoD(arr){
   var hash = {};
   var re = [];
   for(var i = 0, len = arr.length; i < len; i++){
       if(!hash[arr[i]]){
           re.push(arr[i]);
           hash[arr[i]] = true;
       }
   }
   return re;
}

404页面检测

这个404页面检测倒不算是什么坑,但是觉得蛮好玩的。因为如果没有自定义配置404的页面,浏览器返回的404页面是固定的。可以通过这个特性来检查服务器是否有配置返回自定义的404页面:

var _url = [this.props.url.match(/^(http|htpps):\/\/([a-zA-z]+[^\s?!\/]*)/)[0]+'/qwertypoiuj'+randomNumInt(1,100)],//随机地址
   r = /Additionally, a 404 Not Found(\n|\s){0,}error was encountered while trying to use an ErrorDocument to handle the request/igm,//浏览器固定返回的404页面结构
   r_title = /\<title\>404 Not Found\<\/title\>/igm,//浏览器固定返回的404页面标题
   charset = this.props.charset;
//用ajax获取随机不存在地址
getScript(elem, charset);

通过特定的结构和标题两重检验,可以绝大部分断定该页面是不是自定义的404页面(如果自定义404本身就做成这样那就行不通了)。

结束语

ok,完了,分享一些毛皮~


本文由 w3cmark_前端笔记 版权所有,转载时请注明出处。
注明出处格式:w3cmark (http://www.w3cmark.com/2016/nie-web-checker.html)

分享到:

评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
关注w3cmark
微信公众号 w3cmark_com