前端性能优化

浏览器部分

  • 网络层面javascript

    1. 过多的HTTP请求php

      打开一个网页的时候,后台程序的响应并不所需太多时间,等待的时间主要花费在下载网页元素上了,即HTML、CSS、JavaScript、Flash、图片等。据统计,每增长一个元素,网页载入的时间就会增长25-40毫秒(具体取决于用户的带宽状况)。css

    2. 资源访问带宽小html

      两方面,一方面是客户端的带宽,一方面是服务器端的带宽。java

    3. 网页元素(图片、视频、样式)太大node

  • 浏览器渲染层面jquery

    1. 渲染阻塞:webpack

      浏览器想要渲染一个页面就必须先构建出DOM树与CSSOM树,若是HTMLCSS文件结构很是庞大与复杂,这显然会给页面加载速度带来严重影响。ios

      所谓渲染阻塞资源,便是对该资源发送请求后还须要先构建对应的DOM树或CSSOM树,这种行为显然会延迟渲染操做的开始时间。nginx

      JS阻塞与CSS阻塞:

      HTML、CSS、JavaScript都是会对渲染产生阻塞的资源,HTML是必需的(没有DOM还谈何渲染),但还能够从CSS与JavaScript着手优化,尽量地减小阻塞的产生。

    2. 重复渲染

    3. DNS解析

  • 服务端层面

    1. 硬件配置低:这个是双向的
    2. 服务器软件,好比防火墙、内网策略等
    3. 未对Nginx这类web服务器进行配置优化
    4. CPU占满、数据库未优化
    5. 代码问题,代码效率,代码性能
    6. 包含了过多的分析类工具

代码部分

  • 构建层面

    未对代码进行打包、压缩、兼容性优化。

    未合并重复的请求、代码。

  • 编码层面

    没有良好的编码习惯,错误的编排JS与CSS

    for循环、迭代、同步、重定向、阻塞请求

    未删除重复、无用的代码

    未对逻辑业务复杂的代码进行重构,了解设计模式,对业务进行疏理

  • 机制(SSR,英文Server Side Render:服务器端渲染)

    未加入Async异步机制

    未思考页面加载、用户体验

  • 规范

    CSS规范

    HTML规范/HTML5规范

    Airbnb代码规范等。

优化原则

尽可能减小HTTP请求

在浏览器(客户端)和服务器发生通讯时,就已经消耗了大量的时间,尤为是在网络状况比较糟糕的时候,这个问题尤为的突出。

一个正常HTTP请求的流程简述:如在浏览器中输入"www.xxxxxx.com"并按下回车,浏览器再与这个URL指向的服务器创建链接,而后浏览器才能向服务器发送请求信息,服务器在接受到请求的信息后再返回相应的信息,浏览器接收到来自服务器的应答信息后,对这些数据解释执行。

而当咱们请求的网页文件中有不少图片、CSS、JS甚至音乐等信息时,将会频繁的与服务器创建链接,与释放链接,这一定会形成资源的浪费,且每一个HTTP请求都会对服务器和浏览器产生性能负担。

网速相同的条件下,下载一个100KB的图片比下载两个50KB的图片要耗费的网络资源更多。因此,请减小HTTP请求。

具体的方法:

  1. 组合文件,优化图片,使用sprites设计风格: 将背景图片合并成一个文件,经过background-imagebackground-position 控制显示;

    确保您的图像不大于它们所需的图像,它们采用正确的文件格式(PNG一般更适用于少于16种颜色的图形,而JPEG一般更适合照片)而且它们是针对Web压缩的。

    使用CSS sprites在网站上常用的图像建立模板,如按钮和图标。CSS sprites将您的图像组合成一个大图像,一次加载全部(这意味着更少的HTTP请求),而后只显示您想要显示的部分。这意味着您经过不让用户等待加载多个图像来节省加载时间。

    有一些在线工具:

  2. 肉联图片,使用data:URL方案将图像数据嵌入实际页面中。这能够增长HTML文档的大小。将内嵌图像组合到(缓存的)样式表中是一种减小HTTP请求并避免增长页面大小的方法。

  3. 简化页面的设计

