整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

你知道HTML、CSS、JS文件在浏览器中是如何转化成页面的吗?

前面一篇文章:「高频面试题」浏览器从输入url到页面展示中间发生了什么 中,我们有对浏览器的渲染流程做了一个概括性的介绍,今天这篇文章我们将深入学习这部分内容。

对于很多前端开发来说,平常做工主要专注于业务开发,对浏览器的渲染阶段可能不是很了解。实际上这个阶段很重要,了解浏览器的渲染过程,能让我们知道我们写的HTML、CSS、JS代码是如何被解析,并最终渲染成一个页面的,在页面性能优化的时候有相应的解决思路。

我们先来看一个问题:

HTML、CSS、JS文件在浏览器中是如何转化成页面的?

如果你回答不上来,那就往下看吧。

按照渲染的时间顺序,渲染过程可以分为下面几个子阶段:构建DOM树、样式计算、布局阶段、分层、栅格化和合成显示。

下面详细看下每个阶段都做了哪些事情。

1. 构建DOM树

HTML文档描述一个页面的结构,但是浏览器无法直接理解和使用HTML,所以需要通过HTML解析器将HTML转换成浏览器能够理解的结构——DOM树。

HTML文档中所有内容皆为节点,各节点之间有层级关系,彼此相连,构成DOM树。

构建过程:读取HTML文档的字节(Bytes),将字节转换成字符(Chars),依据字符确定标签(Tokens),将标签转换成节点(Nodes),以节点为基准构建DOM树。参考下图:

打开Chrome的开发者工具,在控制台输入 document 后回车,就能看到一个完整的DOM树结构,如下图所示:

在控制台打印出来的DOM结构和HTML内容几乎一样,但和HTML不同的是,DOM是保存在内存中的树状结构,可以通过JavaScript来查询或修改其内容。

2. 样式计算

样式计算这个阶段,是为了计算出DOM节点中每个元素的表现样式。

2.1 解析CSS

CSS样式可以通过下面三种方式引入:

  • 通过link引用外部的CSS文件
  • style 标签内的CSS
  • 元素的style属性内嵌的CSS

和HTML一样,浏览器无法直接理解纯文本的CSS样式,需要通过CSS解析器将CSS解析成 styleSheets 结构,也就是我们常说的 CSSOM树

styleSheets结构同样具备查询和修改功能:

document.styleSheets

2.2 属性值标准化

属性值标准化看字面意思有点不好理解,我们通过下面一个例子来看看什么是属性值标准化:

在写CSS样式的时候,我们在设置color属性值的时候,经常会用white、red等,但是这种值浏览器的渲染引擎不容易理解,所以需要将所有值转换成渲染引擎容易理解的、标准化的计算值,这个过程就是属性值标准化。

white标准化后的值为 rgb(255, 255, 255)

2.3 计算DOM树中每个节点的样式

完成样式的属性值标准化后,就需要计算每个节点的样式属性,这个阶段CSS有两个规则我们需要清楚:

  • 继承规则:每个DOM节点都包含有父节点的样式
  • 层叠规则:层叠是CSS的一个基本特征,是一个定义了如何合并来自多个源的属性值的算法。

样式计算阶段是为了计算出DOM节点中每个元素的具体样式,在计算过程中需要遵守CSS的继承和层叠两个规则。

该阶段最终输出的内容是每个DOM节点的样式,并被保存在 ComputedStyle 的结构中。

3. 布局阶段

经过上面的两个步骤,我们已经拿到了DOM树和DOM树中元素的样式,接下来需要计算DOM树中可见元素的几何位置,这个计算过程就是布局。

3.1 创建布局树

在DOM树中包含了一些不可见的元素,例如 head 标签,设置了 display:none 属性的元素,所以我们需要额外构建一棵只包含可见元素的布局树。

构建过程:从DOM树的根节点开始遍历,将所有可见的节点加到布局树中,忽略不可见的节点。

3.2 布局计算

到这里我们就有了一棵构建好的布局树,就可以开始计算布局树节点的坐标位置了。从根节点开始遍历,结合上面计算得到的样式,确定每个节点对象在页面上的具体大小和位置,将这些信息保存在布局树中。

布局阶段的输出是一个盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小。

4. 分层

现在我们已经有了布局树,也知道了每个元素的具体位置信息,但是还不能开始绘制页面,因为页面中会有像3D变换、页面滚动、或者用 z-index 进行z轴排序等复杂效果,为了更方便实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树(LayerTree)。

在Chrome浏览器中,我们可以打开开发者工具,选择 Elements-Layers 标签,就可以看到页面的分层情况,如下图所示:

浏览器的页面实际上被分成了很多图层,这些图层叠加后合成了最终的页面。

到这里,我们构建了两棵树:布局树和图层树。下面我们来看下这两棵树之间的关系:

