优化网站性能方法,让快速访问网站不在是梦想

目录
文章目录隐藏
  1. 尽可能减少 HTTP 的请求数
  2. 使用 CDN(内容分发网络)
  3. 添加 Expire/Cache-Control 头
  4. 启用 Gzip 压缩
  5. 将 css 放在页面最上面
  6. 将 script 放在页面最下面
  7. 避免在 CSS 中使用 Expressions
  8. 把 JS 和 CSS 放到外部文件中
  9. 减少 DNS 查询
  10. 最小化 JavaScript 和 CSS
  11. 避免重定向
  12. 移除重复的脚本
  13. 配置实体标签(ETag)
  14. 使用 AJAX 缓存
优化网站性能方法,让快速访问网站不在是梦想

  互联网大家很熟悉,已经深入到我们生活的方方面面,使得用户对快速访问网页需求越来越高,对于企业来说用较低的成本较快的速度去留住用户流量就是在日益竞争的环境下取胜的关键,而做为网站建设者的我们,如何提高网站性能,成为急需去解决的问题,本文让你清楚认识到影响网站性能的原因,从而避免不利于网站性能的因素,同时借助 Yslow 工具快速找到问题所在,提高网站性能,让提高网站性能、快速访问网站不在是梦想。

尽可能减少 HTTP 的请求数

  什么是 HTTP 请求?官方的定义是:从客户端到服务端的请求消息。包括首行中,对资源的请求方法,资源的标识符及使用协议。这个解释很标准,但我们理解起来很困难,接下来我用菜鸟的原方式解释一下什么是 HTTP 请求,简单地说就是当你打开网页的时候,你所看到的图片、文字、多媒体等等,这一切内容都是你从服务器获取的,每一个内容的获取就是一个 HTTP 请求。

我用一张图来给大家解释一下:

尽可能减少 HTTP 的请求数

  从上图可以看出,当我们打开一个网页的时候,左边部分图片 1、图片 2、图片 3 等等,脚本文件 javascript1、javascript2 等等,样式文件 css1、css2 等等,这些都是要从服务器上来获取的,那么,每一个文件就是一个请求,当文件较多的时候,这个请求数就会很庞大。我们来看一下右边部分,这是一个优化后的请求,我们可以很直观的看到,我们将图片进行了合并,脚本文件进行了合并,样式文件进行了合并,这样当我们再次请求的时候,文字是一个请求,图片 1、2、3 合并成一个文件,脚本 javascript1、2、3 合并成一个文件,css1、2、3 也合并成了一个文件,这样我们可以看到请求数相对于左边只有四个请求,这样对服务器的压力就会减轻了许多。这是一个靠我们智慧就能解决的问题

使用 CDN(内容分发网络)

  什么是 CDN?官方给我们很长的一个解释:内容分发网络,意思是尽可能避免互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN 系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet 网络拥挤的状况,提高用户访问网站的响应速度。

  很长的一个书面解释,还是用我们菜鸟的语言来解释一下吧,简单地说,在离你最近的地方,放置一台性能好链接顺畅的副本服务器,让你能够以最近的距离、最快的速度获取内容。同样让我们用一张图来解释一下:

使用 CDN(内容分发网络)

  从图上可以很直观地看出,在没有使用 CDN 系统的时候,上面第一这台电脑当访问服务器的时候,要通过多个节点即三个小圈(红色的箭头走向),最后到达服务器获取内容。第二台电脑也要通过多个节点即两个小圈(蓝色箭头走向),来到大服务器获取内容。当我们使用 CDN 系统时,我们就可以把服务器制作成两个副本,将这两台副本服务器放置在离用户最近的地方,这样当用户访问这台服务器的时候,他就可以直接访问副本服务器来获取他想要的内容,这样从距离和速度上节省了很多,那么,很明显可以看到这需要添加服务器的,那么服务器是什么呢?服务器就是 money,每一台服务器就是成本,所以这是一个靠 money 来解决的问题。当然,如果你 money 富裕的话这就不是问题了。

