前端优化的技术点浅析
最近关注前端页面的性能优化,参照一些文章做了整理,在前端方面属于门外汉,大多数都是在相应的文章中摘取的笔记。
- 归纳
- 使用缓存和CDN
- 减少页面的HTTP请求
- 减少下载的内容
- 减少渲染过程中的阻塞
- 减少渲染过程中的瓶颈
- PageSpeed规则
- 避免目标页面重定向,访问页面的过程中进行了多次重定向
- 启用压缩功能,第三方webserver会将文件进行压缩,之后传输
- 改善服务器的响应时间,pagespeed在服务端的RT超过200ms会认为比较差
- 静态文件采用浏览器的缓存机制
- 缩减资源文件的大小,例如js、css等文件,去掉无用的空格缩进等
- 优化图片,做一些无损压缩
- 缩减首屏内容的大小
- 使用异步脚本,不用让用户等待完成下载再去呈现网页
- chrome控制台的指标分析
- Network的功能是非常实用和强大的;
- 从左到右分别是Name、Method、Status、Type、Initiator、Size、Time和Timeline。Name表示加载的文件名,Method表示请求的方法,Status表示状态码(200为请求成功,304表示从缓存读取),Type表示文件的MIME Type的类型。Initiator表示发出这个文件请求的发出者,Size表示文件大小;
- Time表示每个请求的总时长,Timeline以图表的形式显示了整个网页的请求和加载情况;
- Timeline中有一条蓝线和一条红线,蓝线表示DOM Content Loaded事件触发的时间,红线表示 Window onload事件触发的时间;
- 模拟慢速网络Charles
- Charles中的Throtting功能可以模拟慢速网络,http://www.charlesproxy.com/download/
- 监测工具
- Page Speed 是谷歌开发的分析和优化网页的工具,可以作为浏览器插件使用。工具基于一系列优化规则对网站进行检测,对于未通过的规则会给出详细的建议。与此类似的工具还有 Yslow 等,推荐使用gtmetrix网站同时查看多个分析工具的结果;
- 阿里测,http://alibench.com/
- 前端页面耗时可以参考的时间
- 0.1秒 : 0.1 秒是用户感知的最小粒度,在这个时间范围内完成的操作被认为是流畅没有延迟的
- 1.0秒: 1.0 秒内完成的响应认为不会干扰用户的思维流。尽管用户能感觉到延迟,但 0.1 秒 -1.0 秒内完成的操作并不需要给出明显 loading 提示
- 10秒 : 达到 10 秒用户将无法保持注意力,很可能选择离开做其他事情
- 页面数据相关
- 访问数据
- PV/UV:最基础的 PV(页面访问数量)、UV(独立访问用户数量)
- 页面来源:页面的 refer,可以定位页面的入口
- 操作系统:了解用户的 OS 状况,帮助分析用户群体的特征,特别是移动端,iOS 和 Android 的分布就更有意义了
- 浏览器:可以统计到各种浏览器的占比,对于是否继续兼容 IE6、新技术(HTML5、CSS3 等)的运用等调研提供参考价值
- 分辨率:对页面设计提供参考,特别是响应式设计
- 登录率:登陆用户具有更高的分析价值,引导用户登陆是非常重要的
- 地域分布:访问用户在地理位置上的分布,可以针对不同地域做运营、活动等
- 网络类型:wifi/3G/2G,为产品是否需要适配不同网络环境做决策
- 访问时段:掌握用户访问时间的分布,引导消峰填谷、节省带宽
- 停留时长:判断页面内容是否具有吸引力,对于需要长时间阅读的页面比较有意义
- 到达深度:和停留时长类似,例如百度百科,用户浏览时的页面到达深度直接反映词条的质量
- 性能数据
- 白屏时间:用户从打开页面开始到页面开始有东西呈现为止,这过程中占用的时间就是白屏时间
- 首屏时间:用户浏览器首屏内所有内容都呈现出来所花费的时间
- 用户可操作时间:用户可以进行正常的点击、输入等操作
- 页面总下载时间:页面所有资源都加载完成并呈现出来所花的时间,即页面 onload 的时间
- 自定义的时间点:对于开发人员来说,完全可以自定义一些时间点,例如:某个组件 init 完成的时间、某个重要模块加载的时间等等
- 访问数据
- 如何统计白屏时间
- 白屏时间是用户首次看到内容的时间,也叫做首次渲染时间,chrome 高版本有 firstPaintTime 接口来获取这个耗时,但大部分浏览器并不支持,必须想其他办法来监测;
- 观察 WebPagetest 视图分析发现,白屏时间出现在头部外链资源加载完附近,因为浏览器只有加载并解析完头部资源才会真正渲染页面。基于此我们可以通过获取头部资源加载完的时刻来近似统计白屏时间。尽管并不精确,但却考虑了影响白屏的主要因素:首字节时间和头部资源加载时间;
- 如何统计首屏时间
- 首屏时间的统计比较复杂,因为涉及图片等多种元素及异步渲染等方式。观察加载视图可发现,影响首屏的主要因素的图片的加载。通过统计首屏内图片的加载时间便可以获取首屏渲染完成的时间;
- 首屏位置调用 API 开始统计 -> 绑定首屏内所有图片的 load 事件 -> 页面加载完后判断图片是否在首屏内,找出加载最慢的一张 -> 首屏时间;
- 如何统计统计用户可操作和总下载
- 用户可操作默认可以统计domready时间,因为通常会在这时候绑定事件操作。对于使用了模块化异步加载的 JS 可以在代码中去主动标记重要 JS 的加载时间;
- 总下载时间默认可以统计onload时间,这样可以统计同步加载的资源全部加载完的耗时。如果页面中存在很多异步渲染,可以将异步渲染全部完成的时间作为总下载时间;
- 关于Navigation Timing
- Navigation Timing 是一个可以在web中精确测量性能的javascript API。这个API提供了一个简单的方法来获得页面导航、加载事件的精确而又详细的时间状态。目前在 IE9、Chrome、Firefox nightly builds 中可用;
- chrome 工具->控制台,输入performance,就可以看到数据(测量以毫秒的形式从1970年1月1日的午夜开始,结果为0表示该事件未发生);
- navigationStart:当load/unload动作被触发时,也可能是提示关闭当前文档时(即回车键在url地址栏中按下,页面被再次刷新,submit按钮被点击)。如果当前窗口中没有前一个文档,那么navigationStart的值就是fetchStart。
- redirectStart:它可能是页面重定向时的开始时间(如果存在重定向的话)或者是0。
- unloadEventStart:如果被请求的文档来自于前一个同源(同源策略)的文档,那么该属性存储的是浏览器开始卸载前一个文档的时刻。否则的话(前一个文档非同源或者没有前一个文档),为0。 所谓同源是指,域名,协议,端口相同。
- unloadEventEnd:表示同源的前一个文档卸载完成的时刻。如果前一个文档不存在或者非同源,则为0。 + redirectEnd:如果存在重定向的话,redirectEnd表示最后一次重定向后服务器端response的数据被接收完毕的时间。否则的话就是0。
- fetchStart:fetchStart是指在浏览器发起任何请求之前的时间值。在fetchStart和domainLookupStart之间,浏览器会检查当前文档的缓存。
- domainLookupStart:这个属性是指当浏览器开始检查当前域名的DNS之前的那一时刻。如果因为任何原因没有去检查DNS(即浏览器使用了缓存,持久连接,或者本地资源),那么它的值等同于fetchStart。
- domainLookupEnd:指浏览器完成DNS检查时的时间。如果DNS没有被检查,那么它的值等同于fetchStart。
- connectStart:当浏览器开始于服务器连接时的时间。如果资源取自缓存(或者服务器由于其他任何原因没有建立连接,例如持久连接),那么它的值等同于domainLookupEnd。
- connectEnd:当浏览器端完成与服务器端建立连接的时刻。如果没有建立连接它的值等同于domainLookupEnd。
- secureConnectionStart:可选。如果页面使用HTTPS,它的值是安全连接握手之前的时刻。如果该属性不可用,则返回undefined。如果该属性可用,但没有使用HTTPS,则返回0。
- responseStart:指客户端收到从服务器端(或缓存、本地资源)响应回的第一个字节的数据的时刻。
- responseEnd:指客户端收到从服务器端(或缓存、本地资源)响应回的最后一个字节的数据的时刻。
- domLoading:指document对象创建完成的时刻。
- domInteractive:指文档解析完成的时刻,包括在“传统模式”下被阻塞的通过script标签加载的内容(除了使用defer或者async属性异步加载的情况)。
- domContentLoadedEventStart:当DOMContentLoaded事件触发之前,浏览器完成所有script(包括设置了defer属性但未设置async属性的script)的下载和解析之后的时刻。
- domContentLoadedEventEnd:当DOMContentLoaded事件完成之后的时刻。它也是javascript类库中DOMready事件触发的时刻。
- domComplete:如果已经没有任何延迟加载的事件(所有图片的加载)阻止load事件发生,那么该时刻将会将document.readyState属性设置为"complete",此时刻就是domComplete。
- loadEventStart:该属性返回的是load事件刚刚发生的时刻,如果load事件还没有发生,则返回0。
- loadEventEnd:该属性返回load事件完成之后的时刻。如果load事件未发生,则返回0。
- 基于这些数据分析出来的时间
- DNS域名解析时长:从发起页面域名解析至解析完成;
- domainLookupEnd-domainLookupStart
- Connect建立与服务器TCP连接时长:从发起TCP连接至三次握手完成;
- connectEnd-connectStart
- Request请求时长:从发起页面请求至服务器端返回第一个字节;
- responseStart-requestStart
- Response响应时长:从接收服务器发回的第一字节至主页面下载完成;
- responseEnd-responseStart
- DomReady页面Dom树解析:从页面跳转至页面Dom元素稳定;
- domContentLoadedEventEnd-StartTime
- DNS域名解析时长:从发起页面域名解析至解析完成;
- 文章参考
- http://fex.baidu.com/blog/2014/05/build-performance-monitor-in-7-days/
- https://developers.google.com/speed/docs/insights/rules
- http://www.html5rocks.com/en/tutorials/webperformance/basics/?redirect_from_locale=zh
- http://www.programmer.com.cn/14601/