使用内容传送网络CDN

内容分发网络(CDN),也称为内容传送网络,是用于分发传送内容的负载的服务器网络。从本质上讲,您网站的副本存储在多个地理位置不一样的数据中心,以便用户能够更快,更可靠地访问您的网站。

对于初创公司和私人网站来讲,CDN服务的成本可能太高,但随着您的目标受众变得愈来愈大并变得更加全球化,CDN对于实现快速响应时间是必要的。

请记住,最终用户响应时间的80-90%用于下载页面中的全部组件:图像,样式表,脚本,Flash等。这是Performance Golden Rule。而不是从从新设计应用程序架构的艰巨任务开始,最好首先分散您的静态内容。这不只能够大大缩短响应时间,并且因为内容交付网络,它更容易实现。

内容传送网络(CDN)是分布在多个位置的Web服务器的集合,以更有效地向用户传送内容。选择用于向特定用户传送内容的服务器一般基于网络接近度的度量。例如,选择具备最少网络跳数的服务器或具备最快响应时间的服务器。

CDN服务商有不少,这里就再也不多说:专门作CDN服务器的蓝讯、网宿、帝联、快网,还有阿里云、腾讯云、华为云等。国外如Akamai TechnologiesEdgeCastlevel3

除了去购买一些CDN服务商的服务之外,对于大多数开发者,可使用公共CDN网络上的资源,如如下的方式去使用CDN加速:

<!-- google -->
<script
  type="text/javascript"
  src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"
></script>

<!-- cdnjs -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<!-- qiniu cloud -->
<script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script>

<!-- other cdn -->
<script
  crossorigin="anonymous"
  integrity="sha384-vk5WoKIaW/vJyUAd9n/wmopsmNhiy+L2Z+SBxGYnUkunIxVxAv/UtMOhba/xskxh"
  src="https://lib.baomitu.com/jquery/3.4.1/jquery.min.js"
></script>

避免空src或者是href值

空的src和href都会致使多余的HTTP请求,虽然不影响加载时间,可是会对服务器产生没必要要的流量和压力。浏览器仍然会向服务器发起一个 HTTP 请求:

  • IE 向页面所在的目录发送请求
  • Safari、Chrome、Firefox 向页面自己发送请求
  • Opera 不执行任何操做

空的src的image严重的以致于影响整个网站的用户体验,空 src 产生请求的后果不容小憩:

  • 给服务器形成意外的流量负担,尤为时日 PV 较大时;
  • 浪费服务器计算资源;
  • 可能产生报错。

有两种形式:

  1. HTML形式

    <img src="">
    <a href=""></a>
  2. JavaScript形式

    var img = new Image();
    img.src = "";

解决办法:

  1. 删除空的srchref标签
  2. a标签的href属性,链接到实际的页面:
<a href="#"></a>
<a href="#nogo"></a>
<a href="##"></a>
<a href="###"></a>
<a href="void(0);"></a>
<a href="void(0)"></a>
<a href=";"></a>
<a href=""></a>
  1. 禁止跳转,添加cursor:pointer样式
<style>
    a{cursor: pointer}
</style>
<a>点击一</a>
<a onclick="doSomething()">点击二</a>
  1. a 标签建立一个带有描述信息的href 属性,并监控click事件调用preventDefault()函数。
<a href="#Something_De scriptive" id="my_id">Trigger</a>
<script>
    $("#my_id").click(function(e){
        e.preventDefault(); //取消单击事件的默认动做以阻止连接的跳转。
        //  其余的代码
})
</script>

优势:

  • <a>够响应键盘事件并得到焦点(从而屏幕阅读器可以读出背后的内容,加强可访问性)
  • 优雅降级,在网络链接不好,尚未加载到CSS的时候,<a>依然有手型与正常的link样式。

gzip的组件

全部现代浏览器都支持 gzip 压缩并会为全部 HTTP 请求自动协商此类压缩。启用 gzip 压缩可大幅缩减所传输的响应的大小(最多可缩减 90%),从而显著缩短下载相应资源所需的时间、减小客户端的流量消耗并加快网页的首次呈现速度。