添加 Expire/Cache-Control 头

添加 Expire/Cache-Control 头

  如果 apache(Web 服务器)开启了 expire 模块,当浏览器发送资源请求的时候,apache 返回资源的同时,会返回一个名为 expire 的 http 头,expire 头的内容是一个时间值,值就是资源在本地的过期时间,存在本地。在本地缓存阶段,找到一个对应的资源值,当前时间还没超过资源的过期时间,就直接使用这个资源,不会发送 http 请求。

  Cache-Control 是 http 协议中常用的头部之一,顾名思义,他是负责控制页面的缓存机制。如果该头部只是缓存,缓存的内容也会存在本地,操作流程和 expire 相似,但也有不同的地方,cache-control 有更多的选项,而且也有更多的处理方式。

启用 Gzip 压缩

  什么是 Gzip 压缩?Gzip 思想就是把文件先放到服务器压缩一遍然后再称述,这样可以显著的减少文件存储的大小,称述完毕之后,浏览器会重新对压缩过后的文件进行解压缩并执行。目前浏览器都能够很好的支持 Gzip。

启用 Gzip 压缩

  在 YAHOO 也特别强调了,所有的文本内容进行 Gzip 压缩,这些文本包括 HTML、PHP、JS、CSS、XML、TXT 等等,使用 Gzip 的好处就是将稳健的体积变小,下面我们以 79KB 的文件为例,通过小图图表来说一下,假设原本一个 79kb 的 js 文件,在本地压缩后达到 28kb,如果在服务器我们对 79kb 的原始的 js 文件进行 Gzip 压缩它的大小可以达到 25kb,如果我们在服务器端,对已压缩过的 js 文件再进行 Gzip 压缩,那么它的大小就可以达到 15kb,那么通过这个图表可以很明显看到这个原始 js 文件和这个通过 Gzip 压缩过的文件大小(最后小蓝柱)是相差好几倍的,这个在提升文件访问速度起着至关重要的作用,这个在我们服务器端配置一下就可以了,很简单。

启用 Gzip 压缩文件对比

将 css 放在页面最上面

  css 层叠样式表(英文全称:CascadingStyleSheets),层叠意味着后面的 css 可以覆盖前面的 css,级别高的 css 可以覆盖级别低的 css,那么,为什么要把 css 放在页面最上边呢?其实是为了解决一个问题,在 IE 下,把 css 放在页面底部的问题,在于它禁止了网页内容的显示,IE 阻止内容的显示以免重画页面元素,在低网速的条件下,用户打开的时候就只能看到空白页了。在 Firefox 浏览器里面,虽然不会阻止显示,但当 css 下载后页面部分元素可能需要重画,所以为了提高浏览器的性能,避免出现空白或闪烁的问题,我们应该将 css 放在页面额顶部 head 中,先进行加载和渲染,这样就避免上述提出的问题。

将 script 放在页面最下面

首先我们来了解一下 dome 的加载顺序,从下图可以看出,当我们打开网页的时候,加载顺序首先是读取 HTML 标签,然后是 head 标签,然后读取 head 标签内的 meta 标签,接着是 title 标签,然后是 title 内容,最后读取 style 标签,这时开始加载样式,加载完之后,开始解析这个样式,解析完之后继续向下读,读到了 link 标签,这会它会加载外部样式文件表进行解析,然后继续向下读,读到 script 标签,加载外部的 script 文件,解析这个文件并执行这个脚本文件,最后继续向下,读到 body 标签,然后读到里面的 div 标签,最后读到 img 标签加载外部头像,加载完毕,整个过程完成。

