Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance when combining specific page styles AND global style in the same page

My main goal is to allow for the loading of several pages to be as fast as possible. For this I want to take advantage of both, the cache and one "special technique" that, as a fallback, relies on the standard cache.

Structure

On the backend I have the following structure. There's a main page in the public_html and several subpages, each with specific css rules different from each other. The creation of all the minimized files is done by a script, so no extra complexity there. For simplicity, let's assume that this is the structure, although it's more complex:

/public_html
  /index.php
  /style.css    ~50kb
  /min.css      ~100kb
  /subjects
    /index.php
    /style.css      ~20kb
    /min.css        ~10kb
  /books
    /index.php  
    /style.css      ~20kb
    /min.css        ~10kb
  ...

First request

So when the user enters first time on a subpage, they will receive this html code:

<!DOCTYPE html>
<html>
  <head>
    <link href="/subjects/min.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    All the body here
    <link href="/min.css" rel="stylesheet" type="text/css">
  </body>

As you can see, the user loads all the css code needed for that page in the header, in a small file. Note that /subjects/min.css is MUCH smaller than /min.css which would make this first request to load faster. Then, after the full html and css has correctly loaded, the /min.css will start loading. This file contains all of the subpages style.

Note that it's appropriate to put the <link> within the <body> tag, and even if it didn't work, there's no problem since the page-specific style is already loaded. Why am I loading this here? Keep reading:

Following requests

For the second and subsequent requests on that session, the user will receive this html code:

<!DOCTYPE html>
<html>
  <head>
    <link href="/min.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    All the body here
  </body>

The /min.css should be already cached from the first request. However, if for any reason it's not, it will load now the full minimized style, as in any normal website. This would be the fallback case.

Is this a valid scheme? Why haven't I seen anything like this before? Does it contain any logic error?

These are the main problems I can see, not strong enough in comparison to the benefits:

  • It adds some extra complexity to the code.
  • An extra request, after everything is already loaded, needs to be made. This would add a slight overhead on the server, however it's a static file.

Notes about the comments:

  1. The browser will make less requests. This is true, in this way the browser does one extra request. However, it's after loading the html and css, so this will not affect in a great manner the html.

  2. Cache. Yes, I'm doing my best to catch the file. A point could be made against cache of the <link> if it's inside the <body>, though, because I don't know if it behaves differently about the cache, I only assumed yes in the question.

like image 892
Francisco Presencia Avatar asked Feb 12 '14 20:02

Francisco Presencia


People also ask

Should every page have its own CSS file?

A site with only a few pages likely only needs one CSS file. Even if it has a few pages with different template, as long as those templates are fairly similar it can be all rolled together. Even sites with hundreds or thousands of pages can often get away with a single CSS file if the pages are largely the same.

What is the most efficient way of inserting CSS styles?

The best method for attaching your CSS style sheets is to use external styles. With this method, you will write all your CSS in a separate file with a . css extension. You can then link to the CSS file from each of your HTML pages.

What are the ways in which we can style our pages?

Adding Styles to HTML Elements These are the three methods of implementing styling information to an HTML document. Inline styles — Using the style attribute in the HTML start tag. Embedded style — Using the <style> element in the head section of the document.


2 Answers

UPDATE:

Please mind that the answer which the questioner marked as accepted cannot be recommended -
don't ever do this!

Any kind of "pre-loading" of CSS files doesn't make any sense, as you should never split up your CSS into several files!

My original answer:

So what is your real question in the end?

In my humble opinion your doing it all wrong - sorry!

Usually an author intends to

  • give a site a consistent look/ appearance
  • keep the maintainability as easy as possible
  • avoid FOUC (flash of unstyled content)
  • minimize number of (HTTP) requests
  • support cache mechanism to reduce bandwidth/ data volume

just to mention some of the most important aspects.

All of them are disregarded by your approach.

As you are using the link element within the body element, I assume you are using HTML5. Because in other HTML versions this would be invalid.

But also in HTML5 I would not rely on this. Have a look at the 2 versions:

  1. http://www.w3.org/html/wg/drafts/html/master/document-metadata.html#the-link-element
  2. http://www.w3.org/html/wg/drafts/html/CR/document-metadata.html#the-link-element

