web系统性能及规范检测笔记

静态检查

关于javascript的语言特性,Douglas Crockford在蝴蝶书里面写过:“一些特性因为规范的不完善而可能导致可移植性问题,一些特性会导致代码难以阅读或修改,一些特性诱使我们追求奇技淫巧但却易于出错,还有一些是语言本身设计错误”。

由于javascript语言本身弱类型灵活多变的特点,某些特性的不正确使用或者格式的混乱会导致造成一些未预见的行为或错误。为了解决此类的问题,我们需要静态检查

JSLint

JSLint是Douglas Crockford编写的工具,它将Web开发人员多年积累下来的反模式整合为一套规则,用以对Javascript脚本扫描,并给出相应的问题描述信息。

规则大致包含几个方面:

  • 语法错误检查: 比如括号配对遗漏等问题。
  • 代码格式检查: 比如缺少结尾分号、数组&对象末尾多余逗号等问题。
  • 变量定义检查: 比如未定义变量成为全局变量等问题。
  • 糟粕特性检查: 比如with、void语句等不推荐使用的问题。

最初的JSLint由于规则严格不妥协和拒绝开源等问题,受到一些诟病。时至今日JSLint也允许规则自定义并且可以在github上获取到它了。

关于JSLint的默认规则和自定义规则盗张图描述:

另外,在这篇文章发布的三天前(2015/10/22), Douglas依旧在更新JSLint。它的强(yan)大(ge)功(gui)能(ze)从源码中可以略见一斑。

JSLint https://github.com/douglascrockford/JSLint

JSHint

JSHint是Anton Kovalyov基于JSLint实现的一个开源工具。相对于JSLint来说,JSHint稍微友好一些,可配置性更高。也是现在web开发者使用最多的静态检查工具之一。

关于JSHint配置,分 增强参数(Enforcing Options)松弛参数(Relaxing Options) 。将增强参数设置为true,则JSHint会检查规则更严格,在某些情况下会产生更多告警;同理,将松弛参数设置为true,则JSHint会检查规则更友好,在某些情况下会产生的告警更少。

记录一部分常用配置参数:

增强参数

作用

bitwise

禁用位运算符

curly

循环和条件语句必须使用大括号块包围

eqeqeq

强制使用全等(===)和不全等(!==)来替代相等(==)和不相等(!=)

freeze

禁止重写原生对象原型

indent

代码缩进宽度

noarg

禁止使用arguments.callee和arguments.caller

undef

禁止使用未定义变量

unused

禁止定义了变量却不使用

trailing

禁止行尾空格

maxparams

函数可接受的最大参数数量

maxlen

每行代码最大字符串长度

松弛参数

作用

boss

