页面性能

1. 提升页面性能的方法

  • 资源压缩合并,减少 HTTP 请求
  • 非核心代码异步加载
  • 浏览器缓存
  • 使用 CDN
  • 预解析 DNS

1.1 资源压缩合并,减少 HTTP 请求

1.2 非核心代码异步加载

1.2.1 异步加载的方式
  • 动态脚本加载()

    1
    document.createElement
  • defer

  • async
1.2.2 异步加载的区别
  • defer 是在 HTML 解析完之后才会执行,如果是多个,按照加载的顺序依次执行
  • async 是在加载完之后立即执行,如果是多个,执行顺序和加载顺序无关

举个栗子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
<script src="./defer1.js" defer></script>
<script src="./defer2.js" defer></script>
...
<script type="text/javascript">
console.log('write');
</script>

<script type="text/javascript">
for(var i=1; i<=40000; i++){
if(i%20000 === 0) {
console.log(i);
}
}
</script>

输出结果:

1
2
3
4
5
write  
20000
40000
defer1
defer2

标记了 defer 属性的 script 标签是按照加载顺序执行的。如果将:

1
2
<script src="./defer1.js" defer></script>
<script src="./defer2.js" defer></script>

修改为:

1
2
<script src="./defer1.js" async></script>
<script src="./defer2.js" async></script>

且将 defer1.js 的内容增加,则有可能出现 defer2 先于 defer1 打印的情况。

1.3 浏览器缓存

  • 强缓存:不管是否有更新,都用本地缓存
    • Expires: 过期时间(服务器的绝对时间)
      例如: Expires: Thu, 21 Jan 2017 23:39:02 GMT 表示在服务器时间之前,均使用缓存文件
    • Cache-Control: 相对时间(客户端的相对时间),单位:秒
      例如: Cache-Control: max-age=3600 表示客户端缓存下来的3600秒内不再请求新数据,直接使用本地缓存

如果二者同时出现,则由 Cache-Control

  • 协商缓存:与服务器确定是否用本地缓存
    • Last-Modified Last-Modified: Wed, 26 Jan 2017 00:35:11 GMT
    • If-Modified-Since
      • Etag
      • If-None-Match

举个例子:
发送请求时,请求头中携带发送时间为 Last-Modified,返回的时间为 If-Modified-Since

Last-ModifiedIf-Modified-Since 只能判断更新时间,无法判断内容
EtagIf-None-Match 可以判断内容

1.4 使用 CDN

第一次打开网站时,无法使用缓存,CDN 则能提高网站性能。

CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。

1.5 预解析 DNS

DNS: Domain Name System,即域名系统,是域名和IP地址相互映射的一个分布式数据库。域名解析即通过主机名,最终得到该主机名对应的IP地址的过程。

DNS 请求需要的带宽非常小,但是延迟却有点高,这点在手机网络上特别明显。DNS预解析 能让延迟明显减少一些,例如用户点击链接时。在某些情况下,延迟能减少一秒钟。

DNS预解析是浏览器试图在用户访问链接之前解析域名,这是计算机的正常DNS解析机制。域名解析后,如果用户确实访问该域名,那么DNS解析时间将不会有延迟。

1
2
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//host_name_to_prefetch.com">