首页 > 技术文章 > 《高性能网站建设进阶指南》笔记

hellohello 2017-11-28 17:16 原文

浏览器通常在运行js上花费的时间很少,绝大部分时间都消耗在dom上。
使用浏览器性能评估工具
内存出现问题时,可以从这两方面入手:1.delete不再需要的js对象。2.移除不必要的dom
代码拆分:doloto工具用于把代码分成两部分:1.onload前执行。2.onload后异步下载执行

延迟加载代码的情况:
1.与UI有关。在js中,动态绑定元素的交互事件。这样下载前,用户点击没有任何反应,下载后才可以点击
2.与UI无关。可以先使用桩函数(函数体里面什么都不做,桩函数仅仅使调用的地方不报错而已),后续下载的js用同名的函数,把这个桩函数覆盖即可,达到动态的代码替换。更高级的桩函数用法,被调用时记录调用次数,等js下载完后,自动进行相同次数的调用

常规方式加载js会阻塞页面其他资源的下载,还会阻塞脚本后面的元素渲染,使用异步加载js方式可以避免这种阻塞现象,从而提高页面加载速度
异步的js下载:
1.xhr注入。ajax获取js,然后创建标签,把js设置到标签中
2.动态创建script标签,引用外部的js文件
3.使用script的defer属性

行内脚本会阻塞资源的下载和页面渲染,解决办法是
2.使用defer属性处理行内脚本(?)
3.异步启动js的执行(onload)
ps:假如图片下载需要1s,并且启动了150ms后执行js(执行时间需要5s)。则首先下载图片,150ms后,有一个timer事件进入队列,1s后图片下载完了,渲染图片的消息进入队列。js从队列中取出第一消息是timer,接着执行js(执行时长5s),完成后取出下一个消息,渲染图片


高效js:
1.尽量使用局部变量,或把多次访问到的全局变量保存为局部变量来访问。(减小作用域链的访问长度)
2.with会把一个新的对象添加到作用域链的顶部,增加了长度(with结束会自动恢复),尽量避免使用with
3.tryCatch的catch也会增加作用域链的长度,尽量不要在catch块中执行过多代码
4.将多次访问的对象属性保存为局部变量,替换为访问局部变量,可以较少对对象属性的查找(如循环数组的时候,把arr.length保存为局部变量来访问)
5.访问属性的时候,访问的对象层次越低越好。a.b.c.val 效率低于 a.val
6.obj.val 和 obj['val'] 效率上来说基本没区别
7.操作dom对象比非dom对象消耗更大,更要注意以上的优化

8.按照命中的频率来调整if else的判断次序,常见的放在顶部,这样命中之前所做的判断就会更少(同样的道理也可以应用到switch上)
9.对多个if else 进行if 二分拆分 可以提高效率(但会导致括号嵌套层数增加,代码多的时候看上去很混乱)
10.以上两个优化如果不是范围判断,而是等值判断的话,可以放到数组或对象中,这样一来可以直接命中,而不需要判断

11.避免使用forin来遍历对象属性,这会访问到整个原型链。如果已知对象的属性,就直接访问吧
12.连接字符串的时候是使用加法还是使用数组的join来连接,不同浏览器有不同的优化,一般情况下,加法是首选

常见的导致js运行时间过程的原因:
1.过多的dom操作
2.循环次数多
3.递归层次深

comet:是一种提升传统ajax的速度和拓展性的技术实现的合集
传输技术:
1.轮询:setTimeout,定期发送ajax请求
2.长轮询(Long polling):
client:发送ajax请求,响应的回调函数中重新发送ajax请求
server:接收到请求,并且等到有新数据的时候才响应,期间会一直处于连接状态,等待数据
3.xhr流:监听ajax的readystatechange,当code=3的时候,就可以通过xhr.responseText获取响应,调用回调函数。接着code=4的时候连接还没关闭,可以在这时候发出一个新的ajax请求,达到流的复用

4.启用gzip压缩

代码精简:
1.事件委托:将对个绑定在子元素上的点击事件,修改为一个绑定在父元素上的点击事件。
2.为较长的js变量或函数设置别名(用另一个较短的变量来赋值)

对gzip进行嗅探:
背景:有的浏览器支持gzip,但发送的请求中没有accept-Encoding说明,导致服务器没有响应经过gzip压缩的数据,降低了效率
解决:
1.往页面上添加一个display:none的iframe,src指向 a
2.a 的响应式一个压缩过的html。原文内容是:document.cookie.write(xxxx)记录一个cookie。这里的作用是如果浏览器支持gzip压缩,则通过iframe请求的a内容会被正常解析,会记录一个cookie,后续的所有请求中,如果有这个cookie,则响应经过压缩的数据,也就是不用依赖accept-Encoding了。如果浏览器不支持gzip,则iframe中的内容是乱码,不能正常解析,也就不会设置cookie了

提高网站对资源的下载效率:
1.资源分配到多个域名下,如a.site.com,b.site.com,,c.site.com等,浏览器对单个域名的并行连接数有限,所以多个域名,则并行连接数也会提升,但dns查找的时间会增加

关于iframe:
好处:文档独立于父文档
缺点:
1.创建iframe比创建其他元素时的消耗要高1~2个数量级,是消耗最高的元素
2.iframe阻塞onload事件,解决办法:动态设置src值的方法
3.与父文档共享相同域名下的并行连接数;不利于SEO,爬虫不易读取iframe中的内容

 

css选择符的执行过程是从右往左的。#ta a{} 这会匹配所有的a,然后查找是否存在id=ta的的父元素及祖先元素,开销相当大。
最右边的选择符称为关键选择符,匹配的元素越少越好

降低reflow

推荐阅读