前端页面渲染机制 (基本 Cover)

本贴最后更新于 926 天前,其中的信息可能已经时移世易

大学第一课:写 html;那时还用 Dw 开发,怀念。

因为自己不是前端开发人员,所以对前端页面在浏览器的渲染过程也不是很了解。对前端的了解仅限于知道经典三段:html、css 和 js。如何解析,如何渲染,包括优化放在这篇简单记录一下。

html、css 和 js 三者的关系简单举个例子:一个五官精致的大美女(html 得整体结构),化了妆更好看了(css 美化),然后她的脸被蚊子咬了,开始疯狂抓脸(触发的 js 动作),然后妆花了,脸破了(js 动作触发后对 html 和 css 产生的结构样式的影响)

Cover 了一个纯前端个人简介代码,个人感觉这个页面可以帮助我们更好的去理解前端页面渲染:

大家好我是金龙鱼,← 点击访问

那就开始分析(复制粘贴,我是缝合怪)前端页面渲染机制,参考文章如下:

1、浅析前端页面渲染机制(重要!!其实这一篇引申的就很全面了)

2、前端页面渲染过程(偏概念性;比较简单直观)

3、html 网页渲染的基本过程(有图)

那我就来缝合一下,首先开局一张图:

1.PNG

如图,撇去渲染时基础模块和操作系统这块不谈,整个浏览器从获取文件、渲染、最后到成像可以大致分为 6 步:

1.发起请求;

2.解析 HTML;

3.解析样式;

4.执行 JavaScript;

5.布局;

6.绘制

渲染的过程集中在 2-5 步,而整个渲染的过程其实就是将 URL 对应的各种资源,通过浏览器渲染引擎的解析,输出可视化的图像。

分布剖析一下:

0、浏览器获取 html 文件

没啥好说的吧

1、html 解析器构建 dom 树

拿到 html 文件后,首先会将字节转换为字符,确认 tokens 标签,然后转换为节点,通过节点构建 DOM 树。

DOM 树的概念可以参照菜鸟教程

2.PNG

构建 DOM 树就很简单了,按父子级依次向下(比如 html 标签就是祖宗;head 和 body 是第二代这种向下结构)

2、css 解析器构建 CSSOM 树

同样的,对应的 css 也会将字节转换为字符,确认 tokens 标签,然后转换为节点,通过节点构建 CSSOM 树。在解析 html 的过程中,遇到 head 标签中引用的 css,会暂停 DOM 树的构建,先将 css 解析并构建 CSSOM,然后再继续解析 html。这是因为如果后面的 html 用到了 css 样式,而样式没有提前解析,就会出现无样式状态。

3、javascript 引擎

加载 js,在页面渲染期间,如果遇到 javascript,浏览器的渲染引擎会暂停工作,先交给 javascript 引擎来执行需要的 js 代码。因为如果后面的 DOM 中涉及到 js 修改的节点,会造成两次渲染,所以要进行 js 阻塞。(JavaScript 可以修改网页的内容,也能修改 CSS 的信息,JavaScript 引擎解释 JavaScript 代码并把代码的逻辑和对 DOM 和 CSS 的改动信息应用到布局中去,从而改变渲染的结果。)

所以 javascript 终归是动作,展现还是需要 html 和 css 来干。

所以构建渲染树自然就只有 DOM 树和 CSSOM 树了。

4、构建渲染树

如上,就是把 html 解析器、css 解析器和 javascript 引擎最终渲染完的 DOM 树和 CSSOM 树结合到一起,就成渲染树了。

5、布局

创建渲染树后,下一步就是布局(Layout),或者叫回流(reflow,relayout),这个过程就是通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸,将其安置在浏览器窗口的正确位置,而有些时候我们会在文档布局完成后对 DOM 进行修改,这时候可能需要重新进行布局,也可称其为回流,本质上还是一个布局的过程,每一个渲染对象都有一个布局或者回流方法,实现其布局或回流。

简单理解就是在绘制页面之前先确定位置嘛

这块还是很细的,我不是前端,也不做深究了(其实这些都很细,就是我学的浅。。。)

6、绘制

最后是绘制(paint)阶段或重绘(repaint)阶段,浏览器 UI 组件将遍历渲染树并调用渲染对象的绘制(paint)方法,将内容展现在屏幕上,也有可能在之后对 DOM 进行修改,需要重新绘制渲染对象,也就是重绘,绘制和重绘的关系可以参考布局和回流的关系。

不说重绘,其实绘制就是将渲染树根据布局画在页面上了,至此一个前端页面渲染就结束了,可以展现了。

完:看看 Demo

3.PNG

还是 Cover 了猪头网站上的一个自我介绍的代码,分析下结构,首先看 html:

<!DOCTYPE html>
<html>
<head>
    <meta charset=utf-8>
    <title>大家好我是金龙鱼</title>
    <meta name=viewport content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1">
    <link href=css/app.121ce650a966130fb0f2ffacb130b3de.css rel=stylesheet>
</head>
<body>
<div id=app></div>
<script type=text/javascript src=js/manifest.4c9b38ff9e55227eeaef.js></script>
<script type=text/javascript src=js/vendor.1238791dbc82476562b4.js></script>
<script type=text/javascript src=js/app.8475796382bd29594a13.js></script>
<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?cb7a49e4f6a740b15e6fd25de2803712";
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(hm, s);
})();
</script>
</body>
</html>

首先浏览器拿到 html,html 解析器开始构建 DOM,按层级往下的话,在 head 中读到 css 文件会去 css 解析器中构建 CSSOM,构建完后继续构建 DOM。遇到 javascript,javascript 引擎开始渲染相应的 js,js 触发修改 css 和 html 的动作。完了后继续构建 DOM。都完事后去构建渲染树,然后布局绘制,页面就展现出来了。

至于我的这个界面,html 中的内容很少,因为主要的内容都放在了 app.8475796382bd29594a13.js 这个文件中了,所以会通过这个 js 再去渲染修改 css 和 html。

前端学的不好,这些是我读完文章后的胡扯,如有问题请纠正,不胜感激 😄

  • 框架
    47 引用 • 346 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...