Compare the section (at the top) "Contexts in which this element can be used:".

As the information from the CSS is most needed by the browser to render a page, it should be one of the first things loaded.

Have a look at the article:"How Browsers Work: Behind the scenes of modern web browsers" and especially at the section:"Rendering engines".

So loading another style sheet will force the browser to redo all the work, beside the additional HTTP request, which in particular on GSM connections may cause "trouble" because of the greater latency.

And if each page of your site really has such an amount of individual style rules then I would say it is a "design flaw".

One of the "design principles" is: As much as necessary - as little as possible!

Another (big) advantage of using just one style sheet is that it is cached by the browser after the first load. And as the CSS of a site normally doesn't change too often this is a great advantage which by far outweighs the disadvantage of some more KB to load on first page visit (btw independent of the entry/ landing page)!

Conclusion:
I really cannot recommend to use your approach!

Put all your styles (normalize, basic, media queries, print) in one single file which you load via <link> in the <head> of your document.

That's the best you can do.

like image 62
Netsurfer Avatar answered Oct 23 '22 04:10

Netsurfer


Yes, what you are doing is perfectly valid and common

CSS is perhaps a bad example, but the same principle ( load the last one in via ajax btw )

Like say, images.

We are on page 1 of our website and we know 99.999% of the time our visitors are going to click to page 2, and we know that on page 2 we have some large images to serve, yes, then we may load them silently AFTER page 1 has loaded - getting ready, then the site 'feels' fast as they navigate. A common trick in mobile web applications/sites/

So yes:

It is the same principle for ANY type of file that you may want to 'pre cache' for subsequent requests.

  • Load the page
  • while the visitor is 'reading' the loaded page, pre fetch files/data that you expect they may request next. ( images, page 2 of result data, javascript, and css ). These are loaded via ajax as to not hold up the page 'onload' event firing - a key difference from your example

However, To answer your goal - allow for the loading of the pages to be as fast as possible

Doing this, or any kind of 'pre emptive loading' technique, is minimal to 'speed of delivery' if we are not serving static files from a static server, a cookieless domain , and ultimately a Content Delivery Network.


Achieving the goal of allowing for the loading of the pages to be as fast as possible, is the serving of static files differently from your dynamic content ( php rendered et all )

1) Create a subdomain for these resources ( css, js, images/media ) - static.yourdomain.com

2) Turn off cookies, headers and tune cache headers specifically for this sub domain.

3) Look into using a service like http://cdnify.com/ or www.akamai.com.

These are the performance and speed steps for serving static content. ( hope no suck eggs, just directly related the question and if anyone is unfamiliar with this )

The 'pre emptive loading' techniques are still great, but they are now more related to pre loading data for usability than they are for speed.


Edit/Update:

To clarify 'speed' and 'usability speed'.

  • Speed is judged by software often as when the page 'onload' event fires ( that is why it is important to load these 'pre emptive resources' via ajax.

  • Perceived speed ( usability ) is the how quickly a user can see and interact with the content ( even though the page load event may not have fired ).


Edit/update

In a few areas of the post and in the comments was mentioned the loading of these additional 'pre emptive' resources via javascript/ajax.

The reason is to not delay the page 'onload' event firing.

Many website test speed tools ( yslow, google .. ) use this 'onload' event to judge page speed.

Here we delay the page 'onload' event.

<body>

... page content 

<link rel="stylesheet" href="/nextpage.css"  />
</body>

Here we Load via javascript /some cases Ajax ( page data ) and do not preventing the page load event

<body>
.. page content

  <script>

    window.onload = function () {

       var style   = document.createElement( 'link' );
       style.rel   = 'stylesheet';
       style.type  = 'text/css';
       style.href  = '/nextpage.css';
       document.getElementsByTagName( 'head' )[0].appendChild( style );

   };

   </script>

( this, as a bonus, also gets around the compatibility problems with having a <link> tag within the <body> as discussed in your other threads )

like image 24
Rob Sedgwick Avatar answered Oct 23 '22 05:10

Rob Sedgwick