从HTTP / 1.1开始,Web客户端表示支持使用HTTP请求中的Accept-Encoding标头进行压缩。

Accept-Encoding:gzip,deflate

压缩包括XML和JSON在内的任何文本响应都是值得的。不该对图像和PDF文件进行gzip压缩,由于它们已通过压缩。试图对它们进行gzip不只会浪费CPU,还可能会增长文件大小。

好比,在nginx中开启gzip压缩:

# 开启gzip
gzip on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
gzip_comp_level 2;
# 进行压缩的文件类型。javascript有多种形式。其中的值能够在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png font/ttf font/otf image/svg+xml;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";

其余web容器启动gzip的方法:

CSS放在顶部,JS放在底部

把Javascript脚本在底部,删除阻止渲染的JavaScript
在HTML文件<body>中指定外部样式表和内联样式块可能对浏览器的渲染性能产生不利影响。

  1. 浏览器阻塞渲染网页直到全部外部的样式表都已被下载。
  2. (用<style>标记指定的)内联样式块可能会致使reflows和页面跳动。
    所以,把外部样式表和内联样式块放在页面的<head>中是很重要的。经过确保样式表首先被下载和解析,可让浏览器逐步渲染页面。

具体作法:

  • 将内联样式块和<link>元素从页面<body>移动到页面<head>中。

    HTML 4.01规范(第12.3节)规定,始终把使用<link>标签的外部样式表放在<head>部分里,还要确保您指定的样式有正确的顺序。

  • <style>区块放在<head>部分里。

  • 使用css媒体类型

若是可让CSS资源只在特定条件下使用,这样这些资源就能够在首次加载时先不进行构建CSSOM树,只有在符合特定条件时,才会让浏览器进行阻塞渲染而后构建CSSOM树。

CSS的媒体查询正是用来实现这个功能的,它由媒体类型以及零个或多个检查特定媒体特征情况的表达式组成。

<!-- 没有使用媒体查询,这个css资源会阻塞渲染  -->
<link href="style.css"    rel="stylesheet">
<!-- all是默认类型,它和不设置媒体查询的效果是同样的 -->
<link href="style.css"    rel="stylesheet" media="all">
<!-- 动态媒体查询, 将在网页加载时计算。
根据网页加载时设备的方向,portrait.css 可能阻塞渲染,也可能不阻塞渲染。-->
<link href="portrait.css" rel="stylesheet" media="orientation:portrait">
<!-- 只在打印网页时应用,所以网页首次在浏览器中加载时,它不会阻塞渲染。 -->
<link href="print.css"    rel="stylesheet" media="print">

使用媒体查询可让CSS资源不在首次加载中阻塞渲染,但无论是哪一种CSS资源它们的下载请求都不会被忽略,浏览器仍然会先下载CSS文件。

把Javascript脚本在底部,删除阻止渲染的JavaScript

浏览器必须经过在呈现页面以前解析HTML来构建DOM树。若是您的浏览器在此过程当中遇到脚本,则必须先中止并执行它,而后才能继续。

具体作法:

将脚本定义或引用放置到<body>底部。
<script defer="defer"> defer 属性规定是否对脚本执行进行延迟, 脚本将在页面完成解析时执行。

请输入图片描述

蓝色线表明网络读取,红色线表明执行时间,这俩都是针对脚本的;绿色线表明 HTML 解析。

此图告诉咱们如下几个要点:

  1. deferasync 在网络读取(下载)这块儿是同样的,都是异步的(相较于 HTML 解析)
  2. 它俩的差异在于脚本下载完以后什么时候执行,显然 defer*是最接近咱们对于应用脚本加载和执行的要求的
  3. 关于 defer,此图未尽之处在于它是按照加载顺序执行脚本的,这一点要善加利用
  4. async 则是一个乱序执行的主,反正对它来讲脚本的加载和执行是牢牢挨着的,因此无论你声明的顺序如何,只要它加载完了就会马上执行
  5. 仔细想一想,async对于应用脚本的用处不大,由于它彻底不考虑依赖(哪怕是最低级的顺序执行),不过它对于那些能够不依赖任何脚本或不被任何脚本依赖的脚原本说倒是很是合适的,最典型的例子:Google Analytics

