1、用户输入URL地址;
2、浏览器解析URL解析出主机名;
3、浏览器将主机名转换成服务器ip地址(浏览器县查找本地DNS缓存列表,没有的话再向浏览器默认的DNS服务器发送查询请求 同时缓存);
4、浏览器将端口号从URL中解析出来;
5、浏览器与目标web服务器建立TCP链接;(三次握手)
6、浏览器向服务器发送一条HTTP请求报文;
7、服务器接受到浏览器发送的HTTP请求并返回一条HTTP相应报文;
8、关闭TCP链接;
9、浏览器解析HTML文档等并完成布局渲染;
10、如果文档中有资源,重复6、7、8、9动作,直至资源全部加载完毕;
浏览器的渲染过程
1、解析HTML,得到一个DOM tree;
2、解析CSS,得到CSSOM tree;
3、将两者整合成渲染数,render tree;
4、布局(layout), 根据Render Tree计算每个节点的位置大小等信息;
5、绘制(Painting )根据计算好的信息绘制整个页面;
1、2、3非常快,但是4和5比较耗时,有三个术语: “重排” 和 “回流”是一个意思,指的是重新执行步骤4 “重绘” 指重新执行步骤5 重排意味着重新计算节点的位置大小等信息,重新在草稿本上画了草图,所以一定会重绘 重绘不一定会重排,比如背景颜色改变
重排和重绘代价很高,所以浏览器并不会一有信息改变就去执行重排和重绘,而是会将多个可能的重排和重绘一次执行。是的,它可能会异步。
有两个css属性,display: none和visibility: hidden,前者会导致重排和重绘,后者会导致重绘。这是后者的优点,但缺点是此节点一直保存在内存中,占用资源。
解析HTML的详细过程
1.预扫描HTML,下载资源;
2.解析HTML,得到一个DOM,添加到 DOM tree;
3.如遇到style,得到一个CSSOM ,添加到 CSSOM tree;
4.如遇到第一个外部css,若已下载完,同3,如果没有则继续解析HTML;
5.如再遇到外部css,只要前面的外部css或本css没有下载完,就继续解析HTML,因为CSS需要顺序解析,不然层叠样式就可能错误;
6.遇到script,会暂停解析HTML,等待其下载完毕。下载完毕后,如果所有的外联的css下载完毕(即使是在此script标签后的css),则执行此脚本,不然会等待css下载、解析完毕再执行;
7.解析到body中的第一脚本,如果css解析完毕,则开始预渲染(first paint);
所以css的下载会阻塞js的执行、预渲染。不会直接阻塞html的解析。但是当css的下载阻塞了js的执行,js的执行又阻塞了html的解析时,css的下载就会间接阻塞html解析。
页面渲染优化
1、HTML文档结构层级尽量少,最好不要深与六层;
2、js脚本尽量后放;
3、少量首屏样式内联放在标签内;
4、样式结构层次尽量简单;
5、在js脚本中尽量减少DOM操作,尽量缓存访问DOM的样式信息,避免过度触发回流;
6、减少通过JavaScript代码修改元素样式,尽量使用修改class名方式操作样式或动画;
7、动画尽量使用在绝对定位或者固定定位的元素上(脱离文档流 BFC);
8、隐藏在屏幕外。或在页面滚动时,尽量停止动画;
9、涉及多域名的网站,尽量开启域名预解析;