<link> vs @import
Opened this issue · 0 comments
[toc]
引用外部样式表一般有两种方式。
第一种是使用html 的link
标签:
<link href="external.css" rel="stylesheet" type="text/css">
第二种是使用css 的@import
语法:
// a.css
@import url("b.css");
或是html style 标签内使用:
<style>
@import url("b.css");
</style>
需要明确的一点是,@import
声明只能在style 标签或css 文件的顶部,在其他位置声明是无效的。
这两种方式的差别其实挺大的,鉴于@import
可能造成的交互、性能影响,我们强烈建议只使用<link>
标签来加载外部样式表。
下面简单聊下两种方式的差别。
兼容性
<link>
标签是标准的html 标签,从第一个版本开始就一直存在,故不存在兼容性问题。
而@import
语法是从css 2.1 开始引入的,所以只能兼容IE5 以上的浏览器。当然了,在当今世代,这根本不用担心。
加载次序
<link>
与@import
造成的样式表加载方式是非常不一样的,这里面的区别会造成很多性能上和交互使用上的差异。下文罗列Steve Souders 对该问题的研究成果,参考自:don’t use @import
@import
对性能的影响主要在于,该语法指向的样式表不能与<link>
指向的样式表并发下载,只能等待后者的样式表加载完。具体场景例如:
@import and @import
同个css 文件或同个<style>
标签内出现多个@import
声明,则这些声明指向的样式表会并发加载,谁先下载完就先解析并应用到文档上。
比如:
<style>
@import url('a.css');
@import url('b.css');
</style>
a.css
、b.css
会并发加载:
虽然a.css
先声明,但假如b.css
比a.css
先加载完成,则b.css
会先解析。
<link>
and <link>
文档中使用<link>
标签指向的外部样式表,都会并发下载,前提时同域名连接数没有超过浏览器限制:
<link rel='stylesheet' type='text/css' href='a.css'>
<link rel='stylesheet' type='text/css' href='b.css'>
<link>
mixed @import
当文档内使用<link>
标签同时内联<style/>
来使用@import
声明时:
<link href="a.css" rel="stylesheet" type="text/css">
<style>
@import url("b.css");
</style>
在IE6-8下,@import
声明指向的样式表并不会与页面其他资源并发加载,而是等页面所有资源加载完成后才开始下载:
@import within <link>
当@import
声明位于<link>
指向的外部样式表时,所有浏览器都不会并发加载该样式表,而是等页面所有资源加载完成后才开始。代码如下:
<link href="a.css" rel="stylesheet" type="text/css">
// a.css
@import url("b.css");
这种行为其实很容易理解,因为a.css
本身时会在文档解析资源时并发加载,加载完后,自身也完成了解析,至于声明引用的b.css
并不是文档本身,也就不需要并发加载b.css
:
<link>
blocks @import
场景代码:
<link href="a.css" rel="stylesheet" type="text/css">
<link href="b.css" rel="stylesheet" type="text/css">
// a.css
@import url("c.css");
在文档中,分别用<link>
标签引用了a.css、b.css,而a.css 又使用@import 声明引用了c.css。注意下次序结构:
+ a.css
+ c.css
+ b.css
预期中,当a.css 加载并解析完的时候,应该就开始加载c.css
:
然而,在IE 浏览器中(具体到哪个版本范围没测过),c.css 样式表的加载会被挂起,直到b.css 加载完成:
总结
在了解了<link>
与@import
的兼容性、加载次序上的差别后,我们需要明确这些差别在日常开发中会带来的影响,以及为什么不推荐使用@import
来加载外部样式表:
@import
声明的样式表不能充分利用浏览器并发请求资源的行为,因为其加载行为往往会押后触发或会被其他资源加载挂起;- 由于
@import
样式表的延后加载,可能会导致页面样式闪烁; - 由于
@import
样式表的延后加载,很有可能会比页面中的javascript 脚本加载更晚,导致js 对html 元素样式的修改可能会被延后才解析的外部样式表所覆盖;