减小DNS查找

用户访问网站的过程以下:

  1. 在地址栏输入网站地址,如www.example.com;

  2. 本地DNS获得这个请求,查询本地DNS缓存,若是有这条记录,则直接返回对应的IP;不然,请求网络上的DNS服务器,获得相应的IP,返回给客户机,并缓存这条记录;

  3. 浏览器向获得的IP发起创建链接请求,获得响应后创建链接,请求数据;

  4. Server端计算所需数据,并返回给client端;

  5. client端,即浏览器,解析数据并显示在浏览器窗口中,至此,请求完成。

在 一次请求中,DNS解析能够占到请求时间的三分之一左右(这点有待验证),因此若是能够缩短DNS解析时间,就能够加快页面的打开速度。

缩短DNS解析的 方法能够经过延长DNS缓存的时间选用更快的DNS Server减小域名总数(例如原来有5个img server,分别为img1.xxx.com至img5.xxx.com,则如今能够减小到3个)等等,可是减小域名个数又会下降资源并行下载的数量, 由于同一域名最多能够并行下载两个资源,因此这里须要一个折衷方案,做者的建议就是将资源分布在大于等于2但小于等于4个域名上(这个也有待验证,例如针 对多大的系统选用多少个域名是最合理的等)。

使用DNS预解析

这里会有一些兼容性问题,能够参见:http://caniuse.com/#feat=link-rel-dns-prefetch

sdfdsf

在网页体验中咱们常会遇到这种状况,即在调用百度联盟、谷歌联盟以及当前网页所在域名外的域名文件时会遇到请求延时很是严重的状况。那么有没有方法去解决这种请求严重延时的现象呢?

通常来讲这种延时的缘由不会是对方网站带宽或者负载的缘由,那么究竟是什么致使了这种状况呢。湛蓝试着进行推测,假设是DNS的问题,由于DNS解析速度极可能是形成资源延时的最大缘由。在页面header中添加了如下代码(用以DNS预解析):

<meta http-equiv="x-dns-prefetch-control" content="on" />

<link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />
<link rel="dns-prefetch" href="http://nsclick.baidu.com" />
<link rel="dns-prefetch" href="http://hm.baidu.com" />
<link rel="dns-prefetch" href="http://eiv.baidu.com" />

dns-prefetch需慎用,多页面重复DNS预解析会增长重复DNS查询次数。

使用场景:

  1. 新用户访问,后端能够经过 Cookie 判断是否为首次进入站点,对于这类用户,DNS Prefetch 能够比较明显地提高访问速度
  2. 登陆页,提早在页面上进行下一跳页用到资源的 DNS Prefetch
  3. 页面中的静态资源在不一样的domain下,如CSS、JS、图片等文件
  4. 电商网站的商品页大量载入不一样domain下的商品图,如淘宝
  5. 手机网页
  6. 大型网站
  7. js或服务端重定向

Chrome中的一些指令:

  • chrome://histograms/DNS.PrefetchQueue:查看队列状态
  • chrome://histograms/DNS:查看从浏览器启动到上一页的DNS记录
  • chrome://dns:查看个域名DNS统计
  • chrome://net-internals/#dns:清除host缓存

