Delete Javascript and Render Lock CSS?

Asked

Viewed 8,777 times

13

Analyzing link in Pagespeed occurred the following warning

Delete Javascript and CSS from blocking rendering content above the edge

Basic layout

 <!DOCTYPE html>
 <html lang=pt-br>
 <head><meta charset=utf-8>
 <title>TESTE</title>
 <meta name=viewport content="width=device-width, initial-scale=1">
 <link rel="shortcut icon" href=favicon.ico>
 <link rel=stylesheet href="style.css">
 </head>
 <body>
 <div class=header>
 <div class=container>
 <h1 class=header-heading>Titulo</h1>
 </div>
 </div>
 <div class=nav-bar>
 <div class=container>
 <ul class=nav>
 <li><a href="#">menu1</a></li>
 <li><a href="#">menu2</a></li>
 <li><a href="#">menu3</a></li>
 </ul>
 </div>
 </div>
 <div class=content>
 <div class=container>
 <div class=main>
 <h1>Page title</h1>
 <hr>
 <h1>Heading level 1</h1>
 </div></div></div>
 </body>
 </html>
  • 1

    But you cannot put the other files at the bottom of the page after Jquery?

  • @Renan If I call jquery at first it works, only not valid in Pagespeed. At the end of the page as Google recommends the page does not load as expected, so I tried to delay the upload but it did not work understood?

  • I understood, but what I asked was: Can’t you put the files that depend on jQuery at the bottom of the page too? After it, for example: <script src='jquery.js'></script> <script src='scriptQueDependeDoJquery.js'></script>.

  • (Function($){ $('#display'). on('click', Function(){ $('. menu'). toggleClass('Hidden'); }); })(jQuery) ---> that part is to show the menu in the layout if it gets down in the footer nothing appears

  • Did you ever test my answer? Did you get past Pagespeed?

  • @Guilhermenascimento managed to put an onload inside the js and put to run at the end of the page and it worked

  • The location I found with an answer that helped a lot about rendering was in this article http://blogmarketingonline.com.br/dica-howto eliminate javascript-e-css-lock-of-rendering/

  • puts the page in .php, then add the style tag inside the head, and inside the tag, put a php <?php file_get_contents("url_do_css"); ?> only with the main css, after that pass all other css and javascript files to after the closing of the html :D tag this passes its result to 100/100

Show 3 more comments

2 answers

10

Javascript

This makes the page disappear because one is missing </script> or because of the document.write within onload:

<script>
var async;
function tempo() {
async = setTimeout(carregar, 2000);
}
function carregar() {
document.write(unescape("%3Cscript type='text/javascript' src='jquery.js'%3E %3C/script%3E"));
}

<body onload="tempo()">

don’t use the document.write, use the document.body.appendChild:

<script>
window.onload = function() {
    var js = document.createElement("script");
    js.src = "js/jquery.js";
    js.async = true;
    document.body.appendChild(js);
};
</script>
</head>
<body>

Something else you can do simply like this, because even if you depend on jQuery to be loaded before it would still not work, because you will be pressing in async, so do so (due to using async it is not necessary to go inside <body> can put inside <head> even):

<script>
//Esta função carrega os arquivos javascript
function loadJs(url, callback)
{
    var added = false, js = document.createElement("script");

    //Verifica se o callback é uma função
    if (typeof callback === "function") {
        var isReady = false;

        //Executa se for carregado no onload ou readystatechange
        function readyExec()
        {
              if (isReady) return;

             //Bloqueia execução repetida do callback
             isReady = true;

             //Chama o callback
             callback();
        }

        js.onload = readyExec;

        /* Internet explorer (http://stackoverflow.com/q/17978255/1518921) */
        js.onreadystatechange = function() {
            if (js.readyState === "complete" ||
                js.readyState === "loaded")
            {
                readyExec();
            }
        };
    }

    js.async = true;
    js.src = url;

    function trigger()
    {
         if (added) return;

         added = true;

         document.body.appendChild(js);
    }

    if (document.readyState !== "loading") {
        trigger();
    } else {
        document.addEventListener("DOMContentLoaded", trigger);
    }
}

/*
Coloque desta maneira pra carregar primeiro o jquery,
depois de carregar ele carrega os demais arquivos, pois
geralmente precisamos do jquery por alguma função nos
outros arquivos
*/

loadJs("js/jquery.min.js", function() {
    loadJs("js/plugin1.js");
    loadJs("js/plugin2.js");
    loadJs("js/outros-scripts.js");
});
</script>

CSS

Already the CSS we can do this way according to the link http://keithclark.co.uk/articles/loading-css-without-blocking-render/ quote:

<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'">
<noscript><link rel="stylesheet" href="css.css"></noscript>

However this method does not seem to work on Android below 4.4 and some browsers seems to still have rendering lock problem when there is the none, then you could try something like this:

