本文共 2585 字,大约阅读时间需要 8 分钟。
对于问题多多的IE678,FOUC(flash of unstyled content)——浏览器样式闪烁是一个不可忽视的话题,但对于ever green的浏览器就不用理会了吗?下面尝试较全面地解密FOUC。
页面加载解析时,页面以样式A渲染;当页面加载解析完成后,页面突然以样式B渲染,导致出现页面样式闪烁。
样式A,浏览器默认样式 或 浏览器默认样式 层叠 部分已加载的页面样式; 样式B,浏览器默认样式 叠加 全部页面样式。我们了解当输入网址按回车后浏览器会向服务器发送请求,然后服务器返回页面给浏览器,浏览器边下载页面边解析边渲染。
下面我们解剖一下边下载页面边解析边渲染的过程:head
标签中的原因,在body
渲染前先把相对完整的CSSOM Tree构建好。但大家都听说过script
会阻塞html页面解析(block parsing),而link
不会,那假如网络环境不好或样式资源体积大时,body
已经解析并加入到DOM Tree后,external stylesheet才加载完成,不是也会造成FOUC吗?style
,link
等样式资源的下载、解析确实不会阻塞页面的解析,但它们会阻塞页面的渲染(block rendering)。Block Parsing: 阻塞HTML页面解析,HTML页面会被继续下载,但阻塞点后面的标签不会被解析,img
,link
等不会发请求获取外部资源。
img
,link
等会继续发送请求获取外部资源,但不会合成Rendering Tree或不会触发页面渲染,也不会执行JavaScript代码。 各浏览器这方面还有一点差异: <link rel="stylesheet">
,<link rel="import">
and @import url("<url>")
会阻塞渲染。
Hi
示例2:阻塞渲染
Hi
示例3:阻塞渲染
Hi
示例4:阻塞渲染
Hi
示例2说明,如果阻塞渲染发生在body
标签内,那么body
及其子元素会继续解析并追加到DOM Tree中;
head
标签内,那么body
及其子元素不会被追加到DOM Tree中。 示例4说明,不管external stylesheet在哪里引入,在页面的所有external stylesheets下载完成前(DOMContentLoaded后才渲染),整个页面将不会被渲染。(估计Chrome会预先统计external stylesheet的数量) 示例1:阻塞渲染
Hi
示例2:阻塞渲染
Hi
示例1:
Hi
示例2:
Hi
上面的示例表明,IE下block rendering等价于block parsing,因为连img
,script
,link
,@import url()
资源请求都会被阻塞。
现在我们知道FOUC时由于页面采用临时样式来渲染页面而导致的,其中仅有chrome能好的屏蔽了这一点,而其他浏览器就呵呵了。那有什么方案可以解决呢?其实我们的目的就是不要让用户看到临时样式,那么我们可以隐藏body
,当样式资源加载完成后再显示body
。
(编译modernizr时记得勾setClasses哦,否则不会替换no-js的!)
上述方案虽然解决了FOUC的问题,但很明显地延长了首屏白屏时间,当前较流行的App Shell(可以理解为先显示页面布局的骨架或一幅图片)也会失效,所以对于2C的应用仅仅采用上述的方案效果并不理想。后续待我研究好后再追加一篇吧^^ 尊重原创,转载请注明来自: ^^肥仔John
如果您觉得本文的内容有趣就扫一下吧!捐赠互勉!
本文转自博客园博客,原文链接:,如需转载请自行联系原作者