@fengfeng
2015-09-15T03:42:10.000000Z
字数 6399
阅读 3232
浏览器
browser
parse
render
localcache
当我们从开始在地址栏输入url到最后浏览器把页面展示给我们,这中间浏览器都做了哪些事情?
首先浏览器会根据url查找本地缓存,看是否本地缓存中存在该url的内容,如果不存在,则向服务器请求该url的内容,否则:
优化点:
- 给静态资源设置适当的缓存时间 expire:xxx /cache-control:max-age=xxx
- 返回的http头带Last-Modified/Etag,当内容过期时,进行条件查询请求;
进一步阅读
当浏览器向服务器发送请求,请求一个url对应的资源时,首先是检查是否本地有服务器host的ip,如果没有通过DNS查询来获取服务器的ip。
无线网络的现状:
- 2G:一般只有10KB/S下行和1KB/S左右的上行速度,延迟基本不低于400ms;
- 3G网络:一般为下行100-200KB/S,上行10-100KB/S,延迟0-400ms,带宽方面基本逼近2M有线网络,但延迟较高,稳定性不够
DNS查询耗时:
- 在相对较快速的有线网络环境下,平均值为数十毫秒左右;
- 2G网络环境下,平均值在几百毫秒左右;
- 在网络很差的移动环境下,平均值达到几秒左右
优化点:
- 让浏览器提前查询dns:dns-prefetch
- 减少页面中的资源的域名/直接ip
<link rel="dns-prefetch" href="pic2.58.com" >
根据DNS查询得到ip+url中的端口80,向服务器发起TCP连接。
因为用户和服务器之间的距离(不仅是物理距离,还有网络链路距离,以及跨运营商中转等)不同,建立连接的时间不同。
优化点:
- 采用CDN,让用户与它最近的服务器建立连接
TCP建立连接3次握手
因为每建立一次TCP连接,都要进行3次握手,建连成本大;
优化点:
- 减少建立连接的次数:merge CSS/js/image
- 减少建立连接的次数:remove empty src/href/URL
- 减少建立连接的次数:keep-alive
当浏览器发送http请求头时,会把相关一些信息发送,这些信息包括:UA,Localsetting,Referer,Cookie等
优化点:
- 能用get,不用post请求url,post至少发送两个包
- 减少发送的http header的大小:避免发送不需要的cookie,静态资源放到独立域名的服务器上
- 减少发送的http header的大小:缩短url的长度,不同浏览器和服务器对url的长度也有限制
GET / HTTP/1.1
Host:www.taobao.com
User-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.17) Gecko/20110420Firefox/3.6.17
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Encoding:gzip,deflate
Accept-Language:en-us,en;q=0.5
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.
Keep-Alive:115
Connection: keep-alive
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 12May 2011 11:02:36 GMT
Content-Type:text/html; charset=GB2312
Transfer-Encoding:chunked
Connection:keep-alive
进一步阅读
服务器接到请求后,根据请求的url和数据等,经过一系列运算,拼出一个大字符串就是网页的内容返回给浏览器
浏览器是边下载边解析,
优化点:
- bigPipe,flush buffer early 不必等所有数据都拿到再拼页面,有一点就输出,早点刷新缓冲区,节省的是等待服务器响应的时间
传统页面展现
bigpipe页面展现
- 304 Not Modified 浏览器还是利用老的缓存数据
- 200 Ok 新的内容
返回的数据越少,传输的越快
优化点:
- 返回的内容进行压缩HTML/CSS/js/img compres gzip
- 异步刷新,不需要返回全部内容,只返回变化的部分,ajax等
浏览器处理过程中的每一个步骤:
根据http响应返回的数据根据页面编码进行解码,而浏览器判断编码主要是依据以下方法:
解析返回的内容,一个字符一个字符解析,边下载边解析
优化点:
- 通过HTTP头信息或meta标签尽早指定正确的字符编码
- 去除HTML/CSS/js/中的空白字符
解析过程遇到css,js等资源,就会发起请求,下载css,js,..,但是浏览器同一个域名并行下载个数有限制
优化点:
- js/css 多域名存放,增加并行下载的个数,注意与cdn查询成本从和浏览器处理性能之间的平衡
进一步阅读
字节(Bytes) -> 字符(characters) -> 标记(tokens) -> 节点(nodes) -> 对象模型
1. 转换(Conversion): 浏览器从磁盘或者网络上读取HTML的原始字节,然后根据指定的编码规则转换成单独的字符(比如按UTF-8编码)。
2. 标记分解(Tokenizing):浏览器将字符串按照W3C HTML5标准转换成确定的标记,比如、以及其他带尖括号的字符。每个标记都有特定的意义以及一套规则。
3. 词法分析(Lexing):分解出来的标记被转换成能定义其属性和规则的对象。
4. DOM 构造: 最终由于HTML标记创建出来的对象被关联到一个树形数据结构。这颗树会反映在原先标签里定义的父子关系,比如HTML对象就是body对象的父对象,body对象又是paragraph对象的父对象等等。
优化点:
- 删除无用的html标签,精简html结构,尽量减少不必要的dom的深度
进一步阅读
当css下载完成后,与HTML一样,进行构建cssom:
优化点:
- 避免通配选择器
- 删除多余的修饰语
- 避免使用后代选择器,特别是那些指定多余祖先的
- 使用class选择器代替后代选择器
- 在IE中避免对非链接元素应用:hover
- 避免CSS expressions
进一步阅读
浏览器只有同时具备DOM(Document Object Mode,文档对象模型)和CSSOM(CSS Object Model,CSS对象模型)才能来构造渲染树。
为了创建渲染树,浏览器大致需要如下的步骤:
谷歌 Web 开发最佳实践手册(4.1.2):渲染树结构、布局和绘制
浏览器即使已经处理好了某些页面内容,只要CSSOM没有构建好,便不会进行渲染,CSS是渲染过程中的阻塞性资源
js前面的css会阻塞js的执行
js执行阻塞页面的解析,domtree的构建
css优化点:
- gzip,提高传输速度,css尽早加载
- 优化css代码,css代码瘦身,压缩,去除冗余
- put css head,js bottom
js优化点:
- js压缩,gzip,提高传输速度
- put css head,js bottom
- 页面中不要插入js的代码,根据实际情况对js进行defer/asyn,或创建标签异步加载js;
- 代码优化,使用id选择器,使用标准的css选择器,
〉* 对常用变量暂存- 对长时间执行的代码用定时器来分片执行或html5 worker
我们已经计算了什么节点是可视的以及它们对应的样式是什么,但是我们还没有计算它们在当前设备中准确的位置和尺寸。这正是布局阶段要做的的工作,该阶段在英语中也被称为“回流”(reflow)。布局阶段的输出结果称为 “盒模型”(box model)。盒模型精确表达了窗口中每个元素的位置和大小,而且所有的相对的度量单位都被转化成了屏幕上的绝对像素位置。
最后阶段,已经知道了哪些节点是可视的、它们的样式和它们的几何外观,我们终于能够将这些信息渲染为屏幕上每个真实的像素点了。这个阶段称为“绘制”,或者“格栅化”(rasterizing)。一旦布局阶段完成,浏览器便开始绘制阶段,将渲染树转化为屏幕上的每个像素点
通过调用操作系统Native GUI的API绘制每一个像素点,更新显存,给显示器发送信号,显示器根据得到的信号进行显示。
如果浏览器刷新频率为60hz,那么定时器的时间小于1/60s(16.666..ms)就没有意义。
优化点:
- 设置适当的定时时间
- 使用requestAnimationFrame(rAF)来代替定时器动画
- 利用GPU加速
进一步阅读
Accelerated Rendering in Chrome
Jank Busting for Better Rendering Performance
Leaner, Meaner, Faster Animations with requestAnimationFrame
GPU Accelerated Compositing in Chrome
以下这些会引起reflow & repaint:
DOM元素的添加、修改(内容)、删除( Reflow + Repaint),添加新的页面内容,例如输入框输入文字等
读取元素的某些属性(offsetLeft、offsetTop、offsetHeight、offsetWidth、scrollTop/Left/Width/Height、clientTop/Left/Width/Height、getComputedStyle()、currentStyle(in IE))
优化点:
- 尽可能限制reflow的影响范围,避免在document上直接进行频繁的DOM操作,如果确实需要可以采用off-document的方式进行
- 先将元素从document中删除,完成修改后再把元素放回原来的位置
- 将元素的display设置为”none”,完成修改后再把display修改为原来的值
- 如果需要创建多个DOM节点,可以使用DocumentFragment创建完后一次性的加入
- 最好通过设置class的方式,避免通过style设置
- 实现元素的动画,它的position属性应当设为fixed或absolute,这样不会影响其它元素的布局
- 不要用table布局,用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染
- 避免使用css expression
- 在HTML的标签中或在CSS中为所有图片指定宽度和高度,或它的块级父元素指定宽度和高度;指定与图片本身相一致的尺寸
- 把外部样式表和内联样式块放在页面的中,确保样式表首先被下载和解析
- 通过HTTP头信息或meta标签尽早指定正确的字符编码
进一步阅读
Rendering: repaint, reflow/relayout, restyle
浏览器的加载过程
从输入 URL 到页面加载完成的过程中都发生了什么事情?
高性能浏览器网络(High Performance Browser Networking) 第一章
高性能浏览器网络(High Performance Browser Networking) 第二章