<script>
function loadCss(css) {
    var added = false;

    function trigger()
    {
        if (added) return;

        added = true;

        var css = document.createElement("link");

        css.onload = function() {
            document.body.appendChild(css);
        };

        css.rel = "stylesheet";
        css.src = css;
    }

    if (document.readyState !== "loading") {
        trigger();
    } else {
        document.addEventListener("DOMContentLoaded", trigger);
    }
}

loadCss("css/seu_css.css");
loadCss("css/seu_outro_css.css");
</script>

Extra tips

Something important to do is to combine CSS files into a single file (the same goes for JS), will depend on the language or back-end technology, follow some useful tools/plugins to automate this:

Apart from this it is very worth using cache for the static files and also the code 304 HTTP status, see more details here:

  • I made the code on top of js and generated the following error; Uncaught Typeerror: Cannot read Property 'appendchild' of null What could be?

  • 1

    @Hugonascement both revised codes

7

Resource loading optimization is something very, very complicated, depending on the state of the system and the goal you want to achieve.

It’s not very clear to me your goal, that is, if you just want to get your page through on a tool or if you really want to improve the user experience on the system, which will depend a lot on how the system works.

Defining objectives and priorities

In general terms, if you have an HTML generated dynamically by some language on the server side, you may want to show this information as quickly as possible, without pauses for script execution or CSS rendering, and postpone it until later. This can be done because the user can read screen information, but on average, it will take a second or more to interact with the screen, so code that adds events and other features can wait a while to give a sense of fluidity in loading.

However, this is not always true. Often some critical features need to be present at all times and it’s up to developers to decide which features go in synchronously and which can be postponed asynchronously or even later.

Techniques to improve CSS performance

CSS is usually not the problem because it is already loaded asynchronously.

However, sometimes it can become a problem when the Assets get too big.

The best way I know how to optimize this is to separate out what is essential and put at the top of the page and leave what is not essential for later or to be uploaded asynchronously.

In addition, specific styles that serve only one page can be placed inline or in separate styles.

A good organization would be like this:

  1. Common style for the whole system
  2. Specific style for the page
  3. User-specific style, if any

Anyway, here organization is everything.

This is because you don’t want to postpone the loading of CSS too much, because in general it is something that is missing in the interface.

It is important to remember that a good organization improves the use of the cache by both the browser and the CDN, after all, you separate what changes more than what changes less. This helps your site to have a shorter loading and rendering time, taking just a little longer at first access.

Techniques to improve Javascript performance

Script optimization, in addition to organization, requires a deeper knowledge of the many options available and how browsers work.

Ideally, you want scripts to start loading as soon as possible, but only run, pausing the page, after critical content has already been displayed.

A simple way to do this is by using the attributes async and defer that respectively:

  • Execute loaded scripts as soon as downloaded in any order (async)
  • Run the loaded scripts after finished displaying the page in the order they appear on the page (defer)

Which is the best? Depends. async is best when you want the functionality added by the script to be present as soon as possible, probably something critical. defer is better for something not worth pausing page rendering.

But say that only use such attributes in your tags <script> is to be very simplistic.

Difficulties in asynchronous scripts

The problems start because inline scripts cannot be asynchronous or deferred.

Therefore, if they depend on some included external source script you need some mechanism for them to run only when such dependencies are satisfied.

The same goes for asynchronous scripts, which can run in any order.

A simplistic way to solve the problem is to use the event window.onload. But it has a serious problem with this approach: it postpones everything to the end, which means that even critical features will have to wait for everything on the page to load.

A better engine is to write your modular Javascript, using standards such as AMD, ES6, Systemjs. Javascript modules are usually defined in terms of what they define (define) and what they depend on (require).

So you add a little Loader script at the beginning of the page (synchronous) which is able to identify when the dependencies of a certain script are satisfied and executes it as soon as possible.

A Loader script does not necessarily mean that it will download the scripts on demand, but that it keeps a record of the modules present on the page and manages to know when they can be run.

Inside the modules, you can still add events onload to postpone the execution of what is not so important.

Or you can still use the mode Lazy more aggressive, which is to load the code of a functionality only when it is activated by the user. For example, imagine that on your system there is a complex Popup window open when the user clicks on a button that is present on all pages. You do not want the code to be loaded on all pages, because the window is not always used. Then you can upload the code and styles used in the popup inside the event click button. The first time the user clicks, it will take a little longer to open, until the Assets cache, but will allow the site to be faster overall.

In your case, which doesn’t seem to be many scripts, I would turn all of them into AMD modules and thus use the async or defer in all scripts.

If you have inline scripts that cannot transform into a module, a technique to postpone their execution is to change the type, example:

<script type="delay/javascript">

And then you create a module that evaluates the contents of these using eval (it’s not a sin when you know what you’re doing).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.