压缩资源

  • 压缩js,css,image

    经过对外部资源进行压缩能够大幅度地减小浏览器须要下载的资源量,它会减小关键路径长度与关键字节,使页面的加载速度变得更快。

    对数据进行压缩其实就是使用更少的位数来对数据进行重编码。现在有很是多的压缩算法,且每个的做用领域也各不相同,它们的复杂度也不相同,不过在这里我不会讲压缩算法的细节,感兴趣的朋友能够本身Google。

    在对HTMLCSSJavaScript这些文件进行压缩以前,还须要先进行一次冗余压缩。所谓冗余压缩,就是去除多余的字符,例如注释、空格符和换行符。这些字符对于程序员是有用的,毕竟没有格式化的代码可读性是很是恐怖的,但它们对于浏览器是没有任何意义的,去除这些冗余能够减小文件的数据量。

    小图片采用base64的格式,直接嵌入代码中,能够帮咱们减小http请求,可是一样,这个会形成咱们代码的说起变大。请求的速度会减慢,这个须要平衡。

    经常使用工具:webpack,gulp

    浏览器接收到服务器返回的HTML、CSS和JavaScript字节数据并对其进行解析和转变成像素的渲染过程被称为关键渲染路径。经过优化关键渲染路径便可以缩短浏览器渲染页面的时间。

  • 删除重复的脚本,相似tree-shaking

    在一个页面中重复引用一个脚本可能存在的问题:浏览器会重复下载并执行脚本文件。

  • 使用合适大小的图片

    若是你只须要一个小图,就不要传一个大图。例如你实际须要显示的是一个60x60的头像,就不要传一个100x100的而后再经过设置宽高将它缩小为60x60的。缘由很简单,这样会消耗没必要要的带宽和系统资源。

  • 减小DOM元素的数量

    复杂页面意味着要下载更多字节,这也意味着JavaScript中的DOM访问速度更慢。若是您想要添加事件处理程序,例如,在页面上循环500或5000个DOM元素,则会有所不一样。

  • 使用异步加载,async、defer

    服务端渲染也是一种减小浏览器资源消耗,减小页面重排重绘,也是一种现行MVVM框架单页应用最主要的SEO优化手段。

避免3xx/4xx

避免重定向

3xx是重定向相关的HTTP响应代码

重定向的意思是,用户的原始请求(例如请求A)被重定向到其余的请求(例如请求B)。

每次页面重定向到另外一个页面时,您的访问者都会面临等待HTTP请求 - 响应周期完成的额外时间。例如,若是移动重定向模式以下所示:

example.com - > www.example.com - > m.example.com - > m.example.com/home,这两个额外重定向中的每个都会使您的页面成为可能加载速度慢。

HTTP 重定向经过 301/302 状态码实现。

HTTP/1.1 301 Moved Permanently  
Location: http://example.com/newuri  
Content-Type: text/html

301 Moved Permanently,这个状态码标识用户所请求的资源被移动到了另外的位置,客户端接收到此响应后,须要发起另一个请求去下载所需的资源。

302 Found,这个状态码标识用户所请求的资源被找到了,但不在原始位置,服务器会回复其余的一个位置,客户端收到此响应后,也须要发起另一个请求去下载所需的资源。

客户端收到服务器的重定向响应后,会根据响应头中 Location 的地址再次发送请求。重定向会影响用户体验,尤为是屡次重定向时,用户在一段时间内看不到任何内容,只看到浏览器进度条一直在刷新。

有时重定向没法避免,在糟糕也比抛出 404 好。虽然经过 HTML meta refresh 和 JavaScript 也能实现,但首选 HTTP 3xx 跳转,以保证浏览器「后退」功能正常工做(也利于 SEO)。

常见的优化办法:

  • 最浪费的重定向常常发生、并且很容易被忽略:URL 末尾应该添加 / 但未添加。好比,访问 http://astrology.yahoo.com/astrology 将被 301 重定向到 http://astrology.yahoo.com/astrology/(注意末尾的 /)。若是使用 Apache,能够经过 Aliasmod_rewriteDirectorySlash 解决这个问题。

  • 网站域名变动:CNAME 结合 Aliasmod_rewrite 或者其余服务器相似功能实现跳转。

  • 在定义连接地址的href属性的时候,尽可能使用最完整的、直接的地址。例如:
    使用 www.cnblogs.com 而不是cnblogs.com
    使用cn.bing.com而不是bing.com
    使用www.google.com.hk而不是google.com
    使用www.mysite.com/products/而不是www.mysite.com/products

避免404浏览器找不到资源的状况发生

发出HTTP请求并得到无用的响应(即404 Not Found)是彻底不必的。特别糟糕的是当外部JavaScript的连接错误而且结果是404时。首先,此下载将阻止并行下载。接下来,浏览器可能会尝试解析404响应主体,就像它是JavaScript代码同样,这样就带来的性能的浪费。

404的影响:

