网页
什么是网页?
- 网页 =
Html+CSS+JavaScript
-
Html
是网页的内容 -
CSS
是网页的样式 -
JavaScript
是网页的行为
-
每个学习编程语言的第一个编程肯定是打印出"Hello World"来看看JavaScript是怎么实现的.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>认识js</title>
</head>
<body>
<script>
document.write("Hello World") //会在页面中出现Hello World
</script>
</body>
</html>
来看一下JavaScript的发展历史
谁也想不到,1995年被当做营销策略推出的JavaScript语言,在2017年成为了最受欢迎平台(web)上的核心语言。JavaScript现在不仅可以在浏览器中运行,它还被用作开发桌面和手机应用,用于嵌入式设备,甚至NASA还拿它来设计太空组件。
JS标准制定简史(简略)
- 只花了10天时间 Brendan 就开发完成了当时被称作Mocha的初版 JavaScript 原型,这个新语言类似 Scheme ,它把函数当做一等公民,并以原型链为其核心。那时候的JS比较简陋,没有数组和字面量的对象的概念,所有的报错都只能通过丑陋的alert展示,缺乏异常处理机制,出错时很多运算的结果会是NaN或undefined。
- 1995年9月,网景公司发布了Netscape Navigator 2.0 beta版,JavaScript也被包装为LiveScript一同面世。
- 1995年12月,Netscape Navigator 2.0 beta3发布,LiveScript在这时被改名为JavaScript(当时这个商标为Sun公司所有,现在属甲骨文公司)。之后不久,网景推出了LiveWire,一种在其服务器(Netscape Enterprise Server)上的JavaScript实现1。
- 1996年开始,JS语言开始走上规范之路,它已ECMAScript的名字被标准化到ECMA-262规范,
- 1997年6月ECMA-262的第一版发布,之后一年中,规范依据ISO / IEC 16262国际标准进行了改进,并由ISO认证机构大量审查,1997年6月ECMAScript规范正式发布第二版。
- 1999年12月,第三版也发布了,这一版的规范带来了正则表达式,switch,do/while,try/catch,Object#hasOwnProperty以及其它的一些改变
- 2007年,TC39委员会被迫分为两部分,一部分负责ES3的渐进加强版ES3.1标准的制定,另一部分则负责重新设计改动巨大的ES4标准。2008年8月,ES3.1被认为是正确的选择,随后其更名为ES5,ES4也随之被废弃,不过值得庆幸的是 ES4 提出的很多新功能被融入到了 ES6 ,也有一些功能仍然在考虑之中,另一些则已被放弃,拒绝或撤回。兼容ES3.1 成为 ES4 标准提出的功能可能被采纳的前提。
- 2009年12月,ES3发布10周年后,第五版ECMAScript才得以发布。这个版本把十年来各浏览器中已有的普遍实践标准化了,新增了get
set
,改进了数组原型的函数式特征,原生支持了JSON的解析,提出了严格模式。 - 2015年6月,也就是ES5.1发布的四年后,TC39公布了JS语言有史以来最大的更新 ES6,其中包含了很多ES4中提出草案。本书,我们将深入探索ES6。
- ES6的发布是JS标准制定历史上的一个重要里程碑。除了数十种引入注目的新功能,ES6 的发布也标志着 ECMAScript 标准将持续更新。
问题:ES3、ES5、ES6指什么?
- ES3 ES5 ES6 指的是不同的ECMAScript的版本
- 1999年12月,ECMAScript 3.0版发布,成为JavaScript的通行标准,得到了广泛支持。
- 2009年12月,ECMAScript 5.0版正式发布
- 2015年6月,ECMAScript 6正式发布
参考:
浏览器的渲染机制
了解渲染机制之前,我们先了解几个概念
- DOM:Document Object Model,浏览器将HTML解析成树形的数据结构,简称DOM。
- CSSOM:CSS Object Model,浏览器将CSS代码解析成树形的数据结构。
- DOM 和 CSSOM 都是以
Bytes → characters → tokens → nodes → object model.
这样的方式生成最终的数据 - Render Tree:DOM 和 CSSOM 合并后生成 Render Tree
浏览器渲染过程
- 用户输入一个
URL
的时候,浏览器就会发送一个请求,请求URL
对应的资源。 - 浏览器的
HTML
解析器会将这个文件解析,并且构建成一棵DOM
树。(在生成DOM
的最开始阶段(应该是Bytes → characters
后),并行发起css、
图片、js
的请求,无论他们是否在HEAD
里。)- 注意:发起
js
文件的下载request
并不需要DOM
处理到那个script
节点,比如:简单的正则匹配就能做到这一点,虽然实际上并不一定是通过正则:)。这是很多人在理解渲染机制的时候存在的误区
- 注意:发起
- 在构建
DOM
树的时候,遇到 js 和
CSS
元素,HTML解析器就换将控制权转让给JS解析器或者是CSS解析器。开始构建CSSOM
-
DOM
树构建完之后,浏览器把DOM树中的一些不可视元素去掉,然后与CSSOM
合成一棵render tree
。 -
Layout
:有了Render Tree
,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。下一步操作称之为Layout
,顾名思义就是计算出每个节点在屏幕中的位置。 -
Painting:Layout
后,浏览器已经知道了哪些节点要显示(which nodes are visible
)、每个节点的CSS属性是什么(their computed styles
)、每个节点在屏幕中的位置是哪里(geometry
)。就进入了最后一步:Painting
,按照算出来的规则,通过显卡,把内容画到屏幕上。
以上几个步骤因为
DOM、CSSOM、Render Tree
都可能在第一次Painting
后又被更新多次,比如JS
修改了DOM
或者CSS
属性。Layout
和Painting
也会被重复执行,除了DOM、CSSOM
更新的原因外,图片下载完成后也需要调用Layout
和 `Painting来更新网页
关于Repaint 和 Reflow
Repaint Reflow也就是中文中的重绘和回流
-
重绘(repaints)
是一个元素外观的改变所触发的浏览器行为,例如改变vidibility、outline、
背景色等属性。浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。重绘不会带来重新布局,并不一定伴随回流。 -
回流(reflow)
是更明显的一种改变,可以理解为渲染树需要重新计算。
引起
Repain
和Reflow
的一些操作
- 当你增加、删除、修改
DOM
结点时,会导致Reflow 或 Repaint
。 - 当你移动
DOM
的位置,或是搞个动画的时候。 - 当你修改
CSS
样式的时候。 - 当你
Resize
窗口的时候(移动端没有这个问题),或是滚动的时候。 - 当你修改网页的默认字体时
- 注:
display:none
会触发reflow
,而visibility:hidden
只会触发repaint
,因为没有发现位置变化。
- 注:
参考:
如何异步加载脚本
向
HTML
页面中插入JavaScript
的方法,就是使用<script>
标签,我们先来了解一下<script>
定义了6个属性
-
async:
异步脚本可选,表示立即下载脚本,但不妨碍页面中其他操作,只对外部脚本有效 -
defer:
延迟脚本可选.表示脚本可以延迟到文档完全被解析和显示之后再执行.只对外部脚本文件有效 -
charset:
可选,表示通过src
属性指定的代码的字符集,由于大多数浏览器会忽略这个值,因此属性很少用 -
src:
可选,表示包含要执行的外部文件 -
language:
已废弃 -
type:
可选,可以看成是language
的替代属性
<script src="script.js"></script>
- 没有
defer
或async
,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该script
标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行
<script async src="script1.js"></script>
<script async src="script2.js"></script>
- 有
async
,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。 -
async
不保证按照它们的先后顺与执行 - 异步脚本一定会在页面的
load
事件前执行
<script defer src="script.js"></script>
- 有
defer
,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但script.js
的执行要在所有元素解析完成之后,DOMContentLoaded
事件触发之前完成。 - 脚本延迟到文档解析和显示后执行,有顺序
解释白屏和 FOUC(无样式内容闪烁)
- fouc出现的条件
- 使用@import方法导入CSS时,此方式由于IE会先加载整个HTML文档的DOM,然后再去导入外部的CSS文件,因此,在页面DOM加载完成到CSS导入完成中间会有一段时间页面上的内容是没有样式的,这段时间的长短跟网速,电脑速度都有关系。
- 将样式表放在页面底部
- 有几个样式表,放在html结构的不同位置。
原理:
当样式表晚于结构性html加载,当加载到此样式表时,页面将停止之前的渲染。此样式表被下载和解析后,将重新渲染页面,也就出现了短暂的花屏现象。
解决方法:
使用LINK标签将样式表放在文档HEAD中。
CSS 和 JS 放置顺序, 异步机制
- 使用 link 标签将样式表放在顶部
- 将JS放在底部
- 脚本会阻塞后面内容的呈现
- 脚本会阻塞其后组件的下载
对于图片和CSS, 在加载时会并发加载(如一个域名下同时加载两个文件). 但在加载 JavaScript 时,会禁用并发,并且阻止其他内容的下载. 所以把 JavaScript 放入页面顶部也会导致 白屏
现象.
上图我们可以看到对于chrome浏览器来说,等所有的css加载完成并解析完成,
CSSOM
计算完成,把页面你全部展示出来,所以会出现解析时间的白屏上图我们可以看到开始时字体比较小都是html的正常字体大小,然后当css加载完成后会出现加载css央视后的字体,页面发生了变化,这是firefox的处理机制(无样式内容闪烁)