HTML中为什么CSS要写在上面JS要写在下面

本文不涉及什么原理性知识,都是实例的推论,要是一定有和原理相关的那可能就是(可能还不见得对,哈哈哈哈!):

  1. 浏览器的基本渲染流程:构建DOM树 => 构建CSSOM树 => 构建Render树 => 布局Render树 => 绘制Render树
  2. 浏览器的单线程导致解析渲染和js的执行不能并存
  3. 浏览器的解析渲染是同步进行的,不是一口气解析完了再一口气渲染再一口气绘制

为什么CSS要写到文件上方的header里?

因为CSS不阻塞线程吗?其实外链的CSS是阻塞的,只不过不阻塞DOM树的构建,遇到link标签,浏览器会异步加载网络上的CSS资源,并往下加载DOM节点,但是并没有额外的渲染发生,等到资源请求回来,浏览器会整合所有的样式表进行统一的渲染和绘制,防止重绘和回流的发生。

我们来写一个简单的html页面,代码如下:




    
    
    


    
123123

这段文字会等待css加载完才出现

打开弱网运行html,会发生什么?如果CSS什么都不阻塞,是不是会显示一个红边框有渐变色的100px的正方形和下面一段文字,等CSS回来,再把div改变?还是什么都不发生,最后等待CSS回来一口气把页面全部渲染,这样还能减少重绘和回流。

但是实际是这样的:先渲染一个红边框渐变色的正方形,然后加载CSS,等CSS加载完毕后渲染一个压扁的长方形和P标签,最后加载背景图资源。这说明了外链的CSS文件会阻塞页面的绘制。

所以为什么CSS要都写在最前面,因为页面不会中途遇到的CSS资源产生多次绘制,如果一路上没有遇到CSS和JS,页面是一边解析一边渲染,最后一口气绘制的。

为什么JS要写到文件的底部?

因为js的运行是要占用主线程的,也就是在js运行的时候,页面是不进行解析和渲染的,如果js写在最前面,如果不做特殊处理,除了能提供依赖以外和做一些预处理之外,连dom节点都无法捕捉,导致功能受到了很大的限制

我们看下面这一段代码




    
    
    


    
123123
b
c

这段代码在弱网情况下会发生什么?答案是:

  1. 显示一个红边框渐变色北京的正方形div(如果不是弱网这步肉眼观察不到)
  2. 加载CSS,大概2~3s后css加载回来,改变了第一个div的形状,背景色消失,开始执行js的大循环(这里证明js被css阻塞了,但是下面两个div没有被渲染,说明css异步挂载后,本应该执行的dom解析被js阻塞了)
  3. 循环结束,绘制剩下两个div
  4. 加载并绘制第一个div的背景图片

PS: 浏览器的行为很迷(应该是和帧渲染有一定关系,这一帧我正好渲染了,也有可能没有渲染)弱网强网,本页刷新,新标签页打开,开调适的页面和不开调适的页面,渲染的顺序都会有较小概率出现不同,比如强网的时候渲染顺序十分不稳定,有时候会直接出现一个带背景图的压缩div,有时候也会出现渐变色的正方形,然后执行js,再出现后两个div,甚至有时候还能直接出现3个div再执行for循环。

这里补充一下,如果没有标签在a和bc之间插入一个script,也就是把上方代码的删除,结果是:先显示a,script执行完毕再显示bc

顶部CSS+底部JS的优势

再看一段代码,对比前面在body里的CSS文件,如果把CSS写在header里,又会发生什么:




    
    
    
    



    
123123
b
c

按照前面的结论,无论遇到

你可能感兴趣的:(HTML中为什么CSS要写在上面JS要写在下面)