有时候,404错误发生了,用户可能根本没有感受到。例如

  • 例如请求favicon.ico文件,或者请求了某个不存在的脚本文件、样式表、图片文件,页面仍是会按照正常的方式进行呈现。
  • 丢失的脚本文件、样式表、图片文件,会致使页面的某些行为、界面效果出现异常(也可能不是很明显)
  • 最大的问题多是性能方面的影响。尤为是若是请求一个不存在的脚本文件,由于浏览器在请求脚本文件的时候,即使是返回404,它也会尝试去按照Javascript的方式解析响应中的内容。这无疑会增长不少处理的时间,而由于该文件不存在,因此这些都是无用功。

看获得的影响:

  • 若是用户请求的某个页面不存在,那么他将收到明确的回应
  • 默认状况下,他将收到一个标准的错误页面(请注意:很多用户会被这个页面吓到)

常见的优化办法:

404 意味着Not Found,意思是说未找到资源。既然如此,那么至少会有两种缘由致使404错误:

  • 该资源按理说是要有,但咱们没有提供。用户按照正常的方式来请求,因此资源找不到。
    • 为网站提供favicon.ico这种常常可能会被忽略的资源
    • 使用一些检查工具:好比Link checker
  • 该资源原本就不存在,用户按照不正常的方式来请求,固然仍是找不到。
    • 避免用户收藏绝对地址,给后期更新带来隐患。可使用地址Rewrite来重写,或者在设计阶段定义一些灵活友好的地址
    • 使用Routing技术,配置路由规则。

AJAX优化

使Ajax可缓存

AJAX=Asynchronous JavaScript And XML,AJAX不是新的编程语言,而是一种使用现有标准的新方法。
AJAX是与服务器交换数据并更新部分网页的艺术,在不从新加载整个页面的状况下。

因为AJAX其实也是须要发起请求,而后服务器执行,并将结果(一般是JSON格式的)发送给浏览器进行最后的呈现或者处理,因此对于网站设计优化的角度而言,咱们一样须要考虑对这些请求,是否能够尽量的利用到缓存的功能来提升性能。

对于AJAX而言,有一些特殊性,并非全部的AJAX请求都是能够缓存的。

  1. POST的请求,是不能够在客户端缓存的,每次请求都须要发送给服务器进行处理,每次都会返回状态码200。(这里能够优化的是,服务器端对数据进行缓存,以便提升处理速度)
  2. GET的请求,是能够(而且默认)在客户端进行缓存的,除非指定了不一样的地址,不然同一地址的AJAX请求,不会重复再服务器执行,而是返回304。

有的时候,咱们可能但愿GET请求不被缓存,有几种作法来达到这样的目的。

  1. 每次调用的时候,请求不一样的地址(能够在原始地址后面添加一个随机的号码)。
  2. 若是你所使用的是jquery的话,则能够考虑禁用AJAX的缓存。
$.ajaxSetup({ cache: false });

axios中

var config = {	headers: {'Content-Type': 'application/json','Cache-Control' : 'no-cache'}};
 
axios.get('/post',config)

使用GET的Ajax请求

在使用XMLHttpRequest(目前的AJAX都是基于它实现的)的时候,浏览器中的POST实现为两步走的过程,首先发送头部信息,而后再发送数据。但若是是使用GET的话,就只有一个TCP的包发送出去(除非有大量的Cookie),这样无疑能够提升性能。

可是get有容量限制,大于2K(对get的限制IE是2K,firefox、chrome是4K)的内容只能用post。

Cookie优化

  • 减少cookie大小

    减少cookie的大小,由于在发请求时浏览器会将cookie信息发送到server端,因此应该只在cookie中存必要的信息且越长度越小越好。在 写cookie的时候要记得给cookie设置一个合理的过时时间及域

  • 对一些静态资源不须要使用cookie的单独设置域

    当浏览器发出静态图像请求并将cookie与请求一块儿发送时,服务器对这些cookie没有任何用处。所以,他们只会毫无理由地建立网络流量。您应该确保使用无cookie请求请求静态组件。建立一个子域并在那里托管全部静态组件。

    若是您的域名是www.example.org,您能够托管您的静态组件static.example.org。可是,若是您已经在顶级域上设置了cookie example.org而不是www.example.org,则全部请求都 static.example.org将包含这些cookie。在这种状况下,您能够购买一个全新的域,在那里托管您的静态组件,并保持此域无cookie。雅虎 用途yimg.com,YouTube使用ytimg.com,亚马逊使用images-amazon.com等。

    在无cookie域上托管静态组件的另外一个好处是,某些代理可能拒绝缓存使用cookie请求的组件。在相关说明中,若是您想知道是否应该使用example.orgwww.example.org做为主页,请考虑cookie的影响。

    省略www会让您别无选择,只能写入cookie *.example.org,所以出于性能缘由,最好使用www子域并将cookie写入该子域。

