前面一篇文章:「高频面试题」浏览器从输入url到页面展示中间发生了什么 中,我们有对浏览器的渲染流程做了一个概括性的介绍,今天这篇文章我们将深入学习这部分内容。
对于很多前端开发来说,平常做工主要专注于业务开发,对浏览器的渲染阶段可能不是很了解。实际上这个阶段很重要,了解浏览器的渲染过程,能让我们知道我们写的HTML、CSS、JS代码是如何被解析,并最终渲染成一个页面的,在页面性能优化的时候有相应的解决思路。
我们先来看一个问题:
HTML、CSS、JS文件在浏览器中是如何转化成页面的?
如果你回答不上来,那就往下看吧。
按照渲染的时间顺序,渲染过程可以分为下面几个子阶段:构建DOM树、样式计算、布局阶段、分层、栅格化和合成显示。
下面详细看下每个阶段都做了哪些事情。
HTML文档描述一个页面的结构,但是浏览器无法直接理解和使用HTML,所以需要通过HTML解析器将HTML转换成浏览器能够理解的结构——DOM树。
HTML文档中所有内容皆为节点,各节点之间有层级关系,彼此相连,构成DOM树。
构建过程:读取HTML文档的字节(Bytes),将字节转换成字符(Chars),依据字符确定标签(Tokens),将标签转换成节点(Nodes),以节点为基准构建DOM树。参考下图:
打开Chrome的开发者工具,在控制台输入 document 后回车,就能看到一个完整的DOM树结构,如下图所示:
在控制台打印出来的DOM结构和HTML内容几乎一样,但和HTML不同的是,DOM是保存在内存中的树状结构,可以通过JavaScript来查询或修改其内容。
样式计算这个阶段,是为了计算出DOM节点中每个元素的表现样式。
CSS样式可以通过下面三种方式引入:
和HTML一样,浏览器无法直接理解纯文本的CSS样式,需要通过CSS解析器将CSS解析成 styleSheets 结构,也就是我们常说的 CSSOM树。
styleSheets结构同样具备查询和修改功能:
document.styleSheets
属性值标准化看字面意思有点不好理解,我们通过下面一个例子来看看什么是属性值标准化:
在写CSS样式的时候,我们在设置color属性值的时候,经常会用white、red等,但是这种值浏览器的渲染引擎不容易理解,所以需要将所有值转换成渲染引擎容易理解的、标准化的计算值,这个过程就是属性值标准化。
white标准化后的值为 rgb(255, 255, 255)
完成样式的属性值标准化后,就需要计算每个节点的样式属性,这个阶段CSS有两个规则我们需要清楚:
样式计算阶段是为了计算出DOM节点中每个元素的具体样式,在计算过程中需要遵守CSS的继承和层叠两个规则。
该阶段最终输出的内容是每个DOM节点的样式,并被保存在 ComputedStyle 的结构中。
经过上面的两个步骤,我们已经拿到了DOM树和DOM树中元素的样式,接下来需要计算DOM树中可见元素的几何位置,这个计算过程就是布局。
在DOM树中包含了一些不可见的元素,例如 head 标签,设置了 display:none 属性的元素,所以我们需要额外构建一棵只包含可见元素的布局树。
构建过程:从DOM树的根节点开始遍历,将所有可见的节点加到布局树中,忽略不可见的节点。
到这里我们就有了一棵构建好的布局树,就可以开始计算布局树节点的坐标位置了。从根节点开始遍历,结合上面计算得到的样式,确定每个节点对象在页面上的具体大小和位置,将这些信息保存在布局树中。
布局阶段的输出是一个盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小。
现在我们已经有了布局树,也知道了每个元素的具体位置信息,但是还不能开始绘制页面,因为页面中会有像3D变换、页面滚动、或者用 z-index 进行z轴排序等复杂效果,为了更方便实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树(LayerTree)。
在Chrome浏览器中,我们可以打开开发者工具,选择 Elements-Layers 标签,就可以看到页面的分层情况,如下图所示:
浏览器的页面实际上被分成了很多图层,这些图层叠加后合成了最终的页面。
到这里,我们构建了两棵树:布局树和图层树。下面我们来看下这两棵树之间的关系:
正常情况下,并不是布局树的每个节点都包含一个图层,如果一个节点没有对应的图层,那么这个节点就从属于父节点的图层。
那节点要满足什么条件才会被提升为一个单独的图层?只要满足下面其中一个条件即可:
构建好图层树之后,渲染引擎就会对图层树中的每个图层进行绘制。
渲染引擎实现图层绘制,会把一个图层的绘制拆分成很多小的绘制指令,然后将这些指令按照顺序组成一个绘制列表。
绘制一个图层时会生成一个绘制列表,这只是用来记录绘制顺序和绘制指令的列表,实际上绘制操作是由渲染引擎中的合成线程来完成的。
通过下图来看下渲染主线程和合成线程之间的关系:
当图层的绘制列表准备好后,主线程会把该绘制列表提交给合成线程,合成线程开始工作。
首先合成线程会将图层划分为图块(tile),图块大小通常是 256256 或者 512512。
然后合成线程会按照视口附近的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图。而图块是栅格化执行的最小单位。渲染进程维护了一个栅格化的线程池,所有的图块栅格化都是在线程池内执行的,运行方式如下图所示:
一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程。
浏览器进程里面有一个名字叫做 viz 的组件,用来接收合成线程发过来的 DrawQuad 命令,然后根据命令执行。 DrawQuad 命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上。
多年开发老码农福利赠送:网页制作,网站开发,web前端开发,从最零基础开始的的HTML+CSS+JavaScript。jQuery,Vue、React、Ajax,node,angular框架等到移动端小程序项目实战【视频+工具+电子书+系统路线图】都有整理,需要的伙伴可以私信我,发送“前端”等3秒后就可以获取领取地址,送给每一位对编程感兴趣的小伙伴
一个完整的渲染流程可以总结如下:
渲染过程中还有两个我们经常听到的概念:重排和重绘。在这篇文章中就不细说了,下一篇文章再详细介绍。
我们日常学习和日常工作中,如果想要将PDF文件转换为HTML文件要怎么办呢?随着需求的增加,我们需要会的技能也要增加了。不止要将PDF文件转换为TXT,转换为Word。还要会将PDF转换为HTML。
那么如果你遇见要将PDF文件转换为HTML的问题要怎么解决呢?今天小编就和大家分享如何转换PDF文件为HTML的四种实用方法。
PDF to HTML这款软件可以将PDF文件轻松转换为HTML格式。支持批量转换跑到福清群文件并且尽量保留PDF文件的原始文本、格式以及布局。
风云PDF转换器这款软件可以将PDF文件快速转换为HTML格式,除此外,软件支持将PDF文件与常见的格式之间相互转换,比如PDF与Word文档,PPT、图片、TXT格式、Excel等。软件还包括将PDF文件合并、PDF压缩、PDF页面提取、PDF拆分等功能,软件功能全面,页面整洁。支持一键转换,批量转换、拖拽添加文件等便捷操作。
TriSun pdf to HTML这款软件可以将PDF文件转换为HTML。软件支持转换有所限制的PDF文件,比如不允许拷贝内容、保存为文本的PDF文件等。
PDF to Html Converter这款软件功能简单,除了将PDF文件转换为HTML之外,没有多余的选项以及功能。但是可以对添加的PDF文件进行管理,可移除与清理。
以上就是小编整理的四款可以将PDF文件转换为HTML的软件,希望可以帮助到大家。
拟机为我们提供了一个无限可能的世界。在这个世界里,我们可以尝试、学习、甚至犯错,而不必担心现实生活中的后果。Emacs,作为一款强大的文本编辑器,它的Org模式更是让人们在组织复杂信息时如鱼得水。但是,当我们尝试将Org文件转换为HTML格式时,有时会遇到一个令人困惑的问题:“source block missing language specification #include”。这是什么意思?它又该如何解决呢?
在深入探讨之前,让我们先来思考一个问题:为什么我们要将Org文件转换为HTML?答案可能各有不同,但一个共同点是,我们都希望能够更好地分享和展示我们的工作。HTML作为一种广泛支持的格式,能够让我们的内容在不同的平台上呈现出一致的效果。这就像是我们穿上了一件合身的外衣,让内在的价值得以外显。
当我们遇到“source block missing language specification #include”的提示时,我们应该怎么办呢?首先,我们需要理解这个提示的含义。在Emacs的Org模式中,当我们使用源代码块时,通常需要指定语言类型,比如#+BEGIN_SRC python。这样,Emacs就能够知道如何高亮和格式化我们的代码。但如果我们忘记了这一步,就会收到上述的提示。
解决这个问题的方法其实很简单。我们只需要回到源代码块的开始,确保正确地指定了语言类型。如果是包含在文件中的代码,比如C语言的头文件,我们可以使用#+INCLUDE: "file.h" src c这样的语法来引入。
通过这个简单的修正,我们就能够顺利地将Org文件转换为HTML,而不会再有任何阻碍。这个过程就像是我们在虚拟世界中解决了一个谜题,获得了前进的钥匙。
并且可以尝试以下几种方法来解决:
方法一:添加语言规范
在 Org 文档中,对于包含代码块的文本,需要添加语言规范,以便 Org-mode 正确地解析和转换代码。
具体步骤如下:
在代码块的开头,添加一行指示语言规范的注释。例如,对于 C 语言代码,可以添加以下注释:
#lang c
再次尝试将 Org 文档转换为 HTML。
方法二:使用 org-babel
org-babel 是 Org-mode 的一个扩展包,可以用于将代码块转换为各种格式,包括 HTML。
具体步骤如下:
安装 org-babel 扩展包。
M-x package-install RET org-babel
在 Org 文档中,将代码块标记为 babel 块。例如,对于 C 语言代码,可以使用以下标记:
#+begin_src c#include <stdio.h>int main() { printf("Hello, world!\n"); return 0;}#+end_src
再次尝试将 Org 文档转换为 HTML。
方法三:使用 org-html-export-filter
org-html-export-filter 是 Org-mode 的一个函数,可以用于在导出 HTML 时自定义代码块的转换。
具体步骤如下:
在 Emacs 配置文件中,添加以下代码:
(defun my-org-html-export-filter (block) "自定义代码块的转换。" (if (string-match-p "^#lang\s+c\s*$" (org-block-property block :language)) (org-html-export-filter-block-as-code block "c" "highlight") (org-html-export-filter-block-as-verbatim block)))(add-hook 'org-html-export-filter-alist 'my-org-html-export-filter)
再次尝试将 Org 文档转换为 HTML。
以上三种方法都可以解决 Org 转为 HTML 时提示“source block missing language specification #include<stdio.h>”的问题。具体选择哪种方法,可以根据自己的实际情况和需求来决定。
*请认真填写需求信息,我们会在24小时内与您取得联系。