优化原则
非核心代码异步加载的方式
异步加载的三种方式:async和defer、动态脚本创建。
(1)async方式
<script type="text/javascript" src="xxx.js" async="async"></script>
- async属性是HTML5新增属性,需要Chrome、FireFox、IE9+浏览器支持
- async属性规定一旦脚本可用,则会异步执行
- async属性仅适用于外部脚本,如果是多个脚本,该方法不能保证脚本按顺序执行
(2)defer方式
- defer属性兼容所有浏览器,规定是否对脚本执行延迟,直到页面加载为止
- 如果是多个脚本,该方法可以确保所有设置了defer属性的脚本按顺序执行
- 如果脚本不会改变文档的内容,可将defer属性加入到script标签中,以便加快处理文档的速度
(3)动态创建script标签
在还没有定义async和defer前,异步加载的方式是动态创建script,通过window.onload方法确保页面加载完毕再将script标签插入到DOM中。
代码实现:
function addScript(src){
var script=document.createElement('script')
script.setAttribute("type","text/javascript")
script.src=src
document.body.appendChild(script)
}
window.onload=function(){
addScript("js/index.js")
}
异步加载的区别
(1)defer是在HTML解析完之后才会执行,如果是多个,按照加载的顺序依次执行。
(2)async是在加载完之后立即执行,如果是多个,执行顺序和加载顺序无关。 蓝线:网络读取 红线:执行事件 绿线:Html解析
利用浏览器缓存
对于网页来说,缓存是提升页面性能的同时减少服务器压力的利器。
强缓存
**强缓存:**不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的network选项中可以看到该请求返回200状态码。判断是否缓存依据:是否超出某个时间或时间段。
相关header:
Expires :响应头里的过期时间,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存。例如:Expires:Thu,21 Jan 2023 23:39:02 GMT(静态组件)Cache-Control :这是一个相对时间,在配置缓存时以秒为单位,用数值表示。当值设置为max-age=300时,代表在这个请求正确返回时间的五分钟内再次加载资源,就会命中强缓存。例如:Cache-Control:max-age=300(动态组件)- Cache-Control优先级高于Expires。
强缓存不关心服务端文件是否已经更新,这可能导致加载文件不是服务端最新的内容。这时就要用到协商缓存。
协商缓存
**协商缓存:**向服务器发送请求,服务器会根据这个请求的请求头的参数来判断是否命中协商缓存。如果命中则返回304状态码,并带上新的响应头通知浏览器从缓存中读取资源。协商缓存需要与cache-control共同使用。
相关header:
ETag :ETag是上一次加载资源时,服务器返回的响应头,是对该资源的一种唯一标识,只要资源有变化,ETag就会重新生成。
浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的ETag值放到请求头里的If-None-Match 里,服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源的ETag是否一致,就能判断资源相对于客户端而言是否被修改过。
如果服务器发现ETag匹配不上(说明资源更新了),那么直接以常规GET 200回包形式将新的资源(包括新的ETag)发给客户端;如果ETag是一致的,则直接返回304知会客户端直接使用本地缓存即可。
缓存的机制
强缓存优先于协商缓存,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(ETag/If-None-Match)。协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存。
用户行为对浏览器缓存的影响:
- 地址栏访问,链接跳转是正常用户行为,将会触发浏览器缓存机制
- F5刷新,浏览器会设置max-age=0,跳过强缓存判断,会进行协商缓存判断
- ctrl+F5刷新,跳过强缓存和协商缓存,直接从服务器拉取资源
减少DNS的查找
用户访问网站的过程如下:
- 在地址栏输入网址,如:https://www.baidu.com
- 本地DNS得到这个请求,查询本地DNS缓存,如果有这条记录,则直接返回对应的IP;否则,请求网络上的DNS服务器,得到相应的IP,返回给客户端,并缓存这条记录。
- 浏览器向得到的IP发起建立连接请求,得到响应后建立连接,请求数据
- 服务器端计算所需数据,并返回给客户端
- 客户端即浏览器,解析数据并显示在浏览器窗口中,至此,请求完成。
在一次请求中,DNS解析可以占到请求时间的1/3,所以缩短DNS请求时间是很有必要的。
方法:DNS预解析
DNS预解析
DNS预解析的主要作用就是在浏览器本地会有一些DNS缓存,浏览器请求地址时,如果发现地址在DNS缓存中,就可以直接请求本地的IP地址,省去了向DNS发起请求查找服务器地址的时间。
dns-prefetch 的使用:
<link rel="dns-prefetch" href="http://hm.com"></link>
AJAX优化
对请求进行优化,能用get请求的尽量用get请求。
(1)post请求需要进行两步操作(首先发送头部信息,然后再发送数据),如果是get请求的话,就只有一个TCP的包发送出去,这样无疑提高了性能。所以post请求的性能比get请求要差一些。
(2)对于Ajax请求而言,有一些特殊性,并不是所有的Ajax请求都是可以缓存的。
在使用Ajax请求的时候,考虑使用缓存,可以避免往服务器进行重复请求,节约网络资源,提高页面性能。
Cookie优化
- 减小cookie大小
在发送请求时,浏览器会将cookie信息发送到服务器,所以应该只在cookie中存必要信息,且长度越小越好。在写cookie时,要记得给cookie设置一个合理的过期时间。 - 去除不必要的cookie
- 设置合适的cookie过期时间
其他方法
- 将CSS放在顶部,JS放在底部
- 避免重定向(3xx)和找不到资源(404)
|