une - javascript tutorial




La recommandation d'inclure CSS avant JavaScript est-elle invalide? (9)

C'est une question très intéressante. J'ai toujours mis mon CSS <link href="..."> s avant mon JS <script src="..."> s parce que "j'ai lu une fois que c'est mieux." Donc, tu as raison; il est grand temps de faire de la recherche!

J'ai mis en place mon propre harnais de test dans Node (code ci-dessous). Fondamentalement, je:

  • Assurez-vous qu'il n'y avait pas de mise en cache HTTP, donc le navigateur devrait faire un téléchargement complet chaque fois qu'une page est chargée.
  • Pour simuler la réalité, j'ai inclus jQuery et le CSS H5BP (donc il y a une quantité décente de script / CSS à analyser)
  • Mettre en place deux pages - une avec CSS avant le script, une avec CSS après le script.
  • Enregistrement du temps nécessaire à l'exécution du script externe dans <head>
  • Enregistrement du temps nécessaire à l'exécution du script en ligne dans <body> , qui est analogue à DOMReady .
  • Retardé l'envoi de CSS et / ou de script au navigateur par 500ms.
  • Ran le test 20 fois dans les 3 principaux navigateurs.

Résultats

D'abord, avec le fichier CSS retardé de 500ms:

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 583ms  36ms  | 559ms  42ms  | 565ms 49ms
St Dev      | 15ms   12ms  | 9ms    7ms   | 13ms  6ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 584ms  521ms | 559ms  513ms | 565ms 519ms
St Dev      | 15ms   9ms   | 9ms    5ms   | 13ms  7ms

Ensuite, j'ai mis jQuery à retarder de 500ms au lieu du CSS:

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 597ms  556ms | 562ms  559ms | 564ms 564ms
St Dev      | 14ms   12ms  | 11ms   7ms   | 8ms   8ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 598ms  557ms | 563ms  560ms | 564ms 565ms
St Dev      | 14ms   12ms  | 10ms   7ms   | 8ms   8ms

Enfin, j'ai mis jQuery et le CSS à retarder de 500ms:

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 620ms  560ms | 577ms  577ms | 571ms 567ms
St Dev      | 16ms   11ms  | 19ms   9ms   | 9ms   10ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 623ms  561ms | 578ms  580ms | 571ms 568ms
St Dev      | 18ms   11ms  | 19ms   9ms   | 9ms   10ms

Conclusions

Tout d'abord, il est important de noter que je fonctionne sous l'hypothèse que vous avez des scripts situés dans la <head> de votre document (par opposition à la fin du <body> ). Il existe plusieurs arguments concernant la raison pour laquelle vous pouvez lier vos scripts dans <head> à la fin du document, mais cela sort du cadre de cette réponse. Ceci est strictement à savoir si <script> s devrait aller avant <link> s dans <head> .

Dans les navigateurs modernes de DESKTOP, il semble que la liaison à CSS ne procure jamais un gain de performance. Mettre CSS après script vous apporte une quantité triviale de gain lorsque CSS et le script sont retardés, mais vous donne des gains importants lorsque CSS est retardé. (Montré par les last colonnes dans le premier ensemble de résultats.)

Étant donné que la liaison à CSS ne semble pas nuire aux performances mais peut apporter des gains dans certaines circonstances, vous devez lier les feuilles de style externes après avoir lié des scripts externes uniquement sur les navigateurs de bureau si les performances des anciens navigateurs ne sont pas préoccupantes. Lire la suite pour la situation mobile.

Pourquoi?

Historiquement, lorsqu'un navigateur rencontrait une <script> pointant vers une ressource externe, le navigateur cessait d'analyser le code HTML, récupérait le script, l'exécutait, puis continuait à analyser le code HTML. En revanche, si le navigateur rencontrait un <link> pour une feuille de style externe, il continuerait à analyser le code HTML pendant qu'il extrairait le fichier CSS (en parallèle).

D'où le conseil largement répété de mettre les feuilles de style en premier - elles seraient téléchargées en premier, et le premier script à télécharger pourrait être chargé en parallèle.

