前端面试中经常问到的问题:如何提高网站性能 总结

前端面试中经常问到的问题:如何提高网站性能 总结

1. 使用dns预解析

DNS 请求需要的带宽非常小,但是延迟却有点高,这点在手机网络上特别明显。预读取 DNS 能让延迟明显减少一些,例如用户点击链接时。在某些情况下,延迟能减少一秒钟。 
在某些浏览器中这个预读取的行为将会与页面实际内容并行发生(而不是串行)。正因如此,某些高延迟的域名的解析过程才不会卡住资源的加载。
这样可以极大的加速(尤其是移动网络环境下)页面的加载。在某些图片较多的页面中,在发起图片加载请求之前预先把域名解析好将会有至少 5%的图片加载速度提升。
你可以通过在服务器端发送 X-DNS-Prefetch-Control 报头,或是在文档中使用值为 http-equiv 的 <meta>标签:

打开和关闭 DNS 预读取

在高级浏览器中a标签是默认打开预解析的,但是在https协议中是默认关闭的,此句话是强制打开a img script等 标签的预解析
<meta http-equiv="x-dns-prefetch-control" content="off">
link标签的dns预解析
<link rel="dns-prefetch" href="//host_name_to_prefetch.com">
您可以通过将 content 的参数设置为“on”来改变设置。

强制查询特定主机名

你可以通过使用 rel 属性值为 link type 中的 dns-prefetch 的 <link> 标签来对特定域名进行预读取:
<link rel="dns-prefetch" href="http://www.spreadfirefox.com/">
在这个例子中,Firefox将预解析域名"www.spreadfirefox.com"。

而且,<link> 元素也可以使用不完整的 URL 的主机名来标记预解析,但这些主机名前必需要有双斜线:

<link rel="dns-prefetch" href="//www.spreadfirefox.com">
强制对域名进行预读取在有的情况下很有用, 比如,
在网站的主页上,强制在整个网站上频繁引用的域名的预解析,即使它们不在主页本身上使用。即使主页的性能可能不受影响,这将提高整体站点性能

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

通过webpack,grunt等打包工具,对于js,css文件进行打包成单个的js以及css,使用gzip进行代码压缩,从而减少请求文件的大小以及数量,每个js,css文件的加载都要发送一次http请求,所以通过合并js,css文件从而减少http请求次数。

3.浏览器缓存

1.强缓存

  • Expire(绝对时间,下发的服务器时间,有可能客户端和服务端时间不一致。Expire:Thu,21 Jan 2017 23:39:02
    GMT);
//在前端<head>标签中设置
<meta http-equiv="expires" content="0">  

//在后端设置
response.setDateHeader("Expires",date.getTime()+20000); //Expires:过时期限值 
response.setDateHeader("Expires", 0);//不允许浏览器端或缓存服务器缓存当前页面信息。
  • Cache-Control(相对时间,按照客户端时间,3600秒内使用缓存。Cache-Control:max-age=3600)
//在前端<head>标签中设置
<meta http-equiv="cache-control" content="no-cache">

//在后端设置
response.addHeader( "Cache-Control", "no-cache" );//浏览器和缓存服务器都不应该缓存页面信息

在http响应头中,如果两个时间都有,以Cache-Control为准

2.协商缓存(问一下服务器)

Last-Modified(服务器下发的响应头中加,Last-Modified:Thu,21 Jan 2017 23:39:02 GMT)
If-Modified-Since,(http请求头中加,时间和Last-Modified下发的一致,缺点:文件没变但时间过期,会再次加载
//在后端设置
response.setDateHeader("Last-Modified",date.getTime()); //Last-Modified:页面的最后生成时间 
Etag (哈希值,服务器下发的响应头中加,文件没改变可继续使用缓存) If-None-Match(http请求头中加,时间和Etag下发的一致)
//响应消息头
Etag:"a030f020ac7c01:1e9f" 

关于下面这些HTTP请求头部字段以及相关的http知识,可以去阅读 《图解http》一书,对此有详细的文字跟图解

  • Expire
  • Cache-Control
  • Last-Modified
  • If-Modified-Since
  • If-Modified-Since
  • If-None-Match

4.异步加载

异步加载的方式:

1.动态脚本加载(动态创建节点:document.createElement("/script/"),用js创建一个标签,再加到文档中);
2.defer(在script标签中加上此属性);
3.async(在script标签中加上此属性)。 
异步加载的区别:
1.defer是在HTML 解析完 之后才会执行,defer属性规定是否对脚本执行进行延迟,直到页面加载为止,如果是多个,按照加载的顺序依次执行 ;
2.async是在加载完之后 立即执行 ,async属性规定一旦脚本可用,则会异步执行,如果是多个,执行顺序和加载顺序无关。
这里来一张defer跟async,还是用图解比较明了

此图告诉我们以下几个要点:

defer 和 async 在网络读取(下载)这块儿是一样的,都是异步的(相较于 HTML 解析)
它俩的差别在于脚本下载完之后何时执行,显然 defer 是最接近我们对于应用脚本加载和执行的要求的 关于
defer,此图未尽之处在于它是按照加载顺序执行脚本的,这一点要善加利用 async
则是一个乱序执行的主,反正对它来说脚本的加载和执行是紧紧挨着的,所以不管你声明的顺序如何,只要它加载完了就会立刻执行 仔细想想,async
对于应用脚本的用处不大,因为它完全不考虑依赖(哪怕是最低级的顺序执行),不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的,最典型的例子:Google
Analytics

猜你喜欢

转载自blog.csdn.net/shadow_zed/article/details/88095667