ECMAScript、DOM、BOM
ECMAScript
标准化的JavaScript,脱离宿主对象的JS核心语法,也称作JavaScript核心,涉及如数据类型、数组、字符串、正则、对象等;
JS的运行宿主包括浏览器、服务器、桌面APP、移动端APP、命令行应用、小程序等;
DOM
浏览器提供的一系列能操作网页结构的API
BOM
浏览器提供的一系列和页面结构无关但和浏览器其他功能相关的API
javascript引入
js引入
hello world
从URL输入到页面展现
浏览器的渲染机制
- 解析 HTML 标签, 构建 DOM 树
- 解析 CSS, 构建 CSSOM 树
- 把 DOM 和 CSSOM 组合成 渲染树 (render tree)
- 在渲染树的基础上进行布局, 计算每个节点的几何结构
- 把每个节点绘制到屏幕上 (painting)
Repaint 和 Reflow
Repaint重新绘制
绘制界面发生变化的部分。例如,就像通过js修改一个元素的color。
Reflow回流
重新计算元素的几何尺寸、位置。例如通过js删除一个节点。
重绘和回流的案例
- 添加、删除、更新DOM节点(reflow 、repaint)
- 修改元素的magin、padding、border(reflow、repaint)
- display: none(reflow、repaint)
- visibility: hidden(repaint)
- 修改颜色、背景色(repaint)
总结
1.要是用JavaScript修改样式的话,尽量一次性修改样式;
2.给动画使用绝对定位可以减小reflow;
3.DOM离线后修改;
资源加载顺序
图片的加载
案例1 图片的加载是否影响其他资源的加载和页面渲染?
答案:不影响
案例2 CSS里给一个选择器设置了背景图片,而此选择器并未选中HTML里任何元素,浏览器是否发生此图片的资源请求?
答案:不请求
案例3 CSS里选择一个页面上的元素,设置了背景图片,但设置该元素display: none,浏览器是否发生此图片的资源请求?如果是给该元素的父亲设置display:none呢?
答案:给自己设置,发请求;给父亲设置,不发请求
案例4 CSS里选择一个页面上的元素,设置了背景图片,但设置该元素visibility: hidden,浏览器是否发生此图片的资源请求?如果是给该元素的父亲设置visibility: hidden呢?
答案:都发请求
案例5 HTML里有一个Img标签,当设置该元素display: none,浏览器是否发生此图片的资源请求?如果给img的父亲设置呢
答案:都发请求
阻塞解析与阻塞渲染
阻塞解析: 阻塞点后面的标签不会被解析,阻塞解析不一定阻塞其他外部资源
的加载。
阻塞渲染:阻塞点后面的标签会继续被解析,img,link等会继续发送请求获取
外部资源,但不会触发页面渲染(白屏),也不会执行JavaScript代码。
CSS加载
- CSS加载不阻塞解析,但会阻塞渲染
白屏
- 页面一片空白,突然展示完整的有样式的内容;
- 当link放在head标签,且加载时间久时,会出现白屏效果;
FOUC [flash of unstyle content]
- 页面一开始展示无样式的内容,突然样式正常;
- 当link放在页面底部,且加载时间久时,会出现FOUC;
- 如果非要把link放在底部的话,在另外写一个loading页面也是可以的!
Tips:尽量把link放在head标签内,防止出现FOUC
JS加载
- JS加载和执行会阻塞解析
Tips:尽量把外置JS放置在body的最后,以便让DOM尽快展现,同时方便JS操作DOM
异步加载 script标签的async 和defer属性
async 与 defer
正常情况下JS的加载会阻止后续DOM结构的解析,并且多个JS会按顺序
依次执行
async: 加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行
进行(异步)
defer: 加载后续文档元素的过程将和 script.js 的加载并行进行(异步),
但 script.js 的执行要在所有元素解析完成之后执行
二者的差异
async | defer |
---|---|
async的存在不影响DOM的解析和其他资源的加载,特立独行,不保证顺序,不保证时机 | defer存在不影响DOM的解析和其他资源的加载,但是会保证在DOM资源主备就绪后再执行,并且对于多个defer的外置JavaScript文件按照顺序执行 |