面试时候有被cue到这点,当时回答的不是很利索,面试官表示解释不够详细,于是便有了这篇文章。
浏览器访问网站(无CDN)
1.用户在自己的浏览器输入要访问的网站域名。
2.浏览器向本地DNS服务器请求对应域名的解析。
3.本地DNS服务器中如果缓存有此域名的解析结果,则直接向用户相应解析结果,如果没有缓存此域名的解析结果,则以递归的方式向整体DNS系统请求解析,获得结果后应答浏览器。
4.浏览器得到域名解析的结果,就是该域名服务器的IP地址,浏览器向此IP发出请求。
5.服务端响应请求,把相应的数据传给浏览器。
浏览器渲染页面
1.根据html文件构建DOM树和CSSOM树。构建DOM树期间,如果遇到JS,阻塞DOM树及CSSOM树的构建,优先加载JS文件,加载完毕,再继续构建DOM树及CSSOM树。
2.构建渲染树(Render Tree)。
3.页面的重绘(repaint)与重排(reflow,也有称回流)。页面渲染完成后,若JS操作了DOM节点,根据JS对DOM操作动作的大小,浏览器对页面进行重绘或是重排。
注意点(面试时遇到的问题)
- 构建
DOM树
读取html文档,将字节转换成字符,确定tokens(标签),再将tokens转换成节点,以节点构建 DOM 树
- 构建
CSSOM树
读取CSS文档,将字节转换成字符,确定tokens(标签),再将tokens转换成节点,以节点构建 CSSOM 树。
- 加载
JS
JS会对DOM节点进行操作,浏览器无法预测未来的DOM节点的具体内容,为了防止无效操作,节省资源,只能阻塞DOM树的构建
- 如何减少和避免回流
- 直接改变className,如果动态改变样式,则使用cssText(考虑没有优化的浏览器).
- 让要操作的元素进行”离线处理”,处理完后一起更新:
- 使用DocumentFragment进行缓存操作,引发一次回流和重绘;
- 使用display:none技术,只引发两次回流和重绘;
- 使用cloneNode(true or false) 和 replaceChild 技术,引发一次回流和重绘.
3.不要经常访问会引起浏览器flush队列的属性,如果你确实要访问,利用缓存.
- 让元素脱离动画流,减少回流的Render Tree的规模. Tip : 回流 必将引起 重绘,而 重绘 不一定会引起 回流 且 回流 的成本比 重绘 的成本高得多的多。