JavaScript
JavaScript ( JS ) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。是客户端和服务器端(node.js)的脚本语言,被称为非结构化编程。动态。
浏览器渲染机制
- DOM:浏览器向服务器发送http请求,服务器响应http请求并将文档发给浏览器,浏览器解析HTML,构建DOM树。
- CSSOM:浏览器解析CSS构建CSSOM树。
- Render Tree:把DOM和CSSOM组合成渲染树,有了渲染树,浏览器就能知道网页上有哪些节点,每个节点的CSS属性。
- Layout:在渲染树的基础上进行布局,计算每个节点的几何结构。顾名思义就是计算出每个节点在屏幕上的位置。
- Painting:把每个节点给绘制到屏幕上。
Repaint(重绘)
样式发生改变,位置没有发生变动,重绘一次即可,页面不需要重新计算一次。
Reflow(重排/回流)
位置发生了变化影响了其他元素的位置,需要重新计算位置即重排,之后重绘。
重绘不一定重排,重排必然重绘
重排和重绘的应用
重排
- 增加、删除、更新DOM节点绘
- 通过display: none隐藏一个DOM节点(位置发生改变)
- 元素尺寸发生变化(如边距)
- 让一个DOM节点动画时
- 添加样式,让整个样式发生改变
- 改变窗口尺寸和滚动窗口
- 计算offsetWidth、scrollTop、clientTop、getComputedStyle()等属性(获取这些属性的信息时需要返回新的布局信息,会强制队列刷新,触发重排)
重绘
- 通过visibility: hidden隐藏一个节点需要重绘
白屏
页面没有加载完,就会出现白屏。
- 对IE来说,把样式放在底部时,在某些场景下(如打开新窗口/刷新页面等)页面会出现白屏,而不是内容逐步展现。
- 如果使用@import标签,即使将CSS写入外部样式表由link引入并放在头部,也可能出现白屏。
- 把js文件放入页面顶部而未使用defer或async延迟或异步加载js文件,从而阻塞html与css的加载也会导致白屏。
FOUC
(Flash of unsettled content)无样式内容闪烁。 页面出现FOUC现象,具体表现为逐步加载无样式的内容,等CSS加载完成后页面突然展现样式。
- 把样式放在底部时,会先显示已加载的html内容,再逐步加载无样式内容,等css全部加载完成后页面突然展现样式。
CSS 和 JS 最佳放置顺序
- 使用 link 标签将样式表放在顶部
- 将JS放在底部
JS的阻塞问题
- JS会阻塞DOM树的解析和渲染
- 若JS文件页面顶部
- JS脚本会阻塞后面内容的呈现
- JS脚本会阻塞其后组件(如图片)的下载
- JS加载时间过长,css需等待,则会出现一段时间白屏
CSS的阻塞问题
- CSS会阻塞DOM树的渲染 (渲染树是依赖于CSSOM和DOM的,必须要等到CSSOM构建完成才能开始渲染)
- CSS可能会阻塞DOM树的解析(若CSS阻塞JS语句,JS会阻塞DOM,则CSS可能阻塞DOM)
- CSS会阻塞其后面JS语句的执行(JS可能会用到DOM节点和CSS样式)
- 是一种优化机制避免回流
异步加载
<script src="script.js"></script>
放在顶部的这个js文件,会提前加载,如何使它在顶部仍然稍后加载?
async (异步脚本)
不让页面等待脚本下载和执行,从而异步加载页面其他内容(并行),异步脚本会在页面的load事件前执行。不保证顺序。
<script async src="script.js"></script>
defer(延迟脚本)
js脚本会被延迟到整个页面都解析完成后再运行,会先于DOMContentLoaded事件执行。按顺序执行。
<script defer src="script.js"></script>
作用
缩短了网页的加载时间,且他们的显示速度更快。
页面加载
对于浏览器来说,页面加载主要有两个事件。DOMContentLoaded、onLoad。
onLoad
等待页面所有资源加载完成才会触发。
DOMContentLoaded
等页面内容解析完就触发。
- 若js在css前,则DOMContentLoaded不会等待css加载,也不会等待之后的图片、视频等其他资源加载。
- 若js在css后,CSS阻塞其后面的js语句执行,js阻塞DOM解析,就导致DOMContentLoaded会等待CSS加载完执行。
浏览器内核
| 浏览器 | 内核 |
|---|---|
| IE | trident |
| Chrome | blink |
| Opera | blink |
| Safari | webkit |
| Firefox | Gecko |