网页是什么
网页 = Html+CSS+JavaScript
Html:网页元素内容
CSS:控制网页样式
JavaScript:操作网页内容,实现功能或者效果
JavaScirpt 发展历史
使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>标题</title>
<link href="index.css" rel="stylesheet">
<style>
body{
background: red;
}
</style>
</head>
<body>
<p>
</p>
<script src="index.js"></script>
<script>
alert(1);
</script>
</body>
</html>
浏览器渲染机制
- 解析 HTML 标签, 构建 DOM 树
- 解析 CSS 标签, 构建 CSSOM 树
- 把 DOM 和 CSSOM 组合成 渲染树 (render tree)
- 在渲染树的基础上进行布局, 计算每个节点的几何结构
- 把每个节点绘制到屏幕上 (painting)
浏览器的工作原理,可参考How browsers work
关于 Repaint 和 Reflow
什么会引发 reflow 回流 或 repaint 重绘
- 增加、删除、更新一个DOM节点
- 使用
display: none
(触发reflow and repaint)或者visibility: hidden
(只触发repaint,因为没有几何变动)隐藏一个节点 - 移动DOM或产生动画时
- 增加一个样式,让整个样式发生改变时
- 当用户改变窗口尺寸,或流动窗口的时候
参考
CSS 和 JS 放置顺序 / 异步机制
- 使用 link 标签将样式表放在顶部
- 将JS放在底部
脚本会阻塞后面内容的呈现
脚本会阻塞其后组件的下载
对于图片和CSS, 在加载时会并发加载(如一个域名下同时加载两个文件)。 但在加载 JavaScript 时,会禁用并发,并且阻止其他内容的下载。所以把 JavaScript 放入页面顶部也会导致 白屏 现象。
白屏&FOUC (Flash of Unstyled Content) 无样式内容闪烁
1.到底什么是白屏什么是FOUC
白屏与无样式内容闪烁(FOUC)是因为不同浏览器加载与显示页面的机制不同而造成的。
- FOUC:一些浏览器例如 firefox 。页面加载时,页面以样式A进行渲染,页面加载完成时,页面突然以样式B进行渲染,所以导致页面出现页面内容闪烁。
- 白屏:一些浏览器例如 chrome 。他的加载和渲染机制是等CSS全部加载解析完后再渲染展示页面,而这个等待的时间就为白屏。
2.为什么会出现白屏和FOUC
- FOUC
firefox浏览器:当我们输入网址按回车后浏览器会向服务端发送请求,然后服务端发送页面给浏览器,浏览器边下载页面边解析边渲染。下面我们解剖一下边下载页面边解析边渲染的过程:
- 边下载边解析就是边下载html边构建DOM Tree;
- 浏览器会以浏览器内置样式(user agent stylesheet)来解析CSSOM Tree;
- DOM Tree + CSSOM Tree 构建出 渲染树(Render Tree),然后页面内容渲染出来;
- 当解析到内联样式(inline-stylesheet)和内部样式(internal stylesheet)时,马上刷新DOM Tree + CSSOM Tree + 新的CSSOM 会发生变化引起 Render Tree变化。
- 当解析到外部链接样式(external stylesheet)是会就先加载,然后如同inline-stylesheet和internal stylesheet那样解析和刷新CSSOM Tree和Render Tree了。
上述步骤5中由于样式文件存在下载这个延时不确定的阶段,因此网络环境不好或样式资源体积大的情况下我们可以看到样式闪烁明显。
- 白屏
chorme浏览器:当我们输入网址按回车后浏览器会向服务端发送请求,然后服务端发送页面给浏览器,浏览器下载完成后页面解析渲染。下面我们解剖一下边下载页面边解析边渲染的过程:
- 根据来自服务器端的 HTML 代码形成DOM Tree;
- 加载并解析全部样式,形成 CSSOM Tree;
- 在DOM Tree + CSSOM Tree构建一棵由一组待生成渲染的渲染树(在 Webkit 中这些对象被称为渲染器或渲染对象,而在 Gecko 中称之为“frame”。)渲染树反映了文档对象模型的结构,但是不包含诸如 <head> 标签或含有display:none属性的不可见元素。在渲染树中,每一段文本字符串都表现为独立的渲染器。每一个渲染对象都包含与之对应的 DOM 对象,或者文本块,还加上计算过的样式。换言之,渲染树是一个文档对象模型的直观展示。
- 对渲染树上的每个元素,计算它的坐标,称之为布局。浏览器采用一种流方法,布局一个元素只需通过一次,但是表格元素需要通过多次。
- 最后,渲染树上的元素最终展示在浏览器里,这一过程称为“painting”。
上述步骤5中由于样式文件存在下载这个延时不确定的阶段,因此网络环境不好或样式资源体积大的情况下我们等待的时间就为白屏。
加载异步
<script src="script.js"></script>
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
<script async src="script.js"></script>
有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。
<script defer src="script.js"></script>
有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。
- defer:脚本延迟到文档解析和显示后执行,有顺序
- async:不保证顺序