Maison > interface Web > tutoriel CSS > le corps du texte

Parlons de la façon dont CSS et JS bloquent l'analyse et le rendu du DOM

青灯夜游
Libérer: 2021-05-27 09:58:16
avant
2703 Les gens l'ont consulté

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.

Parlons de la façon dont CSS et JS bloquent l'analyse et le rendu du DOM

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);
  })
}
Copier après la connexion

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>
Copier après la connexion

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;
}
Copier après la connexion

D'accord, pas grand chose à dire, commençons le texte !

CSS

À 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(&#39;div&#39;);
console.log(div);
Copier après la connexion

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

, insérez

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. . CSSDOMPour faire simple, le navigateur analyse

pour générer

, 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 treeCSS

bloque le rendu de la pageCSSEn fait, l'exemple de tout à l'heure l'a déjà illustré. Si

ne bloque pas la page et bloque le rendu, alors.

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. divCSS 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,

et bloquera naturellement le rendu des pages.

CSSCependant, les choses sont toujours bizarres, veuillez regarder cet exemple,

La structure de l'en-tête est la suivante :

<header>
    <link rel="stylesheet" href="/css/sleep3000-common.css">
    <script src="/js/logDiv.js"></script>
</header>
Copier après la connexion
HTMLMais 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

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(&#39;div&#39;);
console.log(div);
Copier après la connexion

其实那个数组操作时没意义的,只是为了让这个JS文件多花执行时间而已。之后把这个文件插入头部,浏览器跑一下。

结果估计大家也能想象得到,浏览器转圈圈一会,这过程中不会有任何东西出现。之后打印出null,再出现一个浅绿色的div。现象就足以说明JS 阻塞 DOM 解析了。其实原因也很好理解,浏览器并不知道脚本的内容是什么,如果先行解析下面的DOM,万一脚本内全删了后面的DOM,浏览器就白干活了。更别谈丧心病狂的document.write。浏览器无法预估里面的内容,那就干脆全部停住,等脚本执行完再干活就好了。

对此的优化其实也很显而易见,具体分为两类。如果JS文件体积太大,同时你确定没必要阻塞DOM解析的话,不妨按需要加上defer或者async属性,此时脚本下载的过程中是不会阻塞DOM解析的。

而如果是文件执行时间太长,不妨分拆一下代码,不用立即执行的代码,可以使用一下以前的黑科技:setTimeout()。当然,现代的浏览器很聪明,它会“偷看”之后的DOM内容,碰到如<link><script><img>等标签时,它会帮助我们先行下载里面的资源,不会傻等到解析到那里时才下载。

浏览器遇到 <script> 标签时,会触发页面渲染

这个细节可能不少看官大人并不清楚,其实这才是解释上面为何JS执行会等待CSS下载的原因。先上例子,HTMLbody的结构如下:

<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>
Copier après la connexion

这个例子也是很极端的例子,但不妨碍它透露给我们很多重要的信息。想象一下,页面会怎样呢?

答案是先浅绿色,再浅灰色,最后浅蓝色。由此可见,每次碰到<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
  • rencontre une balise <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!

Étiquettes associées:
source:juejin.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!