将 script 放在页面最下面

  了解完这个顺序后,我来解释一下为什么将 script 放在页面最下方,依照上面的例子我写一个死循环,当读到这儿的时候,浏览器会不停的执行它直到死机,所以在用这个脚本的时候大家要注意,我们只是在这里做一个测试,平时这个脚本是万万不能用的,用了以后 IE 奔溃了,我们也就彻底奔溃了!老板也疯了。如果按这样执行的话,在页面上打开就是一个空白,感兴趣的小伙伴下去可以试试,因为它执行 for 的时候浏览器一直在执行它,不会向下进行标签的读取,这样就会阻止下面内容的显示。

将 script 放在页面最下方

  同样我们将这段代码放在最下面前,依照 dome 加载顺序浏览器会依次向下逐步加载,将图片显示出来,当读到底部的 script 的 for 循环的时候,它同样的进行了一个不停地循环,虽然在这个时候浏览器死循环了,但是我们可以看到浏览器加载出来了,该显示的内容都显示出来了,通过这个实例很明显的看到将 script 标签放在页面底部的优势,它会先将页面呈现出来,不会让用户等的太久。

避免在 CSS 中使用 Expressions

  什么是 CSS Expressions?CSS Expressions 俗称 css 表达式,是用来把 css 属性和 javascript 表达式关联起来,这里的 css 属性可以是元素固有的属性,也可以是自定义属性,就是说 css 属性后面可以是一段 javascript 表达式,css 属性的值等于 javascript 表达式的计算结果。

避免在 CSS 中使用 Expressions

  那么它的问题是什么呢,问题是 CSS Expressions 计算频率要比我们想象的多得多,不仅仅是在页面显示和缩放的时候,就是在我们页面滚动乃至鼠标移动的时候都会重新计算一次,给 css 表达式增加一个计数器可以跟踪表达式的计算频率,在页面上随便移动鼠标都可以达到一万次以上的计算量,说到这儿大家觉得不太容易理解,我们以一个实例看一下。

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CSS Expressions 测试</title>
    <script>
        var i = 0;
        function scare() {
            i++;
            document.getElementById('run').value = i;
            return;
        }
    </script>
    <style>
        ul a{width:expression(this.offsetWidth > 750 ? scare() : scare());}
    </style>
</head>
<body>
当鼠标移动时,CSS Expression 计算了<input id="run" />次 <!--请在 IE6、7 下执行这段代码-->
<ul>
    <li><a href="http://baidu.com">aaa</a></li>
    <li><a href="http://baidu.com">bbb</a></li>
    <li><a href="http://baidu.com">cccc</a></li>
</ul>
</body>
</html>
CSS Expressions 计算频率

  通过例子我们可以看到,当我们移动鼠标的时候,input 内的数字在不断的变化,这就说明我们在使用 CSS Expression 的时候,在我们移动鼠标的时候,浏览器会不停的计算,最后严重影响浏览器的性能,影像用户的体验,所以我们应该避免使用 CSS Expression。

把 JS 和 CSS 放到外部文件中

  关于这一点呢有很多争议,有人说把 js 和 css 全部提出来放到单独文件里引用,说这样会减少页面的体积,那反对的人就说了,应该写在页面里面减少请求数,这样可以提高页面渲染速度,加快页面呈献。其实在做这条优化的时候呢,我们应该灵活的使用,千万不可死背教条。

把 JS 和 CSS 放到外部文件中

  首先,我们分析一下提出来的好处与缺点,将 css 和 js 提出来的好处是一是提高了 js 和 css 的复用性,不用每个页面都去定义一次。二是减少页面体积,页面体积减少了那打开页面的速度当然就快了,脚本文件和样式文件被页面单独缓存。三是提高了 js 和 css 的可维护性,这一点虽然与性能无关,但其实也挺重要的,在后期的维护中如果前期的基础打得不好的话,后期维护就非常困难。

  缺点就是单独的文件增加了请求数,如果文件比较多的情况下,这个请求数肯定就会增加,影响网站的性能,其实这点也是可以通过缓存来优化的。

  说到它的好处与确定之后,那么是不是见到 js 和 css 就要单独提取出来呢?在实际的工作中并不是这样的,这里给大家总结一下在一些特殊的情况下还是要写在页面内的:

  一、当某个脚本和样式只应用于一个页面的时候,而且其他页面不会用到,这样放到内部的好处是大于提取出来的,因为相对于你的整个网站来说,只有一个页面使用那就没有必要再提取出来了。

  二、一个不经常被访问到的页面,也可以将 css 和 js 写在页面内部,因为你的这个页面只是偶尔打开使用,那就没有必要将 css 和 js 单独提取出来形成一个文件去使用,从而增加了文件系统的紊乱。

  三,脚本和样式非常少的情况,如果你的样式和脚本只有那么一两行或者三四行五六行,总之不多于 20 行,那你就没必要写到一个单独文件里了。