正常情况下,并不是布局树的每个节点都包含一个图层,如果一个节点没有对应的图层,那么这个节点就从属于父节点的图层。

那节点要满足什么条件才会被提升为一个单独的图层?只要满足下面其中一个条件即可:

  • 拥有层叠上下文属性的元素会被提升为单独的一个图层
  • 需要剪裁(clip)的地方也会被创建为图层。

5. 图层绘制

构建好图层树之后,渲染引擎就会对图层树中的每个图层进行绘制。

渲染引擎实现图层绘制,会把一个图层的绘制拆分成很多小的绘制指令,然后将这些指令按照顺序组成一个绘制列表。

6. 栅格化(raster)操作

绘制一个图层时会生成一个绘制列表,这只是用来记录绘制顺序和绘制指令的列表,实际上绘制操作是由渲染引擎中的合成线程来完成的。

通过下图来看下渲染主线程和合成线程之间的关系:

当图层的绘制列表准备好后,主线程会把该绘制列表提交给合成线程,合成线程开始工作。

首先合成线程会将图层划分为图块(tile),图块大小通常是 256256 或者 512512。

然后合成线程会按照视口附近的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图。而图块是栅格化执行的最小单位。渲染进程维护了一个栅格化的线程池,所有的图块栅格化都是在线程池内执行的,运行方式如下图所示:

7. 合成和显示

一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程。

浏览器进程里面有一个名字叫做 viz 的组件,用来接收合成线程发过来的 DrawQuad 命令,然后根据命令执行。 DrawQuad 命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上。

多年开发老码农福利赠送:网页制作,网站开发,web前端开发,从最零基础开始的的HTML+CSS+JavaScript。jQuery,Vue、React、Ajax,node,angular框架等到移动端小程序项目实战【视频+工具+电子书+系统路线图】都有整理,需要的伙伴可以私信我,发送“前端”等3秒后就可以获取领取地址,送给每一位对编程感兴趣的小伙伴

8. 总结

一个完整的渲染流程可以总结如下:

  • 1、渲染进程将HTML内容转换为浏览器能够读懂的DOM树结构。
  • 2、渲染引擎将CSS样式表转化为浏览器可以理解的styleSheets,计算出DOM节点的样式。
  • 3、创建布局树,并计算所需元素的布局信息。
  • 4、对布局树进行分层,并生成分层树。
  • 5、为每个图层生成绘制列表,并将其提交到合成线程。
  • 6、合成线程将图层分图块,并栅格化将图块转换成位图。
  • 7、合成线程发送绘制图块命令给浏览器进程。浏览器进程根据指令生成页面,并显示到显示器上。

渲染过程中还有两个我们经常听到的概念:重排和重绘。在这篇文章中就不细说了,下一篇文章再详细介绍。

DF文件是工作学习中的常客,在使用过程中,常常需要对PDF格式进行转换,包括但不限于PDF转Word、PDF转PPT、PDF转图片等等。

不过WPS虽然应用广泛,但是里面关于PDF的转换工具必需要会员才可以使用,但又不愿意只为了转换一次而花费钱去买会员,本文为大家提供了5款免费在线转换PDF的网站,建议收藏以备不时之需~

1、i love pdf

I LOVE PDF是一款免费的PDF网站,界面设计简洁,首页没有广告,但每个功能的操作界面是有广告的,不会影响使用。

部分功能:合并PDF、拆分PDF、压缩PDF、PDF转换至Word、PDF转换至PowerPoint、PDF转换至Excel、word转换至PDF文件、PowerPoint转换至PDF、Excel转换至PDF、PDF转JPG、JPG转PDF、页码、水印、旋转PDF、HTML转换PDF、PDF解密、PDF加密、排版PDF文件、PDF转换PDF/A、修复PDF

2、迅捷PDF转换器

免费的在线文档格式转换软件,不仅有常见的格式,还有诸多不常见文档格式在这里都有,包括电子书格式转换,一个网站解决各种文档格式转换问题。

部分功能:
文档转换→DF转换至Word、PDF转换至PowerPoint、PDF转换至Excel、word转换至PDF文件、PowerPoint转换至PDF、Excel转换至PDF、PDF转JPG、JPG转PDF

文档处理→PDF台并、PDF分割、PDF解密、PDF增加密码、PDF修改密码、PDF图片获取、PDF删除页、PDF页面提取、PDF旋转、PDF页面编辑、PDF替换文字、PDF添加水印、PDF删除水印、PDF添加文字、PDF删除文字、PDF链接编辑、PDF添加页码、PDF删除图片、PDF背景颜色、PDF签名等

除此之外,还有音视频格式转等功能,网站功能免费,页面没有广告,可以放心使用。

3、PDF Candy

转换为PDF和20多种格式的文件。此外,PDF Candy提供47种在线工具来处理PDF:编辑、拆分、合并、压缩等等。

