页面性能优化常用办法汇总

前言

互联网有一项闻名的8秒准绳。用户在访问Web网页时,若是时间超过8秒就会感应不不耐烦,若是加载时间太长,他们就会放弃访问。大部分用户希望网页能在2秒之内就完成加载。事实上,加载时间每多1秒,你就会流失7%的用户。8秒并不是切确的8秒钟,只是向网站开发者剖清楚明了加载时间的重要性。那我们应该如何优化页面性能,加快页面加载速度呢?本文只关注一些要点,以下是小编总结的几种常见的方法:

资源压缩与合并

主要包含以下几个方面:

  • html压缩
  • css压缩
  • js压缩和紊乱
  • 文件合并

资源压缩可以从文件中去掉多余的字符, 比如回车和空格.

1. html压缩

html代码压缩就是压缩这些在文本文件中有意义,可是在HTML中不需要的字符,比如: 空格,制表符,换行符等,还有一些其他意义的字符,如HTML注释也可以被压缩。

2. css代码压缩

css代码压缩简单来说就是无效代码删除和css语义合并


image.png

3.js的压缩和紊乱

如何进行js代码的压缩和紊乱呢?

  • 使用在线网站进行压缩
  • 使用html-minifier工具
  • 使用uglifyjs2对js进行压缩

其实css压缩与js的压缩和紊乱比html压缩收益要大得多,同时css代码和js代码比html代码多得多。所以对大公司来说,html压缩无关紧要,但css压缩与js的压缩非常有必要!

4. 文件合并

将多个js/css小文件合并为一个文件, 减少网络请求数.

非核心必要代码异步加载

1. 异步加载

实现异步加载有三种可行办法:

  • async
  • defer
  • 动态创建script标签

async

  • async属性是HTML5新增属性, 目前在Chrome, Firefox, IE9+上支持.
  • async的设置,会使得script脚本异步的加载并在允许的情况下执行
  • async的执行,并不会按着script在页面中的顺序来执行,而是谁先加载完谁执行。

defer

  • 兼容所有浏览器
  • 如果script标签设置了该属性,则浏览器会异步的下载该文件并且不会影响到后续DOM的渲染;
  • 如果有多个设置了defer的script标签存在,则会按照顺序执行所有的script;
  • defer脚本会在文档渲染完毕后,DOMContentLoaded事件调用前执行。

动态创建script标签

在没有defer和async属性前, 异步加载是通过动态创建script标签, 在window.onload事件中触发动态创建script到dom中实现的.
示例代码:

function addScriptTag(src){
  var script = document.createElement('script');
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
}

window.onload = function{
  addScriptTag("js/index.js");
}

2. defer&async异步加载的区别

  • defer是在HTML解析完之后才会实行,若是是多个,按照加载的依次实行
  • async是在加载完之后立即实行,若是是多个,实行按次和加载按次无关

浏览器缓存

对于web应用来说, 缓存是提升页面性能同时减少服务器压力的利器.

浏览器缓存

1. 强缓存

不会向服务器发送请求, 直接从缓存中读取资源, 在Chrome控制台的network选项中可以看到该请求的状态码为200, 但size标识为from dist cache或者from memory cache.

2. response header

Expires

response header里的过期时间, 浏览器再次加载该资源时, 如果在有效时间内, 则使用强缓存, 它的值是一个绝对时间(GMT时间字符串), 如: Expires:Thu,21 Jan 2018 23:39:02 GMT

Cache-Control

(1) 请求Request:

  • no-cache ---- 不要读取缓存中的文件,要求向WEB服务器重新请求
  • no-store ---- 请求和响应都禁止被缓存
  • max-age: ---- 表示当访问此网页后的max-age秒内再次访问不会去服务器请求,其功能与Expires类似,只是Expires是根据某个特定日期值做比较。一但缓存者自身的时间不准确.则结果可能就是错误的,而max-age,显然无此问题.。Max-age的优先级也是高于Expires的。
  • max-stale ---- 允许读取过期时间必须小于max-stale 值的缓存对象。
  • min-fresh ---- 接受其max-age生命期大于其当前时间 跟 min-fresh 值之和的缓存对象
  • only-if-cached ---- 告知缓存者,我希望内容来自缓存,我并不关心被缓存响应,是否是新鲜的.
  • no-transform ---- 告知代理,不要更改媒体类型,比如jpg,被你改成png.