Cependant, les navigateurs modernes (y compris tous les navigateurs que j'ai testés ci-dessus) ont implémenté l' analyse spéculative , où le navigateur «regarde en avant» dans le HTML et commence à télécharger les ressources avant le téléchargement et l'exécution des scripts.

Dans les anciens navigateurs sans analyse spéculative, la mise en premier des scripts affectera les performances car ils ne seront pas téléchargés en parallèle.

Support du navigateur

L'analyse spéculative a été implémentée pour la première fois en: (avec le pourcentage d'utilisateurs de navigateurs de bureau dans le monde utilisant cette version ou plus en janvier 2012)

  • Chrome 1 (WebKit 525) (100%)
  • IE 8 (75%)
  • Firefox 3.5 (96%)
  • Safari 4 (99%)
  • Opéra 11.60 (85%)

Au total, environ 85% des navigateurs de bureau utilisés aujourd'hui prennent en charge le chargement spéculatif. Mettre des scripts avant CSS aura une pénalité de performance sur 15% des utilisateurs dans le monde ; YMMV basé sur l'audience spécifique de votre site. (Et rappelez-vous que le nombre diminue.)

Sur les navigateurs mobiles, il est un peu plus difficile d'obtenir des chiffres définitifs simplement en raison de l'hétérogénéité du paysage du navigateur mobile et du système d'exploitation. Depuis que le rendu spéculatif a été implémenté dans WebKit 525 (publié en mars 2008), et à peu près tous les navigateurs mobiles valables sont basés sur WebKit, nous pouvons conclure que "la plupart" des navigateurs mobiles devraient le supporter. Selon quirksmode , iOS 2.2 / Android 1.0 utilise WebKit 525. Je n'ai aucune idée de ce que Windows Phone ressemble.

Cependant, j'ai lancé le test sur mon appareil Android 4, et bien que je voyais des chiffres similaires aux résultats du bureau, je l'ai connecté au nouveau débogueur fantastique dans Chrome pour Android, et l'onglet Réseau montrait que le navigateur était en attente de téléchargement le CSS jusqu'à ce que JavaScripts soit complètement chargé - en d'autres termes, même la dernière version de WebKit pour Android ne semble pas prendre en charge l'analyse spéculative. Je soupçonne qu'il pourrait être éteint en raison de la CPU, de la mémoire et / ou des contraintes réseau inhérentes aux appareils mobiles.

Code

Pardonnez la négligence - c'était Q & D.

app.js

var express = require('express')
, app = express.createServer()
, fs = require('fs');

app.listen(90);

var file={};
fs.readdirSync('.').forEach(function(f) {
    console.log(f)
    file[f] = fs.readFileSync(f);
    if (f != 'jquery.js' && f != 'style.css') app.get('/' + f, function(req,res) {
        res.contentType(f);
        res.send(file[f]);
    });
});


app.get('/jquery.js', function(req,res) {
    setTimeout(function() {
        res.contentType('text/javascript');
        res.send(file['jquery.js']);
    }, 500);
});

app.get('/style.css', function(req,res) {
    setTimeout(function() {
        res.contentType('text/css');
        res.send(file['style.css']);
    }, 500);
});


var headresults={
    css: [],
    js: []
}, bodyresults={
    css: [],
    js: []
}
app.post('/result/:type/:time/:exec', function(req,res) {
    headresults[req.params.type].push(parseInt(req.params.time, 10));
    bodyresults[req.params.type].push(parseInt(req.params.exec, 10));
    res.end();
});

app.get('/result/:type', function(req,res) {
    var o = '';
    headresults[req.params.type].forEach(function(i) {
        o+='\n' + i;
    });
    o+='\n';
    bodyresults[req.params.type].forEach(function(i) {
        o+='\n' + i;
    });
    res.send(o);
});

css.html

<!DOCTYPE html>
<html>
    <head>
        <title>CSS first</title>
        <script>var start = Date.now();</script>
        <link rel="stylesheet" href="style.css">
        <script src="jquery.js"></script>
        <script src="test.js"></script>
    </head>
    <body>
        <script>document.write(jsload - start);bodyexec=Date.now()</script>
    </body>
</html>

js.html

<!DOCTYPE html>
<html>
    <head>
        <title>CSS first</title>
        <script>var start = Date.now();</script>
        <script src="jquery.js"></script>
        <script src="test.js"></script>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <script>document.write(jsload - start);bodyexec=Date.now()</script>
    </body>
</html>

test.js

var jsload = Date.now();


$(function() {
    $.post('/result' + location.pathname.replace('.html','') + '/' + (jsload - start) + '/' + (bodyexec - start));
});

jquery.js était jquery-1.7.1.min.js

Dans d'innombrables endroits en ligne, j'ai vu la recommandation d'inclure CSS avant JavaScript. Le raisonnement est généralement, de cette forme :