减少 DNS 查询

  怎么减少 DNS 查询?比如我们要访问 www.a.com 的时候,再打开这个页面之前,计算机是不知道 www.a.com 是什么,在哪里,它必须通过一种转换机制到达这个页面,这种机制能够将这个网址对应一个 IP 地址,一个计算机理解的地址,那计算机只认 IP 地址,它不懂域名是什么,然后通过这个 IP 地址对应到 www.a.com 这个网站,整个过程就是 DNS 查找过程。

怎么减少 DNS 查询

  既然是一个查找过程,那肯定是要消耗时间的,根据经验来说大概需要 20 毫秒的时间,在这个 20 毫秒的过程中呢,我们的浏览器是得不到任何资源的,所以这期间我们的浏览器是一片空白,大大家试想一下,如果我们的网站有很多这样的查找过程,对我们打开网站的性能肯定是有很大的影响的。所以我们要对这个过程进行缓存,缓存之后就可以减少这种查找过程,那么,由于现在浏览器都很智能,功能也强大了许多,自身都带了缓存的机制,所以对于操作系统的缓存这里不做介绍,因为现在浏览器自己都有缓存了。

  简单介绍浏览器的缓存,现在主流浏览器大家从下图可以看出三大阵营 IE、Firefox、谷歌,三种浏览器缓存时间各有各的特点,IE 浏览器默认情况下 DNS 缓存时间是 30m,Firefox 浏览器缓存时间大概是 60s,谷歌与 Firefox 基本相同也是 60s,具体他们时间长短为什么不同,我们只能推测大概和他们的浏览器厂商有关。

介绍浏览器的缓存

  缓存时间长短有什么不同呢?当缓存时间长的情况下,就会减少 DNS 重复查找,因为它被缓存了,浏览器会直接从缓存里面查找,节省时间。当缓存时间短的情况下,浏览器会及时的检测到指定网站 IP 地址的变化,保证访问的正确性,那在这个时间的长短上就各有各的好处。所以在缓存时间长短各有利弊的情况下,就导致各个浏览器厂商设置不同。那在做这条优化的时候呢,我们可以根据自己网站的特点来配置相应的技术点,比如我们采用是多域还是单域形式放置资源,比如多域我们可以把 html 文件、图片、js 都分别提出来放在分别得域名下。单域就是把所有的文件、图片、脚本等等都放在一个服务器上。如果我们采用的是多域的方式的话,我们要考虑采用几个域名是最佳的点,不是越多越好,这个就需要大家通过实践来一点点感悟,感兴趣的小伙伴下去试试看看采用几个域名配置网站资源是最合适的。

缓存时间长短有什么不同呢

最小化 JavaScript 和 CSS

  最小化从字面上理解就是使 javascript 文件和 css 文件最小化,减小文件体积,从而提高在页面上的加载速度,那么通过什么方法可以减少文件体积呢?这里我介绍一下,一是可以去除一些不必要的空格,不必要的格式符,不必要的注释,简单理解就是代码的格式化,二是通过简写自定义的方法名、参数名压缩 js 脚本。

  这里我们以 jQuery 为例,我分别下载了两个 jQuery 版本,一个是压缩版的,一个是未压缩版的。