(2) 响应Response:

  • public ---- 数据内容皆被储存起来,就连有密码保护的网页也储存,安全性很低
  • private ---- 数据内容只能被储存到私有的cache,仅对某个用户有效,不能共享
  • no-cache ---- 可以缓存,但是只有在跟WEB服务器验证了其有效后,才能返回给客户端
  • no-store ---- 请求和响应都禁止被缓存
  • max-age: ----- 本响应包含的对象的过期时间
  • Must-revalidate ---- 如果缓存过期了,会再次和原来的服务器确定是否为最新数据,而不是和中间的proxy
  • max-stale ---- 允许读取过期时间必须小于max-stale 值的缓存对象。
  • proxy-revalidate ---- 与Must-revalidate类似,区别在于:proxy-revalidate要排除掉用户代理的缓存的。即其规则并不应用于用户代理的本地缓存上。
  • s-maxage ---- 与max-age的唯一区别是,s-maxage仅仅应用于共享缓存.而不应用于用户代理的本地缓存等针对单用户的缓存. 另外,s-maxage的优先级要高于max-age.
  • no-transform ---- 告知代理,不要更改媒体类型,比如jpg,被你改成png.
Last-Modified 和 If-Modified-Since

都是用于记录页面最后修改时间的 HTTP 头信息,注意:

  • Last-Modified 是由服务器往客户端发送的 HTTP
  • If-Modified-Since是由客户端往服务器发送的头

再次请求本地存在的 cache 页面时,客户端会通过 If-Modified-Since 头将先前服务器端发过来的 Last-Modified 最后修改时间戳发送回去,这是为了让服务器端进行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的内容,如果是最新的,则 返回 304 告诉客户端其本地 cache 的页面是最新的,于是客户端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了服务器的负担。而且在一些ajax应用中,要求获取的数据永远是最新的,而不是读取位于缓存中的数据,做这样的设置是非常有必要的。


image.png

但Last-Modified存在一些缺点:

  • 有些服务器无法获取文件最新的修改时间
  • 文件的修改时间变了, 但内容可能没有变化

既然按文件修改时间无法保证缓存是否合适, 那么是否可以考虑按文件内容来决定文件是否缓存呢?—-ETag和If-None-Match

ETag 和 If-None-Match
  • ETag是上一次加载资源时, 服务器返回给浏览器客户端的response header, 是对该资源的一种唯一标识, 只要资源有变化, Etag就会重新生成, 浏览器每次加载资源向服务器发送请求时, 都会将文件上一次的Etag值放到request header的If-None-Match中, 服务器与客户端传入的If-None-Match进行比对, 看是否一致, 就能很好的断定资源是否有更新过. 若匹配, 则返回HTTP 304状态码, 浏览器则会直接使用本地缓存, 否则, 返回HTTP 200状态码, 返回最新的资源 .


    image.png

Etag & Last-Modified 两者比较:

  • 从准确度来看, Etags要优于 Last-Modified, Last-Modified设置时间的最小单位是秒, 若某个文件在1秒内修改了两次或更多, Last-Modified无法精确的保证文件是否是最新的, 但Etag可以. 若是负载均衡服务器, 每个服务器生成的 Last-Modified值也可能不一致.
  • 从性能来看, Etag要逊于 Last-Modified, 因为 Last-Modified只需要设置时间即可, 而Etag则必须要服务器通过比对算法来比较hash值.
  • 从优先级来看, 服务器优先考虑校验Etag
Cache-Control

浏览器缓存机制流程图


image.png

CDN

CDN服务提供商会有全国各个省份部署节点, 将网站静态资源部署到CDN后, 用户在访问页面时, CDN静态资源会从就近的CDN节点上加载资源. 当请求至达CDN节点后, 节点会判断资源是缓存是否有效, 若有效, 直接返回给用户, 若无效, 会从CDN服务器加载最新的资源返回给用户同时将资源保存一份到该CDN节点上, 以便后续的访问用户使用. 因此, 只在该地区有一个用户先加载了资源, 在CDN中建立了缓存, 该地区的其他用户都能受益.

DNS预解析

DNS 作为互联网的基础协议,其解析的速度似乎容易被网站优化人员忽视。现在大多数新浏览器已经针对DNS解析进行了优化,典型的一次DNS解析耗费20-120 毫秒,减少DNS解析时间和次数是个很好的优化方式。DNS Prefetching是具有此属性的域名不需要用户点击链接就在后台解析,而域名解析和内容载入是串行的网络操作,所以这个方式能减少用户的等待时间,提升用户体验。

预解析的实现过程:

    1. 用meta信息来告知浏览器, 当前页面要做DNS预解析:<meta http-equiv="x-dns-prefetch-control" content="on" />
    1. 在页面header中使用link标签来强制对DNS预解析: <link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />

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

PS:DNS预解析主要是用于网站前端页面优化,在SEO中的作用湛蓝还未作验证,但作为增强用户体验的一部分rel="dns-prefetch"或许值得大家慢慢发现。

浏览器对网站第一次的域名DNS解析查找流程依次为:

浏览器缓存-系统缓存-路由器缓存-ISP DNS缓存-递归搜索

image.png

Chrome内置了DNS Prefetching技术, Firefox 3.5 也引入了这一特性,由于Chrome和Firefox 3.5本身对DNS预解析做了相应优化设置,所以设置DNS预解析的不良影响之一就是可能会降低Google Chrome浏览器及火狐Firefox 3.5浏览器的用户体验。

本文摘至网络

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343