Thursday, April 23, 2009

link vs @import

Conclusion: Always use LINK instead of @import if you want stylesheets to download in parallel resulting in a faster page.

LINK vs. @import

There are two ways to include a stylesheet in your web page. You can use the LINK tag:

< rel="'stylesheet" href="’style.css’">

Or you can use the @import rule:

<>

@import url('style.css');

< /style >

I prefer using LINK for simplicity—you have to remember to put @import at the top of the style block or else it won’t work. It turns out that avoiding @import is better for performance, too.

@import @import

I’m going to walk through the different ways LINK and @import can be used. In these examples, there are two stylesheets: style.css and type.css. Each stylesheet is configured to take two seconds to download to make it easier to see the performance impact. The first example uses @import to pull in these two stylesheets. In this example, called @import @import, the HTML document contains the following style block:

<>
@import url('style.css')

@import url('type.css');

< /style >

If you always use @import in this way, there are no performance problems, although we’ll see below it could result in JavaScript errors due to race conditions. The two stylesheets are downloaded in parallel, as shown in Figure 1. (The first tiny request is the HTML document.) The problems arise when @import is embedded in other stylesheets or is used in combination with LINK.


Figure 1. always using @import is okay

LINK @import

The LINK @import example uses LINK for style.css, and @import for type.css:

<> rel="stylesheet' type="text/css" href="style.css">

<>

@import url('type.css');

< /style >

In IE (tested on 6, 7, and 8), this causes the stylesheets to be downloaded sequentially, as shown in Figure 2. Downloading resources in parallel is key to a faster page. As shown here, this behavior in IE causes the page to take a longer time to finish.


Figure 2. link mixed with @import breaks parallel downloads in IE

LINK with @import

In the LINK with @import example, style.css is inserted using LINK, and style.css has an @import rule to pull in type.css:

in the HTML document:

< rel="'stylesheet'" type="'text/css'" href="'style.css'">

in style.css:

@import url('type.css');

This pattern also prevents the scripts from loading in parallel, but this time it happens on all browsers. When we stop and think about it, we shouldn’t be too surprised. The browser has to download style.css and parse it. At that point, the browser sees the @import rule and starts to fetch type.css.


Figure 3. using @import from within a LINKed stylesheet breaks parallel downloads in all browsers

LINK blocks @import

A slight variation on the previous example with surprising results in IE: LINK is used for style.css and for a new stylesheet called proxy.css. proxy.css is configured to return immediately; it contains an @import rule for type.css.

in the HTML document:

< rel="stylesheet” type=" href="style.css">

< rel="stylesheet" type="text/css" href="proxy.css">

in proxy.css:

@import url('type.css');

The results of this example in IE, LINK blocks @import, are shown in Figure 4. The first request is the HTML document. The second request is style.css (two seconds). The third (tiny) request is proxy.css. The fourth request is type.css (two seconds). Surprisingly, IE won’t start downloading type.css until style.css finishes. In all other browsers, this blocking issue doesn’t occur, resulting in a faster page as shown in Figure 5.


Figure 4. LINK blocks @import embedded in other stylesheets in IE


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

many @imports

The many @imports example shows that using @import in IE causes resources to be downloaded in a different order than specified. This example has six stylesheets (each takes two seconds to download) followed by a script (a four second download).

<>

@import url('style.css');

@import url('type.css');

@import url('c.css');

@import url('d.css');

@import url('e.css');

@import url('f.css');

< /style >

< src="'one.js'" type="'text/javascript'">< /script >

Looking at Figure 6, the longest bar is the four second script. Even though it was listed last, it gets downloaded first in IE. If the script contains code that depends on the styles applied from the stylesheets (a la getElementsByClassName, etc.), then unexpected results may occur because the script is loaded before the stylesheets, despite the developer listing it last.


Figure 6. @import causes resources to be downloaded out-of-order in IE

LINK LINK

It’s simpler and safer to use LINK to pull in stylesheets:

< rel="'stylesheet'" type="'text/css'" href="'style.css'">

< rel="'stylesheet'" type="'text/css'" href="'type.css'">

Using LINK ensures that stylesheets will be downloaded in parallel across all browsers. The LINK LINK example demonstrates this, as shown in Figure 7. Using LINK also guarantees resources are downloaded in the order specified by the developer.


Figure 7. using link ensures parallel downloads across all browsers

These issues need to be addressed in IE. It’s especially bad that resources can end up getting downloaded in a different order. All browsers should implement a small lookahead when downloading stylesheets to extract any @import rules and start those downloads immediately. Until browsers make these changes, I recommend avoiding @import and instead using LINK for inserting stylesheets.


3 comments:

  1. Digg like new site launch here you can add your blog post and get Traffic very easy

    check it out.

    http://www.topwebpost.com

    ReplyDelete
  2. what kind of comments are here :?

    ReplyDelete
  3. I don't know. But I approved as the above site in this comment is good :)

    ReplyDelete