允许在循环和条件语句中使用赋值( 如if(var i=0, len=...){ )

esnext

允许ES6特性

loopfunc

允许循环中定义函数

sub

允许使用方括号语法获取对象属性

除此之外还有一个环境参数(Environments),这个参数告诉JSHint有一些全局变量已经被预定义。

环境参数

作用

browser

指定浏览器全局变量(document,navigator,FileReader等)

devel

指定用于调试的全局变量(console,alert等)

jquery

指定jquery

module

指定module

...

指定...

具体完成配置查询 http://jshint.com/docs/options/

其他

JSCS

JSCS是一个代码风格检查器,它只匹配代码格式的问题,不匹配潜在的bug、error等。它拥有90多个不同的规则,但是如果不做配置的话就没有任何作用。换言之,一切JSCS的要做的东西都需要根据需求自定义开启。

优点:可以自定义插件进行扩展 缺点:慢

ESLint

ESLint是Zakas大神2013年开发的工具,它的特点是可扩展、每条规则独立、不内置编码风格。它默认包含了所有 JSLint、JSHint 中存在的规则,迁移容易,而且可以给规则设置“警告”、“错误”或者直接禁用几个等级。另外它也包含代码风格检测规则,并支持插件扩展。

优点:支持React JSX,支持ES6,支持插件扩展 缺点:慢

动态检查

静态地谈性能不能解决全部的问题,甚至说,大部分性能优化问题是需要程序真正跑起来才能去发现解决优化的。那么关于动态的检测、优化记录几个方法及工具。

我爱火狐

console对象最初是由mozilla提出的,虽然现在各个现代浏览器都实现了这个对象,并且99%也都满足了日常需求,不过在某些非常细微的地方还是略有差异。

console并不只是可以log、error、info等。

函数执行监控

这是一对函数,监控开始 console.profile(tag) 和 监控结束 console.profileEnd()。在这两个指令中间执行的所有逻辑调用会被记录并统计,并且被console.profileEnd返回。

比如现在有几个蛋疼的函数:

function iAmAFuckingFunction(){
    for(var i=0; i<10 ;i++){
        eggacheA(999);
    }
    eggacheB(9999);
}
function eggacheA(count){
    for(var i=0; i<count; i++){
    }
}
function eggacheB(count){
    for(var i=0; i<count; i++){
    }
}

可以在代码中这样加入调试

console.profile("蛋疼函数检测1");
iAmAFuckingFunction();
console.profileEnd();

然后可以在控制台中看到

在这个统计中可以看到从profile到profileEnd之间执行的逻辑有哪些函数被调用,被调用次数,执行时间,总时间等等各项信息。

另外在firebug控制台也有按钮可以直接使用profile

点击“概况”按钮,然后触发一些事件(交互逻辑、ajax等等),操作完毕再次点击“概况”按钮,就可以得到刚才操作所执行逻辑的信息。

比如,现在我想看看平台lazyload逻辑的相关执行信息,那么我先打开页面,点击“概况”

然后把页面向下滚动,滚动结束后再次点击“概况”

可以看到消耗时间最长的是jq的css函数,但这个是总时间,现在想看单个函数执行时间最长,那么点击“平均时间”tab

这个时候能看到最慢的函数执行时间了。前几个都是库,我需要看自己逻辑中的执行情况,那么在右边“文件”tab可以看到相关信息了。

执行时间监控

另外还有一对函数: console.time(tag) 与 console.timeEnd(tag)。它们的用法跟profile差不多,只不过返回的是两个指令之间的时间差。

还是刚才那三个蛋疼函数

console.time("eggache");
iAmAFuckingFunction();
console.timeEnd("eggache");

返回

另外console.timeEnd是有返回值的,返回值就是时间差的毫秒数。也就是说:

console.time("eggache");
iAmAFuckingFunction();
var timeSub = console.timeEnd("eggache");
//timeSub 0.698906173342948

声明:以上方法只能在firefox->firebug中使用,其他浏览器正确无法获取信息

YSlow

这是一个web性能工具,最早由Yahoo!基于firebug开发,现在已经扩展到各个浏览器都能够安装。它按照雅虎页面优化准则(基于34条那个版本比14条更细)来对网站进行性能分析,并对各个检测项按照A、B、C、D、E、F给出评级,当然也会有一个0~100的评分。

现在对腾讯教育平台首页进行YSlow Run Test

会看到一个执行进度条,片刻后执行完毕可以看到

平台首页得分是90分,评价还是很高的,而且这里有个小小的错误,YSlow不认识78910.url.cn,把这几个域名下的资源误认为是不在CDN之下,实际上这些是做了CDN的。所以其实评分还应该更高一点~~~~ 咳咳偏题了,继续说YSlow。

前面说了YSlow是基于雅虎页面优化准则来进行性能检测的,那么其实这其中大部分的事情也都在码农群体中心照不宣地遵守了,只是有一些东西也许随着技术的更新迭代不是那么完美适用了。比如“添加Expires头”这一条。这个准则的初衷其实是为了缓存文件来着,随着HTTP1.1的普及,在有Cache-Control头的情况下,其实没有Expires也是完全可以的。

附两张YSlow分析的图

最后

Timeline的图贴一张,不赘述了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小白安全

Java反序列化利用工具 -- Java Deserialization Exp Tools

Java反序列化漏洞已经被曝出一段时间了,本人参考了网上大神的放出来的工具,将Jboss、Websphere和weblogic的反序列化漏洞的利用集成到了一起...

5446
来自专栏美团技术团队

Android自定义Lint实践2——改进原生Detector

上篇博客《Android自定义Lint实践》中我们介绍了美团App如何使用自定义Lint进行代码检查。 在使用Lint的过程中,我们陆续又发现原生Lint的一些...

2804
来自专栏Android-薛之涛

Android-Proguard(混淆)

  混淆这玩意,也是经常用,但也是没总结,趁端午有假有时间,就在这里整理一下,也祝大家端午快乐。

1234
来自专栏安恒网络空间安全讲武堂

MS08-067漏洞调试分析详解

MS08-067漏洞调试分析详解 一、前言 在《Metasploit渗透测试魔鬼训练营》中有对MS08-067漏洞原理的分析,不过作者的文笔十分晦涩难懂,读起来...

24510
来自专栏程序员互动联盟

【编程基础第十三讲】代码如何写才最漂亮第二篇

存在问题: 好多小伙伴对编码的格式作用模糊,以为只要完成功能就行,其实这种观点是错误的,一定要重视代码规范,不然你哭的地都找不到。 如何实施: 良好的代码开发习...

2498
来自专栏菩提树下的杨过

Flex4中使用WCF

虽然flex跟.net交互的首选是FluorineFx,但是如果在某些特定情况下(比如服务端是现成的,不允许修改,或者服务端开发方不懂FluorineFx为何物...

1849
来自专栏FreeBuf

RCTF 2018 Magic题目详解

此题来自 RCTF 2018 的一道逆向题目 magic. 赛后分析许久, 看了几个 writeup, 但是始终不得要领, 大神们寥寥数语, 扔下一堆代码, 就...

1320
来自专栏逆向技术

16位汇编第三讲 分段存储管理思想

      内存分段 一丶分段(汇编指令分段) 1.为什么分段?   因为分段是为了更好的管理数据和代码,就好比C语言为什么会有内存4区一样,否则汇编代码都写...

1816
来自专栏dotnet core相关

WCF入门(12)

  上次写是小半年前的事情了,还在原来的公司,还在原来的项目,同时认识了不少人。外包公司总是有些不适应的地方,总在很闲和很忙之间徘徊。凌晨2点被客户电话叫醒,只...

531
来自专栏陈树义

简单笔记

1、类的表面类型和实际类型 实例对象有两个类型:表面类型(Apparent Type)和实际类型(ActualType),表面类型是声明时的类型,实际类型是对象...

2455

扫码关注云+社区