版本压缩对比

  首先我们从图中看到,未压缩的大小为 276kb,一共有 282944 个字节,共 10338 行。压缩后的版本大小为 94.1kb,一共有 96381 个字节,共 5 行。大家可以对比这三个值,压缩和未压缩是有很大差别的,所以建议大家在项目正式上线前,将你的 javascript 和 css 都进行一下压缩,使线上的版本是最轻量级的,这样可以大幅度提升我们网站的性能。

避免重定向

什么是重定向呢

  什么是重定向呢?就是原始请求被重新转向了其他的请求,通俗的说就是用户想访问的页面 a 被重新指向了页面 b。那由于重定向有它存在的必要性,所以在 http 协议中有两种状态码标识这种情况,分别是 301 和 302。

  301 重定向表示用户请求的页面被移动到另外位置,比如 a 页面移动到 b 页面,那用户端收到这个反馈后,它会再发起另外一个请求去 b.com 去下载所需要的资源。

  302 重定向表示用户所请求的页面被找到了但不在原始位置,所以服务器会回复它一个地址,用户端收到这个反馈后同样会发起另外一个请求,去服务器返回的地址中下载资源。

  上面的例子我们比较啰嗦解释 301 和 302,其实 301 简单概述就是永久重定向,302 表示临时重定向,这就很好理解了。

避免重定向

  有的小伙伴会有疑问了,301 和 302 都是重定向,它们有什么区别呢?

  对用户来说没有什么区别,无论你是那种重定向你都是要重新请求下载资源,那为什么还要避免使用它呢?对搜索引擎来说,301 和 302 就完全不一样了,现在我们上网几乎干什么都要去搜索一下,所以搜索引擎对于我们是不可缺少的部分,大家都知道搜索引擎会不定期的对网站进行扫描,SEO 技术人员称蜘蛛爬网,为什么要定期去爬网呢,就是为了完善索引结构,让大家想找什么就找什么,所以它会定期的去爬网。若果你的网站使用了 301 永久重定向,蜘蛛爬虫看到你的网站指向了新域名,它就会智能分析永久记住你这个新域名从而删除你的旧地址,比如说用户通过搜索引擎搜索 a.com,你通过跳转直接就到 b.com 了,而不会走从 a 再到 b 这样一个过程。302 呢就不一样了,如果你使用的是 302 临时重定向,无论你从哪去跳,你都要先经过 a 再到 b,它不会分析,就是机械的从 a 到 b。

  通过上面对比 301 和 302 对搜索引擎来说 301 使搜索引擎更智能了。

  为什么要避免使用重定向?

为什么要避免使用重定向

  无论是 301 还是 302 它都增加了服务器到浏览器之间的往返次数,就是当用户发送访问 a 的请求时,服务器收到了,但由于 a 重定向了,重定向了 b,所以服务器会返回一个重定向信息时 301 或者是 302,并把这个信息写在 header 中,并在 header 中返回新的地址即 b 这个地址,但是 body 中是空白的,用户端在收到这个反馈后知道了原来地址改了,改到 b 了。所以用户的浏览器会再次请求到 b,然后才打开网页下载资源。

  从上面整个过程可以看到,用户多了一层获知新地址的过程,这必然增加了浏览器到服务器建的返回次数,其实在上面就讲到了尽量减少 http 请求,所以在不得以的情况下避免使用它。

移除重复的脚本

  移除重复脚本,即不要使用重复的脚本,说到这儿可能有的小伙伴说了这不是废话吗,但究其原理你知道重复使用会出现什么问题吗,我们通过例子看一下。

<body>
<input type="text" id="test" value=""/>
<script>
    var number = 0;
</script>
<script src="test.js"></script>
</body>

   我在 HTML 页面上定义变量 number 等于 0,新创建的 js 文件中给 number 执行++操作,然后将 number 变量增加后的值填入到我们 input 框内,最后在页面上引入改 js 文件。