Quand il s'agit de commander votre CSS et JavaScript, vous voulez que votre CSS passe en premier. La raison en est que le thread de rendu a toutes les informations de style dont il a besoin pour rendre la page. Si le JavaScript inclut d'abord, le moteur JavaScript doit tout analyser avant de passer à l'ensemble de ressources suivant. Cela signifie que le thread de rendu ne peut pas afficher complètement la page, car il ne possède pas tous les styles dont il a besoin.

Mon test actuel révèle quelque chose de très différent:

Mon harnais de test

J'utilise le script Ruby suivant pour générer des délais spécifiques pour diverses ressources:

require 'rubygems'
require 'eventmachine'
require 'evma_httpserver'
require 'date'

class Handler  < EventMachine::Connection
  include EventMachine::HttpServer

  def process_http_request
    resp = EventMachine::DelegatedHttpResponse.new( self )

    return unless @http_query_string

    path = @http_path_info
    array = @http_query_string.split("&").map{|s| s.split("=")}.flatten
    parsed = Hash[*array]

    delay = parsed["delay"].to_i / 1000.0
    jsdelay = parsed["jsdelay"].to_i

    delay = 5 if (delay > 5)
    jsdelay = 5000 if (jsdelay > 5000)

    delay = 0 if (delay < 0) 
    jsdelay = 0 if (jsdelay < 0)

    # Block which fulfills the request
    operation = proc do
      sleep delay 

      if path.match(/.js$/)
        resp.status = 200
        resp.headers["Content-Type"] = "text/javascript"
        resp.content = "(function(){
            var start = new Date();
            while(new Date() - start < #{jsdelay}){}
          })();"
      end
      if path.match(/.css$/)
        resp.status = 200
        resp.headers["Content-Type"] = "text/css"
        resp.content = "body {font-size: 50px;}"
      end
    end

    # Callback block to execute once the request is fulfilled
    callback = proc do |res|
        resp.send_response
    end

    # Let the thread pool (20 Ruby threads) handle request
    EM.defer(operation, callback)
  end
end

EventMachine::run {
  EventMachine::start_server("0.0.0.0", 8081, Handler)
  puts "Listening..."
}

Le mini serveur ci-dessus me permet de définir des retards arbitraires pour les fichiers JavaScript (serveur et client) et des retards CSS arbitraires. Par exemple, http://10.0.0.50:8081/test.css?delay=500 me donne un délai de 500 ms pour transférer le CSS.

J'utilise la page suivante pour tester.

<!DOCTYPE html>
<html>
  <head>
      <title>test</title>
      <script type='text/javascript'>
          var startTime = new Date();
      </script>
      <link href="http://10.0.0.50:8081/test.css?delay=500" type="text/css" rel="stylesheet">
      <script type="text/javascript" src="http://10.0.0.50:8081/test2.js?delay=400&amp;jsdelay=1000"></script> 
  </head>
  <body>
    <p>
      Elapsed time is: 
      <script type='text/javascript'>
        document.write(new Date() - startTime);
      </script>
    </p>    
  </body>
</html>

Lorsque j'inclus d'abord le CSS, la page prend 1.5 secondes pour le rendu:

Lorsque j'inclus d'abord le code JavaScript, la page prend 1,4 secondes à afficher:

J'obtiens des résultats similaires dans Chrome, Firefox et Internet Explorer. Dans Opera cependant, la commande n'a tout simplement pas d'importance.

Ce qui semble se passer, c'est que l'interpréteur JavaScript refuse de démarrer tant que tout le CSS n'est pas téléchargé. Donc, il semble que l'inclusion de JavaScript en premier est plus efficace car le thread JavaScript obtient plus de temps d'exécution.

Ai-je manqué quelque chose, est-ce que la recommandation de placer CSS inclut avant JavaScript inclut pas correct?

Il est clair que nous pourrions ajouter async ou utiliser setTimeout pour libérer le thread de rendu ou mettre le code JavaScript dans le pied de page, ou utiliser un loader JavaScript. Le point ici concerne l'ordre des bits JavaScript et des bits CSS essentiels dans la tête.