4、all to all

ALL TO ALL在线格式转换,国内最全类型的在线文件转换平台,免费、快速,无须下载安装任何软件。支持约200多种格式的文件转换,包括:视频、音频、图片、字体等多媒体文件,以及常见的office文件、PDF、电子书等文档。

5、online2pdf

ONLINE2PDF是个完全免费的良心线上PDF编辑网站,需要配合自带翻译功能的浏览器使用,目前国内访问正常,功能丰富,操作简便。


以上就是全部的内容推荐啦,如果有帮助,记得点个赞吖~

Java实现根据svg模版动态生成图片

使用场景

需要Java语言动态生成图片

用流程图简单说明下我这边工作中使用的场景

仅供参考

所以这里就需要生成证书了

我先给大家看下最终实现的图片效果

这里要先说明一下

  • 图片上的文字都是动态变化的即不同的订单对应的图片内容都不一样
  • 图片上还可以嵌入图片哦 比如上图的logo图片

下面说下我是如何解决的

通过PhantomJS来实现

这种方式是不能实现这个需求的

这个的原理就是对网页截图 但只能对于静态页面截图 不能根据不同的参数值动态生成图片

所以不提倡使用这种方式

但也介绍下这种使用方式 朋友们根据自己的实际需求情况有选择的使用

通过html代码实现图片的效果 放入web容器(比如nginx)中部署

这是h5代码

test文件夹下面的内容

安装一个docker nginx 将test文件夹加载到nginx容器的/usr/share/nginx/html目录下面

docker run --name nginx80  -p 8000:80  -v /tmp/test:/usr/share/nginx/html -d docker.io/nginx

访问的页面效果

访问该页面进行截图

这张图片是截图生成的图片 但url中的id值并没有传给页面

在h5代码中请求后端接口获取数据动态显示出来也是不可以的

所以这种方式使用局限性很窄

简单介绍下代码原理

大致原理是 通过http请求该url获取该url的文件流然后解析h5代码生成图片

通过SVG模版动态生成

先写svg模版(其实也是h5代码)

读取svg模版 动态传入参数生成图片

其实现原理大致为 读取svg document h5代码 将动态参数map解析到h5代码中 转换成字节数组 生成图片格式

Linux环境图片中文乱码

我本地是mac系统没有这个问题 在发布到测试环境linux系统出现了这个问题

先看下问题的现象

看到了没 生成的图片中文全是乱码

原因是因为linux系统没有中文字体

既然linux系统没有中文字体 那么就安装它嘛 let's 盘它!!!

先看下mac环境的字体情况

  • 安装字体管理工具
brew install fontconfig
  • 查看支持中文
fc-list :lang=zh    (注意‘:’前的空格)

mac环境默认会安装很多中文字体

再看下linux环境

  • 安装字体管理工具
yum -y install fontconfig
  • 查看支持中文
fc-list :lang=zh

果然没有中文字体

开始安装中文字体

将mac环境的宋体上传到linux环境

a 先在mac系统中找到字体安装目录

/System/Library/Fonts

b 找到宋体对应的文件

c 将该文件上传到linux指定的目录下

/usr/share/fonts/chinese

d 赋予文件夹操作权限

chmod -R 755 /usr/share/fonts/chinese

e 安装ttmkfdir来搜索目录中所有的字体信息,并汇总生成fonts.scale文件

yum -y install ttmkfdir

ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir

修改字体配置文件

vi /etc/fonts/fonts.conf
添加
<dir>/usr/share/fonts/chinese</dir>

刷新内存中的字体缓存

fc-cache

确认是否安装成功

在jdk中安装该宋体

a 找到jdk所在的安装目录

echo $JAVA_HOME 

b 将宋体文件复制过来

cp /usr/share/fonts/chinese/STHeiti\ Light.ttc /usr/local/software/jdk1.8.0_141/jre/lib/fonts/fallback

fallback代表存放后备语言的文件夹

重启java服务即可

DEMO代码

https://gitee.com/pingfanrenbiji/resource/tree/master/image

注意: 引入的依赖问题

  <!--phantomjs -->
  <dependency>
   <groupId>org.seleniumhq.selenium</groupId>
   <artifactId>selenium-java</artifactId>
   <version>2.53.1</version>
  </dependency>
  <dependency>
   <groupId>com.github.detro</groupId>
   <artifactId>ghostdriver</artifactId>
   <version>2.1.0</version>
  </dependency>

  <!--svg-->
  <dependency>
   <groupId>com.github.hui.media</groupId>
   <artifactId>svg-core</artifactId>
   <version>2.5</version>
  </dependency>

这些依赖jar包我是上传到了公司的私服上了

若是朋友们下拉不下来

我提供给大家这些底层jar包的实现源码

https://gitee.com/pingfanrenbiji/quick-media

自行上传到自己的私服即可