1,CSS和JS在网页中的放置顺序是怎样的?
网站加载的整个完整过程是:1、首先浏览器从服务器接收到html代码,然后开始解析html。2、构件DOM树(根据Html代码自顶向下进行构件),并且在同时构件渲染树。3、遇到js文件加载执行,将阻塞DOM树的构建,遇到css文件,将阻塞渲染树的构建。(script标签中的defer属性:构建DOM树的过程和js文件的加载异步(并行)进行,但是Js文件执行需要在DOM树构建完成之后。
script标签中的async属性:构建DOM树、渲染树的过程和js文件的加载和执行异步(并行)进行。)
从以上过程可以知道,当Js文件放在head中时,浏览器构建DOM树的时候遇到Js文件加载会阻塞,也就是说,浏览器不会加载body中的标签,一旦这个Js文件的数量和内容都比较大,那么就会造成刚刚遇到的情况,就不会给用户一个十分良好的可视化回馈,而在前端开发中,给予用户的可视化回馈是十分重要的。
综上,script标签最好放在</body>标签的前面 ,因为放在所有body中的后面就不会出现网页加载时出现空白的情况,可以持续的给用户提供视觉反馈,同时在有些情况下,会降低错误的发生。
而css标签应该放在<head></head>标签之间,因为如果放在</body>标签的前面,那么当DOM树构建完成了,渲染树才构建,那么当渲染树构建完成,浏览器不得不在重新渲染整个页面,这样就造成了资源的浪费,效率不高。
2,解释白屏和FOUC
白屏:
首先要了解一下chrome和IE浏览器的渲染机制。
1.解析HTML标签构建DOM树;
2.解析CSS构建CSSOM树;
3.把这两者组合成渲染树,根据渲染树进行布局,计算每个节点,再绘制到屏幕上。
如果把样式放在文档底部,浏览器会等HTML和CSS完全加载完成之后再绘制到屏幕上去,譬如我们打开某些国外的网站可能出现加载时间过长,页面会出现白屏,而不是内容逐步展现。
FOUC:
如果把样式放在底部,对于FireFox浏览器,会逐步加载无样式的内容,等CSS加载完成之后突然展现样式。
这是由于FireFox的渲染逻辑是解析HTML就会直接画到页面上,这时你会看到没有样式的内容,CSS再通过不断的解析将页面重绘一遍,也就是闪烁一下突然展现样式,这就是FOUC。
3,async和defer的作用是什么?有什么区别
作用
defer:用于开启新的线程下载脚本文件,并使脚本在文档解析完成后执行。
async:新增属性,用于异步下载脚本文件,下载完毕立即解释执行代码。
区别
一、<script src="script.js"></script>
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
二、<script async src="script.js"></script>
有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。
三、<script defer src="myscript.js"></script>
有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。
4,简述网页的渲染机制
上图为主流两种主流内核的渲染主流程
虽然 Webkit 和 Gecko 使用的术语略有不同,但整体流程是基本相同的。
Gecko 将视觉格式化元素组成的树称为“框架树”。每个元素都是一个框架。Webkit 使用的术语是“呈现树”,它由“呈现对象”组成。对于元素的放置,Webkit 使用的术语是“布局”,而 Gecko 称之为“重排”。对于连接 DOM 节点和可视化信息从而创建呈现树的过程,Webkit 使用的术语是“附加”。有一个细微的非语义差别,就是 Gecko 在 HTML 与 DOM 树之间还有一个称为“内容槽”的层,用于生成 DOM 元素。
根据上图,依次介绍每一步
Html、Style Sheets、Script加载
当我们的浏览器获得html文件后,会自上而下的加载,并在加载过程中进行解析和渲染。 加载说的就是获取资源文件的过程,如果在加载的过程中,遇到外部css文件和图片,浏览器会另外发出一个请求,来获取css文件和相应的图片,这个请求是异步的,并不会影响html文件。 但是如果遇到javascript文件,html文件会挂起渲染的线程,等待javascript加载完毕后,html文件再继续渲染。
为什么html需要等待javascript呢?因为javascript可能会修改DOM,导致后续的html资源白白加载,所以html必须等待javascript文件加载完毕后,再继续渲染。这也就是为什么javascript文件要写在底部body标签前的原因。构造树
html的渲染过程就是将html代码按照深度优先遍历来生成DOM树。 css文件下载完后也会进行渲染,生成相应的CSSOM。 当所有的css文件下载完且所有的CSSOM构建结束后,就会和DOM一起生成Render TreeDOM: Document Object Model,浏览器将HTML解析成树形的数据结构,简称DOMCSSOM: CSS Object Model,浏览器将CSS解析成树形的数据结构,简称CSSOM。Render Tree: DOM和CSSOM合并后生成Render Tree,如下图:
- layout和reflow
计算每个Frame(也就是每个Element)的位置,这又叫layout和reflow过程。
Repaint——屏幕的一部分要重画,比如某个CSS的背景色变了。但是元素的几何尺寸没有变。
Reflow——意味着元件的几何尺寸变了,我们需要重新验证并计算Render Tree。是Render Tree的一部分或全部发生了变化。这就是Reflow,或是Layout。(HTML使用的是flow based layout,也就是流式布局,所以,如果某元件的几何尺寸发生了变化,需要重新布局,也就叫reflow)reflow 会从<html>这个root frame开始递归往下,依次计算所有的结点几何尺寸和位置,在reflow过程中,可能会增加一些frame,比如一个文本字符串必需被包装起来。