Cet article vous présentera le principe du blocage par CSS et JS de l'analyse et du rendu du DOM. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.
Bonjour~ Chers lecteurs, bonjour à tous. Je suppose que tout le monde a entendu cela essayer de mettre CSS
en tête et JS
en bas, ce qui peut améliorer les performances de la page. Mais pourquoi ? Y avez-vous pensé ? Je le savais depuis longtemps mais je ne savais pas pourquoi. Bien sûr, c'était bien de le mémoriser pour les examens, mais ce serait un gâchis dans l'application réelle. Alors lavez (wang) le cœur (yang) le cuir (bu) le visage (lao) et résumez les résultats récents.
Rappel amical, cet article s'adresse principalement aux débutants. Si vous souhaitez voir la conclusion directement, vous pouvez faire défiler vers le bas~
Puisqu'il est lié à la lecture de fichiers. , c'est sûr Si tu as besoin d'un serveur, je mettrai tous les fichiers sur github, donne-moi une étoile et je serai contente ! La seule chose qui nécessite une explication à la fin
node
est cette fonction :
function sleep(time) { return new Promise(function(res) { setTimeout(() => { res() }, time); }) }
Hmm ! En fait, c’est retardé. Si le nom du fichier CSS
ou JS
a un préfixe tel que sleep3000
, cela signifie que le fichier sera renvoyé après un délai de 3000 millisecondes.
Le fichier HTML
utilisé ci-dessous ressemble à ceci :
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Title</title> <style> div { width: 100px; height: 100px; background: lightgreen; } </style> </head> <body> <div></div> </body> </html>
Je vais y insérer différents JS
et CSS
.
est utilisé à la place de common.css
, qu'il y ait ou non un préfixe, le contenu est comme ceci :
div { background: lightblue; }
D'accord, pas grand chose à dire, commençons le texte !
À propos de CSS
, tout le monde doit savoir que les performances de la balise <link>
seront plus élevées si elle est placée dans la tête. que si <script>
Si <link>
est sur la tête en même temps, ce serait peut-être mieux si <script>
était au dessus. Pourquoi est-ce ? Jetons un coup d'œil à l'impact de CSS
sur DOM
.
CSS
ne bloquera pas l'analyse de DOM
Remarque ! Ce dont nous parlons ici, c'est de l'analyse DOM
. L'exemple de preuve est le suivant. Insérez d'abord <script defer src="/js/logDiv.js"></script>
dans l'en-tête. Le contenu du fichier JS
est :
const div = document.querySelector('div'); console.log(div);
defer
. . Je pense que tout le monde le connaît. MDNCette description est utilisée pour informer le navigateur que le script sera exécuté une fois l'analyse du document terminée et avant le déclenchement de l'événement DOMContentLoaded. La définition de cet attribut garantit que DOM
est imprimé immédiatement après l'analyse. Après div
dans n'importe quelle position du fichier <link rel="stylesheet" href="/css/sleep3000-common.css">
, ouvrez le navigateur, vous pouvez voir que le nœud HTML
est d'abord imprimé, et après environ 3 secondes, un bleu peu profond div
. Cela prouve que DOM
ne bloquera pas l'analyse de div
Bien que CSS
prenne 3 secondes pour télécharger, pendant ce processus, le navigateur n'attendra pas que DOM
termine le téléchargement, mais analysera CSS
de. . CSS
DOM
Pour faire simple, le navigateur analyse
, combine le DOM
généré par DOM Tree
, et enfin forme CSS
, puis restitue la page. On peut voir que dans ce processus, CSS Tree
ne peut pas du tout affecter render tree
, il n'est donc pas nécessaire de bloquer l'analyse CSS
. Cependant, DOM Tree
et DOM
seront combinés en DOM Tree
, donc CSS Tree
bloquera-t-il le rendu de la page ? render tree
CSS
CSS
En fait, l'exemple de tout à l'heure l'a déjà illustré. Si Avant que le fichier ne soit téléchargé, le navigateur affichera un CSS
vert clair, puis le transformera en bleu clair. Cette stratégie du navigateur est en fait très judicieuse. Imaginez que sans cette stratégie, la page afficherait d'abord une apparence originale, puis changerait soudainement d'apparence après le téléchargement de CSS
. L'expérience utilisateur est extrêmement médiocre et le rendu est coûteux. div
CSS
Par conséquent, en fonction de considérations de performances et d'expérience utilisateur, le navigateur tentera de réduire autant que possible le nombre de rendus,
CSS
Cependant, les choses sont toujours bizarres, veuillez regarder cet exemple,
<header> <link rel="stylesheet" href="/css/sleep3000-common.css"> <script src="/js/logDiv.js"></script> </header>
HTML
Mais pensez à ce qui va se passer ? 答案是浏览器会转圈圈三秒,但此过程中不会打印任何东西,之后呈现出一个浅蓝色的div
,再打印出null
。结果好像是CSS
不单阻塞了页面渲染,还阻塞了DOM
的解析啊!稍等,在你打算掀桌子疯狂吐槽我之前,请先思考一下是什么阻塞了DOM
的解析,刚才已经证明了CSS
是不会阻塞的,那么阻塞了页面解析其实是JS
!但明明JS
的代码如此简单,肯定不会阻塞这么久,那就是JS
在等待CSS
的下载,这是为什么呢?
仔细思考一下,其实这样做是有道理的,如果脚本的内容是获取元素的样式,宽高等CSS
控制的属性,浏览器是需要计算的,也就是依赖于CSS
。浏览器也无法感知脚本内容到底是什么,为避免样式获取,因而只好等前面所有的样式下载完后,再执行JS
。因而造成了之前例子的情况。
所以,看官大人明白为何<script>
与<link>
同时在头部的话,<script>
在上可能会更好了么?之所以是可能,是因为如果<link>
的内容下载更快的话,是没影响的,但反过来的话,JS
就要等待了,然而这些等待的时间是完全不必要的。
JS
,也就是<script>
标签,估计大家都很熟悉了,不就是阻塞DOM
解析和渲染么。然而,其中其实还是有一点细节可以考究一下的,我们一起来好好看看。
JS
阻塞 DOM
解析首先我们需要一个新的JS
文件名为blok.js
,内容如下:
const arr = []; for (let i = 0; i < 10000000; i++) { arr.push(i); arr.splice(i % 3, i % 7, i % 5); } const div = document.querySelector('div'); console.log(div);
其实那个数组操作时没意义的,只是为了让这个JS
文件多花执行时间而已。之后把这个文件插入头部,浏览器跑一下。
结果估计大家也能想象得到,浏览器转圈圈一会,这过程中不会有任何东西出现。之后打印出null
,再出现一个浅绿色的div
。现象就足以说明JS
阻塞 DOM
解析了。其实原因也很好理解,浏览器并不知道脚本的内容是什么,如果先行解析下面的DOM
,万一脚本内全删了后面的DOM
,浏览器就白干活了。更别谈丧心病狂的document.write
。浏览器无法预估里面的内容,那就干脆全部停住,等脚本执行完再干活就好了。
对此的优化其实也很显而易见,具体分为两类。如果JS
文件体积太大,同时你确定没必要阻塞DOM
解析的话,不妨按需要加上defer
或者async
属性,此时脚本下载的过程中是不会阻塞DOM
解析的。
而如果是文件执行时间太长,不妨分拆一下代码,不用立即执行的代码,可以使用一下以前的黑科技:setTimeout()
。当然,现代的浏览器很聪明,它会“偷看”之后的DOM
内容,碰到如<link>
、<script>
和<img>
等标签时,它会帮助我们先行下载里面的资源,不会傻等到解析到那里时才下载。
<script>
标签时,会触发页面渲染这个细节可能不少看官大人并不清楚,其实这才是解释上面为何JS
执行会等待CSS
下载的原因。先上例子,HTML
内body
的结构如下:
<body> <div></div> <script src="/js/sleep3000-logDiv.js"></script> <style> div { background: lightgrey; } </style> <script src="/js/sleep5000-logDiv.js"></script> <link rel="stylesheet" href="/css/common.css"> </body>
这个例子也是很极端的例子,但不妨碍它透露给我们很多重要的信息。想象一下,页面会怎样呢?
答案是先浅绿色,再浅灰色,最后浅蓝色。由此可见,每次碰到<script>
标签时,浏览器都会渲染一次页面。这是基于同样的理由,浏览器不知道脚本的内容,因而碰到脚本时,只好先渲染页面,确保脚本能获取到最新的DOM
元素信息,尽管脚本可能不需要这些信息。
综上所述,我们得出这样的结论:
CSS
ne bloque pas l'analyse de DOM
, mais il bloque le rendu de DOM
. JS
bloque DOM
l'analyse, mais le navigateur « jette un coup d'œil » DOM
et télécharge les ressources associées à l'avance. Lorsque le navigateur <script>
sans attribut defer
ou async
, il déclenchera le rendu de la page. Par conséquent, si la ressource CSS
précédente n'a pas été chargée, le navigateur attendra. pour qu'il se charge. Terminez l'exécution du script. Donc, vous comprenez maintenant pourquoi <script>
est mieux placé en bas et <link>
est mieux placé en tête. Si la tête a à la fois <script>
et <link>
, c'est le cas. meilleur Avez-vous mis <script>
au-dessus de <link>
?
Merci d'avoir lu ceci. J'espère que cet article vous sera utile. Si vous avez des avis différents ou meilleurs, n'hésitez pas à m'éclairer ! Merci~
Adresse originale : https://juejin.cn/post/6844903497599549453
Pour plus de connaissances liées à la programmation, veuillez visiter : Vidéo de programmation ! !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!