归类一下:

  • 去除没必要要的 Cookie;
  • 尽可能压缩 Cookie 大小;
  • 注意设置 Cookie 的 domain 级别,如无必要,不要影响到 sub-domain;
  • 设置合适的过时时间。

利用缓存

浏览器会缓存大量信息(样式表,图像,JavaScript文件等),以便当访问者返回您的站点时,浏览器没必要从新加载整个页面。而后设置“expires”标题,以表示但愿缓存该信息的时间。在许多状况下,除非您的网站设计常常更改,不然一年是合理的时间段。

利用浏览器缓存 ,为连接或者资源,添加Expires或Cache-Control头

  • 对于静态组件:经过设置远期将来Expires标头实现“永不过时”策略
  • 对于动态组件:使用适当的Cache-Control标头来帮助浏览器处理条件请求

格式:

Expires = "Expires" ":" HTTP-date
# e.g.
Expires: Thu, 01 Dec 1994 16:00:00 GMT 
#(必须是GMT格式)

经过HTTP的META设置expires和cache-control

<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta http-equiv="Expires" content="Mon, 01 Aug 2019 00:00:00 GMT" />

上述设置仅为举例,实际使用其一便可。这样写的话仅对该网页有效,对网页中的图片或其余请求无效,并不会作任何cache
这样客户端的请求就多了,尽管只是检查Last-modified状态的东西,可是请求一多对浏览速度一定有影响。

Cache-Control 的参数包括:

  • max-age=[单位:秒 seconds] — 设置缓存最大的有效时间. 相似于 Expires, 可是这个参数定义的是时间大小(好比:60)而不是肯定的时间点.单位是[秒 seconds].
  • s-maxage=[单位:秒 seconds] — 相似于 max-age, 可是它只用于公享缓存 (e.g., proxy) .
  • public — 响应会被缓存,而且在多用户间共享。正常状况, 若是要求 HTTP 认证,响应会自动设置为 private.
  • private — 响应只可以做为私有的缓存(e.g., 在一个浏览器中),不能再用户间共享。
  • no-cache — 响应不会被缓存,而是实时向服务器端请求资源。这一点颇有用,这对保证HTTP 认证可以严格地禁止缓存以保证安全性颇有用(这是指页面与public结合使用的状况下).既没有牺牲缓存的效率,又能保证安全。
  • no-store — 在任何条件下,响应都不会被缓存,而且不会被写入到客户端的磁盘里,这也是基于安全考虑的某些敏感的响应才会使用这个。
  • must-revalidate — 响应在特定条件下会被重用,以知足接下来的请求,可是它必须到服务器端去验证它是否是仍然是最新的。
  • proxy-revalidate — 相似于 must-revalidate,但不适用于代理缓存.

把css与js使用外联的方式进行使用

建议将css和js之外联方式引用以充分利用cache,只有一个例外就是针对首页,首页能够采用内联来减小http请求数,加快页面显示速度,文中说首 页内联的缘由是首页被人们访问的次数不会太多,并且样式通常比较特殊,不像其它页面同样有相同的页面模板(由于就有相同的样式部分),因此首页的样式能够 内联。而且应该在首页加载完成以后,再在后台动态加载后续页面的css和js,以提升后续页面的访问速度。

若是站点上的用户每一个会话有多个页面查看,而且您的许多页面重复使用相同的脚本和样式表,则缓存的外部文件可能会带来更大的潜在好处。

对于如今的单页面的应用,更适合于动态加载的方案

缓存favicon.ico,并设置最好小于1k