Il y a deux raisons principales de mettre CSS avant JavaScript.

  1. Les anciens navigateurs (Internet Explorer 6-7, Firefox 2, etc.) bloqueraient tous les téléchargements suivants lorsqu'ils commenceraient à télécharger un script. Donc, si vous avez a.js suivi de b.css ils sont téléchargés séquentiellement: d'abord a puis b. Si vous avez b.css suivi de a.js ils sont téléchargés en parallèle pour que la page se charge plus rapidement.

  2. Rien n'est rendu jusqu'à ce que toutes les feuilles de style soient téléchargées - ceci est vrai dans tous les navigateurs. Les scripts sont différents: ils bloquent le rendu de tous les éléments DOM situés sous la balise de script de la page. Si vous placez vos scripts dans HEAD, cela signifie que la page entière est bloquée du rendu jusqu'à ce que toutes les feuilles de style et tous les scripts soient téléchargés. Bien qu'il soit judicieux de bloquer tout rendu pour les feuilles de style (afin d'obtenir le style correct la première fois et d'éviter le flash FOUC), cela n'a aucun sens de bloquer le rendu de la page entière pour les scripts. Souvent, les scripts n'affectent aucun élément DOM ou seulement une partie des éléments DOM. Il est préférable de charger les scripts aussi bas que possible sur la page, ou mieux encore de les charger de manière asynchrone.

C'est amusant de créer des exemples avec Cuzillion . Par exemple, cette page contient un script dans HEAD, de sorte que la page entière est vide jusqu'à ce que le téléchargement soit terminé. Cependant, si nous déplaçons le script à la fin du bloc BODY, l'en-tête de la page s'affiche car ces éléments DOM se trouvent au-dessus de la balise SCRIPT, comme vous pouvez le voir sur cette page .


Je ne soulignerais pas trop les résultats que vous avez, je crois que c'est subjectif, mais j'ai une raison de vous expliquer qu'il vaut mieux mettre en CSS avant js.

Au cours du chargement de votre site Web, il y a deux scénarios que vous verriez:

CAS 1: écran blanc> site Web non créé> site Web style> interaction> site Web stylé et interactif

CAS 2: écran blanc> site Web non créé> interaction> site Web stylé> site Web stylisé et interactif

