Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<link> vs @import #9

Open
SamHwang1990 opened this issue Mar 18, 2017 · 0 comments
Open

<link> vs @import #9

SamHwang1990 opened this issue Mar 18, 2017 · 0 comments

Comments

@SamHwang1990
Copy link
Owner

[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.cssb.css会并发加载:

同级@import 声明并发下载

虽然a.css先声明,但假如b.cssa.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'>

using link ensures parallel downloads across all browsers

<link> mixed @import

当文档内使用<link>标签同时内联<style/>来使用@import声明时:

<link href="a.css" rel="stylesheet" type="text/css">
<style>
  @import url("b.css");
</style>

在IE6-8下,@import声明指向的样式表并不会与页面其他资源并发加载,而是等页面所有资源加载完成后才开始下载:

IE 下文档混合使用<link>与@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

LINK doesn't block @import embedded stylesheets in browsers other than IE

然而,在IE 浏览器中(具体到哪个版本范围没测过),c.css 样式表的加载会被挂起,直到b.css 加载完成:

LINK blocks @import embedded in other stylesheets in IE

总结

在了解了<link>@import的兼容性、加载次序上的差别后,我们需要明确这些差别在日常开发中会带来的影响,以及为什么不推荐使用@import来加载外部样式表:

  • @import声明的样式表不能充分利用浏览器并发请求资源的行为,因为其加载行为往往会押后触发或会被其他资源加载挂起;
  • 由于@import样式表的延后加载,可能会导致页面样式闪烁;
  • 由于@import样式表的延后加载,很有可能会比页面中的javascript 脚本加载更晚,导致js 对html 元素样式的修改可能会被延后才解析的外部样式表所覆盖;

参考文章

@SamHwang1990 SamHwang1990 changed the title link vs @import <link> vs @import Mar 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant