参考:https://www.w3cschool.cn/webdevelopment/index.htmljavascript
一、htmlcss
1.1 标签中属性值统一使用 双引号html
<!-- Not recommended --> <span id='j-hook' class=text>Google</span> <!-- Recommended --> <span id="j-hook" class="text">Google</span>
二、css前端
2.1 模块组织html5
2.1.1 Components 最少以两个单词命名,经过 - 分离,例如:java
.like-button
).search-form
).article-card
)三、jsweb
3.1函数/方法注释ajax
/**
* 函数描述
*
* @param {string} p1 参数1的说明
* @param {string} p2 参数2的说明,比较长
* 那就换行了.
* @param {number=} p3 参数3的说明(可选)
* @return {Object} 返回值描述
*/
function foo(p1, p2, p3) {
var p3 = p3 || 10;
return {
p1: p1,
p2: p2,
p3: p3
};
}
3.2性能优化正则表达式
避免没必要要的 DOM 操做算法
浏览器遍历 DOM 元素的代价是昂贵的。最简单优化 DOM 树查询的方案是,当一个元素出现屡次时,将它保存在一个变量中,就避免屡次查询 DOM 树了。
// Recommended
var myList = "";
var myListHTML = document.getElementById("myList").innerHTML; for (var i = 0; i < 100; i++) { myList += "<span>" + i + "</span>"; } myListHTML = myList; // Not recommended for (var i = 0; i < 100; i++) { document.getElementById("myList").innerHTML += "<span>" + i + "</span>"; }
即:每次DOM对象都保存到一个变量中。
四、
一、.全部的 变量和函数的声明在做用域的最前面
二、全局做用域的变量尽量少,有些函数须要用到函数外面一层的变量时,可使用闭包函数把这个变量放到函数内,隔绝全局变量。
全局做用须要变量的话能够设置一个全局做用域的对象( glob$ = { } ),其它的变量挂在这个对象下。
三、闭包函数中最好不雅设一个变量指向DOM对象,DOM对象的属性再指向这个闭包函数内的对象。(防止内存溢出)
四、事件绑定用onclick建立事件,会被同名覆盖掉,
把js放在</body>
结束标签以前而不是<head></head>
标签内部可以避免浏览器阻塞,提高用户体验,已经算是一个常识。这个常识的背后,涉及到了浏览器单进程的概念。
事实上,多数浏览器使用单一进程来处理用户界面(UI)刷新和javascript脚本执行,因此同一时刻只能作一件事。
这里说的用户界面刷新,指的是咱们“所能看到的UI”变化(好比点击一个按钮,会出现按钮被按下去的效果)。换句话来讲,处理UI就没法处理javascript,反之亦然。因此若是一份运行时间很长的js脚本放在页面顶端,会阻塞以后页面的下载和渲染,给用户的感受就是“页面一片空白卡死不会动”。
虽然如今网速和浏览器的效率已经获得了巨大的提高,但随着移动端的兴起以及前端框架如Vue
,React
的大量使用,这个问题仍是很是值得咱们注意的。
首先对于数据的存取,有如下这么一句关键:
每个js函数都会带有一个叫作
[[Scope]]
的内部属性,也就是该函数的做用域链,它决定了哪些数据能被函数访问。
书上详细介绍了做用域链
、执行上下文
、活动对象
、全局对象
、闭包
等概念,在这里就不进行复述了。用我本身理解的话来讲,就是一个函数若要使用一个变量,它会从最近的地方,也就是定义在函数内部的局部变量里面去找;若没有找到,则往更远处的全局变量(或者上一级做用域)里面去找。偏偏是这个“找”的过程,产生了性能的问题。书上使用了“解析标识符”来表述“找”这个动做,而js性能偏偏是随着解析标识符深度的增长而下降,因此在最佳实践里,每每是经过把一个较深的变量赋值给一个局部变量,在函数内部直接调用这个局部变量来提高性能。
说完变量,就到了方法。在js中一切皆对象,然而js的对象是基于原型而来,这就引出了一个原型链的概念。与前文关于解析标识符的原理相似,要调用一个对象中的方法,首先会从这个对象实例中查找,若找不到,则会沿着其原型链一步一步由近到远地往上查找,其性能也是随之降低的。
另外,书上也讨论到了关于“嵌套成员”的问题。好比window.location.href
,它会先找到window
对象,而后查找嵌套于内的location
对象,再找到这里面的href
属性,前先后后套了多层,在性能上也有着必定的花销。因此在实际的编码过程当中,咱们更多时候会面对的每每是这种嵌套成员的问题,时刻记得缓存对象成员的值,在执行完毕后利用cacheObj = null
的方式释放缓存,能够有效地提升性能,以下例子:
// bad document.querySelector('.xxx').style.margin = 10 + 'px' document.querySelector('.xxx').style.padding = 10 + 'px' document.querySelector('.xxx').style.color = 'pink' // good let xxxStyle = document.querySelector('.xxx').style xxxStyle.margin = 10 + 'px' xxxStyle.padding = 10 + 'px' xxxStyle.color = 'pink' xxxStyle = null
这一章节详细介绍了关于dom操做的一系列问题。首先要明确一个知识点就是dom操做是具备“天生就慢”的问题。为何会如此呢?由于在浏览器里面,处理html和js是两套不一样的机制,他们经过接口来进行联系的。引用书中的原话,就是能够把html和js理解为两座岛,他们之间须要一座桥来进行沟通,而过桥则会产生时间与成本上面的开销,也所以引发了性能的问题。这一章节经过分析不一样的dom操做函数,来综合对比了各类方法的速度。
dom操做每每容易引发浏览器的重绘与重排。重排,指的是页面的布局和几何属性改变时所发生的事情;重绘,是指把dom元素绘制到屏幕上面的过程。
会形成性能问题的,每每来自于重排,由于浏览器须要从新计算页面全部元素的大小与位置,而后把它们安置在正确的地方。因此,要提高页面的性能,很重要的一个举措就是避免页面的重排。
值得注意的是,并不是只有在修改页面元素的大小和位置的时候才会引起重排,在获取的时候浏览器也会出发重排,以返回正确的值。
然而不少时候咱们不得不直接操做dom,尽管它们会引发重排和重绘。书上给出了几个方案,都能有效提高性能。其实方法和上文关于js缓存局部变量的方法相似,也是经过缓存的机制,减小对于dom元素属性的查找,以及批量修改变量再一次性更新dom的办法去减小查询与修改。
除此之外,让元素脱离文档流也是一个很好的方法。由于元素一旦脱离文档流,它对其余元素的影响几乎为零,性能的损耗就可以有效局限于一个较小的范围。
讲完重排与重绘,往dom元素上绑定事件也是引发性能问题的元凶。利用浏览器自带的冒泡或捕获机制,能够经过事件委托的方式减小事件处理器的数量,从而把性能优化得更好。
这一章首先分析了几种循环类型,结论是只有for-in
循环的性能最慢,由于每次迭代都会同事搜索实例或原型属性,致使其性能只有其它类型速度的1/7。
循环在代码中很是常见,既然没法避免,则须要经过尽可能减小循环次数,减轻每次循环的工做量的方式提高性能。
对于条件语句if else
或者switch
,其性能在现实中并无太大区别,关键是要正确处理语义化的需求。有的时候也可使用查表法进行。
对于递归算法,最好的提高性能方法是缓存上次执行的结果,在下一次递归的时候直接引用而非从头开始计算。
前面五章都是针对JS原生的语法分析性能问题,从这一章开始分析针对用户界面的可感知性能问题。
因为浏览器是单线程运做的,在处理UI事件的时候没法处理js事件,反之亦然,因此对于耗时过长的js任务来讲,可使用定时器的方法使其让出线程控制权,让浏览器优先处理UI事件以提高用户体验。
html5新增的web worker
容许多开线程,意味着耗时较长、性能损耗较大的js任务能够放到web worker
中进行,而无需阻塞浏览器UI线程的执行。值得注意的是,web worker
没法使用浏览器相关的资源,因此没法用以进行dom操做等。
ajax
技术已是现在的主流技术,在这里就无需赘述了。书上关于其性能优化的内容,多集中在浏览器资源缓存上。若是可以有效利用浏览器的缓存机制,能够大大减小与服务端的交互,提高性能。
书上没有说起的是如今逐渐开始流行的fetch API
,关于这方面的性能的问题也值得咱们研究。