前些时间主要学习了前端的性能优化的基础知识,总结笔记,准备进阶!javascript
² 白屏时间:在head头部和底部分别嵌入脚本能够得到head头部的加载时间,这个时间事后页面开始程序内容,能够大体认为是白屏时间php
² 用户可操做时间:默承认以统计domready时间,由于一般会在这时候绑定事件操做css
² 页面总下载时间:能够统计onload时间html
² 首屏时间:这个较为复杂,统计首屏全部内容呈现出来的时间,主要因素是图片的加载,异步渲染,iframe等前端
window.performance的navigation和timing接口提供了丰富的信息java
² navigation提供的信息:用户访问页面的形式和关于访问重定向的一些相关信息web
ü timing提供的信息:文档解析各个步骤的耗时chrome
ü .navigationStart 准备加载页面的起始时间api
ü .unloadEventStart 若是前一个文档和当前文档同源,返回前一个文档开始unload的时间跨域
ü .unloadEventEnd 若是前一个文档和当前文档同源,返回前一个文档开始unload结束的时间
ü .redirectStart 若是有重定向,这里是重定向开始的时间.
ü .redirectEnd 若是有重定向,这里是重定向结束的时间.
ü .fetchStart 开始检查缓存或开始获取资源的时间
ü .domainLookupStart 开始进行dns查询的时间
ü .domainLookupEnd dns查询结束的时间
ü .connectStart 开始创建链接请求资源的时间
ü .connectEnd 创建链接成功的时间.
ü .secureConnectionStart 若是是https请求.返回ssl握手的时间
ü .requestStart 开始请求文档时间(包括从服务器,本地缓存请求)
ü .responseStart 接收到第一个字节的时间
ü .responseEnd 接收到最后一个字节的时间.
ü .domLoading ‘current document readiness’ 设置为 loading的时间 (这个时候还木有开始解析文档)
ü .domInteractive 文档解析结束的时间
ü .domContentLoadedEventStart DOMContentLoaded事件开始的时间
ü .domContentLoadedEventEnd DOMContentLoaded事件结束的时间
ü .domComplete current document readiness被设置 complete的时间
ü .loadEventStart 触发onload事件的时间
ü .loadEventEnd onload事件结束的时间
http://yslow.org/ 提供相应的chrome插件,并听从yahu的优化法则提供优化的建议。
以上是一些业界作的比较好的工具,主要是对页面的白屏时间,首屏时间等指标,页面重绘次数,dom数,页面大小,总下载时间等。
Pagespeed和yslow都根据雅虎的优化法则提供一些优化的建议。
一、 尽可能减小HTTP请求次数
http比较耗时,应尽量减小请求。
贴吧实践:combo js/css ,css sprit
二、减小DNS查找次数
减小主机名的数量也会减小页面中并行下载的数量。减小DNS查找次数能够节省响应时间,可是减小并行下载却会增长响应时间。指导原则是把这些页面中的内容分割成至少两部分但不超过四部分。这种结果就是在减小DNS查找次数和保持较高程度并行下载二者之间的权衡了。
贴吧实践:静态文件再也不不一样的域下的静态服务器。
三、 避免跳转
当URL本该有斜杠(/)却被忽略掉时。例如,当咱们要访问http://astrology.yahoo.com/astrology 时,实际上返回的是一个包含301代码的跳转,它指向的是http://astrology.yahoo.com/astrology/ (注意末尾的斜杠)。在Apache服务器中可使用Alias 或者 mod_rewrite或者the DirectorySlash来避免
四、 可缓存的AJAX
五、 推迟加载内容
哪些内容是页面呈现时所必需首先加载的。
预加载是在浏览器空闲时请求未来可能会用到的页面内容(如图像、样式表和脚本)。使用这种方法,当用户要访问下一个页面时,页面中的内容大部分已经加载到缓存中了,所以能够大大改善访问速度。
贴吧实践:滚动加载,把内容数据存储在不可见元素里(textarea)
六、 减小DOM元素数量(减小页面体积)
贴吧实践:缩减页面体积,减小pageData的重量
七、 根据域名划分页面内容
因为DNS查找带来的影响你首先要确保你使用的域名数量在2个到4个之间。
贴吧实践:静态文件再也不不一样的域下的静态服务器。
八、 使iframe的数量最小
<iframe>优势:
解决加载缓慢的第三方内容如图标和广告等的加载问题
Security sandbox
并行加载脚本
<iframe>的缺点:即时内容为空,加载也须要时间
会阻止页面加载
没有语意
九、 不要出现404错误
十、 使用内容分发网络(Content Delivery Network,CDN)
贴吧实践:cdn
十一、 为文件头指定Expires或Cache-Control
这条守则包括两方面的内容:
对于静态内容:设置文件头过时时间Expires的值为“Never expire”(永不过时)
对于动态内容:使用恰当的Cache-Control文件头来帮助浏览器进行有条件的请求
贴吧实践:缓存静态文件
十二、 Gzip压缩文件内容
服务器根据文件类型来选择须要进行gzip压缩的文件,可是这过于限制了可压缩的文件。大多数web服务器会压缩HTML文档。对脚本和样式表进行压缩一样也是值得作的事情,可是不少web服务器都没有这个功能。实际上,压缩任何一个文本类型的响应,包括XML和JSON,都值得的。图像和PDF文件因为已经压缩过了因此不能再进行gzip压缩。若是试图gizp压缩这些文件的话不但会浪费CPU资源还会增长文件的大小。
Gzip压缩全部可能的文件类型是减小文件体积增长用户体验的简单方法。
贴吧实践:开启gzip压缩
1三、 配置ETag
1四、 Entity tags(ETags)(实体标签)是web服务器和浏览器用于判断浏览器缓存中的内容和服务器中的原始内容是否匹配的一种机制(“实体”就是所说的“内容”,包括图片、脚本、样式表等)。增长ETag为实体的验证提供了一个比使用“last-modified date(上次编辑时间)”更加灵活的机制。Etag是一个识别内容版本号的惟一字符串。惟一的格式限制就是它必须包含在双引号内
贴吧实践:配置etag缓存静态文件,方法同为文件头指定Expires或Cache-Control ,主要是触发浏览器的缓存
1五、 尽早刷新输出缓冲
贴吧实践:东伟正在作的事情,bigpipe依赖的原理
1六、 使用GET来完成AJAX请求
Yahoo!Mail团队发现,当使用XMLHttpRequest时,浏览器中的POST方法是一个“两步走”的过程:首先发送文件头,而后才发送数据。所以使用GET最为恰当,由于它只需发送一个TCP包(除非你有不少cookie)
1七、 把样式表置于顶部
在研究Yahoo!的性能表现时,咱们发现把样式表放到文档的<head />内部彷佛会加快页面的下载速度。这是由于把样式表放到<head />内会使页面有步骤的加载显示。
避免页面渲染过程当中的闪烁
1八、 避免使用CSS表达式(Expression)
表达式的问题就在于它的计算频率要比咱们想象的多。不只仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要从新计算一次。给CSS表达式增长一个计数器能够跟踪表达式的计算频率。在页面中随便移动鼠标均可以轻松达到10000次以上的计算量
css表达式在渲染过程当中特别耗性能,
1九、 使用外部JavaScript和CSS
在实际应用中使用外部文件能够提升页面速度,由于JavaScript和CSS文件都能在浏览器中产生缓存。内置在HTML文档中的JavaScript和CSS则会在每次请求中随HTML文档从新下载。这虽然减小了HTTP请求的次数,却增长了HTML文档的大小。从另外一方面来讲,若是外部文件中的JavaScript和CSS被浏览器缓存,在没有增长HTTP请求次数的同时能够减小HTML文档的大小。
外置css ,js主要是缓存,主要考虑外置和内置的优缺点及两者之间的平衡
20、 削减JavaScript和CSS
精简是指从去除代码没必要要的字符减小文件大小从而节省下载时间。消减代码时,全部的注释、不须要的空白字符(空格、换行、tab缩进)等都要去掉
代码压缩
2一、用<link>代替@import
前面的最佳实现中提到CSS应该放置在顶端以利于有序加载呈现。
在IE中,页面底部@import和使用<link>做用是同样的,所以最好不要使用它。
@import 是页面加载以后才会引入css,会引发闪烁,关于link和import的区别还有别的方面
2二、避免使用滤镜
IE独有属性AlphaImageLoader用于修正7.0如下版本中显示PNG图片的半透明效果。这个滤镜的问题在于浏览器加载图片时它会终止内容的呈现而且冻结浏览器。在每个元素(不只仅是图片)它都会运算一次,增长了内存开支,所以它的问题是多方面的。
彻底避免使用AlphaImageLoader的最好方法就是使用PNG8格式来代替,这种格式能在IE中很好地工做。若是你确实须要使用AlphaImageLoader,请使用下划线_filter又使之对IE7以上版本的用户无效
在ie中应避免使用滤镜,增长内存开支,耗性能
2三、把脚本置于页面底部
脚本带来的问题就是它阻止了页面的平行下载。HTTP/1.1 规范建议,浏览器每一个主机名的并行下载内容不超过两个。若是你的图片放在多个主机名上,你能够在每一个并行下载中同时下载2个以上的文件。可是当下载脚本时,浏览器就不会同时下载其它文件了,即使是主机名不相同。
避免阻塞页面渲染和其余文件的并行加载
2四、剔除重复脚本
一个避免偶尔发生的两次引用同一脚本的方法是在模板中使用脚本管理模块引用脚本。在HTML页面中使用<script />标签引用脚本的最多见方法就是:
<script type="text/javascript" src="menu_1.0.17.js"></script>
在PHP中能够经过建立名为insertScript的方法来替代:
<?php insertScript("menu.js") ?>
为了防止屡次重复引用脚本,这个方法中还应该使用其它机制来处理脚本,如检查所属目录和为脚本文件名中增长版本号以用于Expire文件头等。
贴吧采用html::script的方式引入脚本文件
2五、减小DOM访问
使用JavaScript访问DOM元素比较慢,所以为了得到更多的应该页面,应该作到:
缓存已经访问过的有关元素
线下更新完节点以后再将它们添加到文档树中
避免使用JavaScript来修改页面布局
减小dom访问,缓存dom节点
2六、开发智能事件处理程序
有时候咱们会感受到页面反应迟钝,这是由于DOM树元素中附加了过多的事件句柄而且些事件句病被频繁地触发。这就是为何说使用event delegation(事件代理)是一种好方法了。
27、减少Cookie体积
HTTP coockie能够用于权限验证和个性化身份等多种用途。coockie内的有关信息是经过HTTP文件头来在web服务器和浏览器之间进行交流的。所以保持coockie尽量的小以减小用户的响应时间十分重要。
有关更多信息能够查看Tenni Theurer和Patty Chi的文章“When the Cookie Crumbles”。这们研究中主要包括:
去除没必要要的coockie
使coockie体积尽可能小以减小对用户响应的影响
注意在适应级别的域名上设置coockie以便使子域名不受影响
设置合理的过时时间。较早地Expire时间和不要过早去清除coockie,都会改善用户的响应时间。
Cookie会每次在http中进行传输,静态文件放在不一样于主域名的域名,tb1.bdstatic.com这个域下不会携带cookie,利用locatstorage
2八、对于页面内容使用无coockie域名
当浏览器在请求中同时请求一张静态的图片和发送coockie时,服务器对于这些coockie不会作任何地使用。所以他们只是由于某些负面因素而建立的网络传输。全部你应该肯定对于静态内容的请求是无coockie的请求。建立一个子域名并用他来存放全部静态内容。imgsrc.baidu.com域下的静态图片有cookie
Tb1,tb2.bdstatic.com/这个域下的静态请求是没有cookie的
30、优化CSS Spirite
在Spirite中水平排列你的图片,垂直排列会稍稍增长文件大小;
Spirite中把颜色较近的组合在一块儿能够下降颜色数,理想情况是低于256色以便适用PNG8格式;
便于移动,不要在Spirite的图像中间留有较大空隙。这虽然不大会增长文件大小但对于用户代理来讲它须要更少的内存来把图片解压为像素地图。100x100的图片为1万像素,而1000x1000就是100万像素。
Spirite中水平排列你的图片,垂直排列会稍稍增长文件大小
3一、不要在HTML中缩放图像
不要为了在HTML中设置长宽而使用比实际须要大的图片。若是你须要:
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />
那么你的图片(mycat.jpg)就应该是100x100像素而不是把一个500x500像素的图片缩小使用。
3二、favicon.ico要小并且可缓存
3三、保持单个内容小于25K
这条限制主要是由于iPhone不能缓存大于25K的文件。注意这里指的是解压缩后的大小。因为单纯gizp压缩可能达不要求,所以精简文件就显得十分重要。
3四、打包组件成复合文本
针对上述优化法则中几个法则学习的技术点
为何要外置css/js? Expire,cache-control和etag的区别是啥?浏览器怎样缓存?
浏览器缓存行为还有用户的行为有关!!!用户行为决定了浏览器是否启用缓存,是直接走缓存仍是间接走缓存。
用户操做 |
Expires/Cache-Control |
Last-Modified/Etag |
地址栏回车 |
有效 |
有效 |
页面连接跳转 |
有效 |
有效 |
新开窗口 |
有效 |
有效 |
前进、后退 |
有效 |
有效 |
F5刷新 |
无效 |
有效 |
Ctrl+F5刷新 |
无效 |
无效 |
若是是初次无缓存浏览的话:
流程
浏览器请求 => 无缓存 è 发送请求向服务器 è 缓存协商 è 呈现
浏览器请求
è有缓存
è 缓存没有过时 è 直接读取浏览器缓存
è缓存过时,发送http 请求给服务器,请求投中带有if-modified-since或者if-none-match,于服务器端last-modify 和etag进行比较,若是为修改,返回304,读取浏览器渲染,若是发现修改,返回200,返回内容包装在消息体中,缓存协商,渲染
Expires cache-control last-modify etag的区别
Expires 是http1.0,目前已过时,为了兼容还带有expires
Cache-control 取代expires,带有更多的规则,max-age publice等
Last-modify 和etag 都是用来的标示文件是否被修改过,多用etag,若是同时出现,etag的优先级大于last-modify
各类方式各有优缺点,好比可否跨域、是否会阻塞其它资源的下载(可否并行下载)、可否管理控制执行顺序、耗费的资源、是否兼容各大浏览器等。
方法 |
说明 |
XHR Eval |
经过 Ajax 方式获取代码,并经过 eval 方式执行代码。 |
XHR Injection |
经过 Ajax 方式获取代码,并在页面上建立一个 script 元素,将 Ajax 取得的代码注入。 |
Script in Iframe |
经过 iframe 加载 js。 |
Script DOM Element |
使用 JavaScript 动态建立 script DOM 元素并设置其 src 属性。 |
Script Defer/Async |
严格来讲,这一条不算是动态加载外部脚本的方法,但不少动态加载外部脚本的方法里都会用到 sctipt 的 defer 或 async 属性,因此也把它单独列在这儿。这个方法利用 script 的 defer 属性,让脚本“推迟”执行,不阻塞页面加载,或者设置 async 属性,让脚本异步执行。遗憾的是这两个属性不是全部浏览器都支持。 |
document.write Script Tag |
经过 document.write 把 HTML 标签 script 写入到页面中。 |
cache trick |
先使用自定义的 script 的 type 属性(如 <script type=”text/cache” …),甚至使用 Image、Object 等 HTML 对象将 js “预下载”(下载到浏览器缓存里),等真正须要执行对应代码时再将它真正地插入页面中。 |
Web Worker |
部分浏览器支持 web worker 功能,能够建立一个 worker 在后台工做,包括加载外部脚本。 |
Bagpipe还正在学习中,bigpipe听从的优化原则是尽早刷新输出缓冲 。浏览器和服务器能够并行同时工做。
看到高性能网站建设那本书,关于css选择器的性能,发现以前我对css选择器的选择过程的认识是彻底错误的,css选择器是从右向左匹配的,而不是从左向右匹配。