number ++
document.getElementById('test').value = number;
移除重复的脚本

  注意我们的初始值 number 为 0,我们在页面上看到 input 框内的值变为 1,原因是我在 js 文件中执行了 number++操作,它的值有 0 变为 1,这是个正确的结果。但是由于我们不小心重复的引用了这个脚本,它会产生什么样的问题呢?

重复引入脚本

  从上图可以看出当我重复引入同一个脚本的时候,input 框内的值变为 2,由此大家可以看到当我引入一次 js 文件时,input 框值是 1,这是正确的,是我们想要的结果,但是当我们不小心重复引入 js 文件时,input 框值变为 2,所以通过这个例子大家也知道了浏览器不会智能的帮你识别重复脚本,他只会不断地根据你引入的 js 文件不断地做累加,其它脚本也会跟着不准确起来,所以在工作中大家要注意这一点。

配置实体标签(ETag)

  ETag 全程 EntityTag(实体标签),它包含在响应头部中,它属于 http 协议,自然所有 web 服务都支持它,那它能干点啥?它是使用特殊的字符串来标识某个请求资源版本,我们举个不太文雅例子,说一只小狗对着大树尿尿,这就是一种标识,一颗资源,一个版本,独一无二,这里只是属于它。这个比喻,只是方便让大家了解意思透彻一点。

配置实体标签(ETag)

  当用户通过浏览器来向服务器请求资源的时候,服务器会进行比较,如果两边的 ETag 一致,那就说明服务器的 ETag 和浏览器的一致,这就意味着该资源没有修改过,和之前一模一样。这时候服务器会返回一个 304 吗,告诉浏览器这里一致可以使用本地缓存的版本。

  让我们再用人类的对话再模拟一下下面的这个过程,那就是当浏览器向服务器请求资源的时候,服务器拿过来一看一对比,一样,它会告诉浏览器你都有了而且一样,不用再要了用你自己的吧,那这个信息返回给浏览器了,浏览器一听我有了,那我回去查查看吧,诶,确实有还真是一样,那就直接用我的吧。这样讲大家理解起来可能会简单多了。

  了解了这个过程,大家就知道了配置 ETag 的好处,它会帮助服务器减轻很多负担。

使用 AJAX 缓存

  Ajax 即“AsynchronousJavascriptAndXML”(异步 JavaScript 和 XML),它能够在不重新加载页面的情况下,使客户端与服务器进行交换数据,可使网站的内容分批加载,而且还可以局部更新。

  Ajax 有两种方法,一种是 POST 请求,一种是 GET 请求。

  POST 请求:每次都是需要报发给服务器处理的,服务器每次都会返回一个状态码 200,从字面上我们发现有个关键词“每次”,就是这个“每次”决定了请求 POST 不被缓存。

  GET 请求:除非你给它指定了一个不同的地址,否者同一个地址的 ajax 请求不会重复在服务器执行,它返回的状态码是 304,说以它是可以被缓存的。

  说到这儿大家可能会产生一个新的疑问,那么什么时候使用 POST 请求呢?什么时候使用 GET 请求呢?解释着两个疑问就需要我们深入的研究一下 POST 和 GET 它们的功能,有什么区别,下面让我们用一张图表来对比一下 POST 和 GET。

使用 AJAX 缓存,post 和 get 区别对比

  通过上面这个图表上的对比,首先我们知道 GET 和 POST 的区别,那我们就知道了什么时候使用 GET,什么时候使用 POST,在理解了这个 GET 和 POST 的内在机制呢,我们就知道了什么时候对 ajax 进行缓存。推荐大家阅读我之前的一篇关于 ajax 的文章《jquery ajax 如何高效的执行请求

  讲到这儿,大家可以再日常工作中具体情况具体使用上面的方法了,深刻的体会一下以上方法对自己网站新能的优化带来的好处。

「点点赞赏,手留余香」

5

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » 优化网站性能方法,让快速访问网站不在是梦想

发表回复