favicon.ico是一个保留在服务器根目录中的图片,为了减轻拥有favicon.ico的带来的性能问题,请确保:

  • 优化它的大小,最好不到1K。
  • 设置Expires标头,使其缓存。

配置的ETag

ETag,全程为:Entity Tag,意思是实体标签,它属于HTTP协议的一部分,也就是全部的Web服务器都应该支持这个特性。它的做用是用一个特殊的字符串来标识某个资源的“版本”,客户端(浏览器)请求的时候,比较ETag若是一致,则表示该资源并无被修改过,客户端(浏览器)可使用本身缓存的版本,避免重复下载。
它比last-modified date更具备弹性,例如某个文件在1秒内修改了10次,Etag能够综合Inode(文件的索引节点(inode)数),MTime(修改时间)和Size来精准的进行判断,避开UNIX记录MTime只能精确到秒的问题。 服务器集群使用,可取后两个参数。使用ETags减小Web应用带宽和负载。

响应标 优点 和特色 劣势 和可能的问题
Expires - HTTP 1.0就有,简单易用。 - 服务器经过这个Header告诉浏览器,某资源直到某个时间才会过时,因此在没有过时以前,浏览器就直接使用本地的缓存了。 - 由于这是时间是由服务器发送的(UTC),但若是服务器时间和客户端事件存在不一致,可能会有些问题。 - 可能存在版本的问题,由于若是在到期以前修改过了,客户端是不会知道的。 - Cache-Control中的max-age能够实现相似的效果,但更加好,由于max-age是一个以秒为单位的时间数,而不是具体的时间,因此不存在上面提到的第一个问题。
Cache-Contro - 服务器经过一个Header(Last-Modified)告诉浏览器,某资源最后修改的时间。 - 浏览器在请求的时候,包含一个Header(If-Modified-Since),而后服务器能够进行比较,若是在该时间后没有修改过,则返回304。 - 它比Expires多不少选项设置 - Last-Modified 也是一个时间,但该时间只能精确到秒,若是在同一个秒中有屡次修改(这个在如今的环境下应该确实是可能的),则可能会发生问题。
ETag - 能够更加精确地判断资源是否被修改,由于它不是一个时间值,而是对时间通过处理的一个长整型数值(固然具体算法咱们目前还不得而知)。 - 浏览器发起新请求时须要包含 If-None-Match。 - 若是部署在服务器场环境中,配置不当的话,可能每一个服务器会对相同的资源生成不同的ETag,这样就增长了重复下载的可能性。

其余的一些缓存使用:

  • 使用本地缓存,缓存部分经常使用用户数据、公开数据
  • 缓存机制设计:缓存+过时时间

总结一下:

  • 添加Expires或Cache-Control
  • Etag
  • 缓存favicon.ico
  • 外联js/css

缩短服务器响应时间

服务器响应时间受到访问流量,每一个页面使用的资源,服务器使用的软件以及硬件自己的影响。要改善服务器响应时间,请查找性能瓶颈,如慢速数据库查询,慢速路由或缺乏足够的内存并修复它们。最佳服务器响应时间低于200毫秒。

不少潜在因素均可能会延缓服务器响应,例如缓慢的应用逻辑、缓慢的数据库查询、缓慢的路由、框架、库、资源 CPU 不足或内存不足。您须要充分考虑全部这些因素,才能改善服务器的响应用时。 若想找出服务器响应用时过长的缘由,首先要进行衡量。而后,准备好相关数据,并参阅有关如何解决该问题的相应指导。当解决问题后,您必须继续衡量服务器响应用时,并设法应对任何会在未来出现的性能瓶颈问题。

  1. 收集并检查现有性能和数据。若无可用内容,请使用自动化的网络应用监测解决方案(市面上有托管的开源版本,适用于大多数平台)进行评估,或添加自定义的方法。
  2. 找出并修复首要的性能瓶颈问题。若是z您使用的是热门网页框架或内容管理平台,请参阅与性能优化最佳作法相关的文档。
  3. 监测并提醒任何会在未来出现的性能衰退问题!

一般来讲,服务器的响应时间由数据库的问题居多,还有错误的程序设计(好比:烂用for循环去查数据库)。