了解浏览器渲染机制,FOUC,浏览器内核

1,785 阅读4分钟

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加载完执行。

浏览器内核

浏览器内核
IEtrident
Chromeblink
Operablink
Safariwebkit
FirefoxGecko