Honnêtement, je ne peux pas imaginer que quelqu'un choisisse le cas 2. Cela voudrait dire que les visiteurs utilisant des connexions Internet lentes seront confrontés à un site Web non créé, qui leur permet d'interagir avec lui en utilisant Javascript (puisque c'est déjà chargé). En outre, le temps passé à regarder un site Web non stylisé serait maximisé de cette façon. Pourquoi quelqu'un voudrait-il cela?

Cela fonctionne aussi mieux que les états jQuery

"Lorsque vous utilisez des scripts qui s'appuient sur la valeur des propriétés de style CSS, il est important de référencer des feuilles de style externes ou d'incorporer des éléments de style avant de référencer les scripts".

Lorsque les fichiers sont chargés dans le mauvais ordre (d'abord JS, puis CSS), tout code Javascript s'appuyant sur les propriétés définies dans les fichiers CSS (par exemple la largeur ou la hauteur d'un div) ne sera pas chargé correctement. Il semble qu'avec un mauvais ordre de chargement, les propriétés correctes soient 'parfois' connues de Javascript (peut-être est-ce dû à une condition de concurrence?). Cet effet semble plus grand ou plus petit selon le navigateur utilisé.


Je ne suis pas vraiment sûr de la façon dont votre test 'rend' le temps en utilisant votre script java. Cependant, considérez ceci

Une page sur votre site est 50k ce qui n'est pas déraisonnable. L'utilisateur est sur la côte est alors que votre serveur est à l'ouest. MTU n'est certainement pas 10k donc il y aura quelques voyages avant et en arrière. Cela peut prendre une demi-seconde pour recevoir votre page et vos feuilles de style. Typiquement (pour moi) javascript (via jquery plugin et autres) sont beaucoup plus que CSS. Theres aussi ce qui se passe quand votre connexion internet étouffe à mi-chemin sur la page mais laisse ignorer cela (il m'arrive de temps en temps et je crois que le rendu css mais je ne suis pas sûr à 100%).

Puisque css est en tête, il peut y avoir des connexions supplémentaires pour l'obtenir, ce qui signifie qu'il peut potentiellement finir avant que la page ne le fasse. Quoi qu'il en soit, pendant le type que prend le reste de la page et les fichiers javascript (ce qui représente beaucoup plus d'octets), la page n'est pas nommée, ce qui rend le site / connexion lent.

MÊME SI l'interprète JS refuse de démarrer tant que le CSS n'est pas fait, le temps de télécharger le code javascript surtout quand il est loin du serveur est en train de couper en temps css ce qui rendra le site pas joli.

C'est une petite optimisation mais c'est la raison pour cela.


La recommandation d'inclure CSS avant JavaScript est-elle invalide?

Pas si vous le traitez comme simplement une recommandation. Mais si vous le traitez comme une règle absolue, oui, c'est invalide.

De https://developer.mozilla.org/en-US/docs/Web/Reference/Events/DOMContentLoaded

Les chargements de <link rel="stylesheet" ...> bloquent l'exécution du script, donc si vous avez un <script> après un <link rel="stylesheet" ...> la page ne terminera pas l'analyse - et DOMContentLoaded ne se déclenchera pas tant que la feuille de style n'est pas chargée.

Il semble que vous ayez besoin de savoir sur quoi repose chaque script et de vous assurer que l'exécution du script est retardée jusqu'à la fin du bon événement. Si le script ne repose que sur le DOM, il peut reprendre dans ondomready / domcontentloaded, s'il dépend des images à charger ou des feuilles de style à appliquer, puis si je lis correctement la référence ci-dessus, ce code doit être différé jusqu'à l'événement onload.

Je ne pense pas qu'une taille de chaussette s'adapte à tous, même si c'est la façon dont ils sont vendus et je sais que la taille d'une chaussure ne convient pas à tous. Je ne pense pas qu'il existe une réponse définitive à laquelle charger d'abord, les styles ou les scripts. Il s'agit plutôt d'une décision au cas par cas de ce qui doit être chargé dans quel ordre et de ce qui peut être différé jusqu'à ce qu'il ne soit plus sur le «chemin critique».

Pour parler à l'observateur qui a commenté qu'il est préférable de retarder la capacité des utilisateurs à interagir jusqu'à ce que la feuille est jolie. Il y a beaucoup d'entre vous là-bas et vous ennuyez vos homologues qui se sentent le contraire. Ils sont venus sur un site pour accomplir un but et retarder leur capacité à interagir avec un site en attendant que les choses qui n'ont pas d'importance pour finir le chargement soient très frustrantes. Je ne dis pas que vous avez tort, mais seulement que vous devriez savoir qu'il existe une autre faction qui ne partage pas votre priorité.

Cette question s'applique particulièrement à toutes les annonces placées sur des sites Web. J'adorerais que les auteurs du site ne fassent que des divs d'espace réservé pour le contenu de l'annonce et s'assurent que leur site est chargé et interactif avant d'injecter les annonces dans un événement onload. Même dans ce cas, j'aimerais que les annonces soient chargées en série plutôt que toutes en même temps, car elles ont un impact sur ma capacité à faire défiler le contenu du site pendant le chargement des annonces. Mais ce n'est que le point de vue d'une personne.

  • Connaissez vos utilisateurs et ce qu'ils apprécient.
  • Connaissez vos utilisateurs et quel environnement de navigation ils utilisent.
  • Sachez ce que chaque fichier fait et quels sont ses pré-requis. Tout faire fonctionner aura préséance sur la vitesse et la beauté.
  • Utilisez des outils qui vous montrent la ligne du temps du réseau lors du développement.
  • Testez dans chacun des environnements que vos utilisateurs utilisent. Il peut être nécessaire de dynamiquement (côté serveur, lors de la création de la page) modifier l'ordre de chargement en fonction de l'environnement des utilisateurs.
  • En cas de doute, modifiez l'ordre et mesurez à nouveau.
  • Il est possible que les styles et les scripts de mélange dans l'ordre de chargement soient optimaux; pas tous, puis tous les autres.
  • Expérimentez pas seulement quel ordre pour charger les fichiers mais où. Tête? Dans le corps? Après le corps? DOM Prêt / Chargé? Chargé?
  • Considérez les options asynchrones et différées, le cas échéant, afin de réduire le délai net que l'utilisateur subira avant de pouvoir interagir avec la page. Testez pour déterminer s'ils aident ou blessent.
  • Il y aura toujours des compromis à prendre en compte lors de l'évaluation de l'ordre de chargement optimal. Pretty vs. Responsive étant juste un.

Nous devons garder à l'esprit que les nouveaux navigateurs ont travaillé sur leurs moteurs Javascript, leurs analyseurs syntaxiques, etc., optimisant les problèmes de code et de balisage communs de telle sorte que les problèmes rencontrés dans les anciens navigateurs tels que <= IE8 ne sont plus pertinents. En ce qui concerne le balisage, mais aussi l'utilisation de variables JavaScript, de sélecteurs d'éléments, etc. Je peux voir dans un avenir pas si lointain une situation où la technologie a atteint un point où la performance n'est plus vraiment un problème.


Voici un résumé de toutes les réponses majeures ci-dessus (ou peut-être ci-dessous plus tard :)

Pour les navigateurs modernes, mettez les css partout où vous le souhaitez. Ils analyseraient votre fichier html (qu'ils appellent l' analyse spéculative ) et commenceraient à télécharger css en parallèle avec l'analyse html.

Pour les anciens navigateurs, continuez à mettre les CSS sur le dessus (si vous ne voulez pas montrer une page nue mais interactive d'abord).

Pour tous les navigateurs, placez le javascript le plus loin possible sur la page, car cela interrompra l'analyse de votre code html. De préférence, téléchargez-le de manière asynchrone (c.-à-d. Appel ajax)

Il y a aussi quelques résultats expérimentaux pour un cas particulier qui prétend mettre le javascript en premier (contrairement à la sagesse traditionnelle de mettre CSS en premier) donne de meilleures performances mais il n'y a pas de raisonnement logique et manque de validation concernant l'applicabilité généralisée. ignorez-le pour le moment.

Donc, pour répondre à la question: Oui. La recommandation d'inclure le CSS avant JS est invalide pour les navigateurs modernes. Mettez CSS où vous voulez, et mettez JS vers la fin, si possible.


Vos tests ont-ils été effectués sur votre ordinateur personnel ou sur un serveur Web? C'est une page blanche, ou est-ce un système en ligne complexe avec des images, des bases de données, etc.? Vos scripts exécutent-ils une simple action d'événement de survol ou sont-ils un composant essentiel de la manière dont votre site Web interagit avec l'utilisateur? Il y a plusieurs choses à considérer ici, et la pertinence de ces recommandations deviennent presque toujours des règles lorsque vous vous lancez dans le développement web de haut niveau.

Le but de la règle «mettre les feuilles de style en haut et les scripts en bas» est que, en général, c'est le meilleur moyen d'obtenir un rendu progressif optimal, ce qui est essentiel à l'expérience de l'utilisateur.

Tout le reste mis à part: en supposant que votre test est valide, et que vous produisez vraiment des résultats contraires aux règles populaires, cela ne vous surprendra pas vraiment. Chaque site Web (et tout ce qu'il faut pour que l'ensemble apparaisse sur l'écran d'un utilisateur) est différent et Internet évolue constamment.


Mis à jour le 2017-12-16

Je n'étais pas sûr des tests dans OP. J'ai décidé d'expérimenter un peu et j'ai fini par détruire certains des mythes.

Synchronous <script src...> bloquera le téléchargement des ressources en dessous jusqu'à ce qu'il soit téléchargé et exécuté

Ce n'est plus vrai . Jetez un oeil à la cascade générée par Chrome 63:

<head>
<script src="//alias-0.redacted.com/payload.php?type=js&amp;delay=333&amp;rand=1"></script>
<script src="//alias-1.redacted.com/payload.php?type=js&amp;delay=333&amp;rand=2"></script>
<script src="//alias-2.redacted.com/payload.php?type=js&amp;delay=333&amp;rand=3"></script>
</head>

<link rel=stylesheet> ne bloque pas le téléchargement et l'exécution des scripts en dessous

C'est incorrect . La feuille de style ne bloque pas le téléchargement mais bloque l'exécution du script ( petite explication ici ). Jetez un oeil à la charte de performance générée par Chrome 63:

<link href="//alias-0.redacted.com/payload.php?type=css&amp;delay=666" rel="stylesheet">
<script src="//alias-1.redacted.com/payload.php?type=js&amp;delay=333&amp;block=1000"></script>

Gardant ce qui précède en tête, les résultats dans OP peuvent être expliqués comme suit:

CSS d'abord:

CSS Download  500ms:<------------------------------------------------>
JS Download   400ms:<-------------------------------------->
JS Execution 1000ms:                                                  <-------------------------------------------------------------------------------------------------->
DOM Ready   @1500ms:                                                                                                                                                      ◆

JS Premier:

JS Download   400ms:<-------------------------------------->
CSS Download  500ms:<------------------------------------------------>
JS Execution 1000ms:                                        <-------------------------------------------------------------------------------------------------->
DOM Ready   @1400ms:                                                                                                                                            ◆




performance