《WebKit 技术内幕》之六(3): CSS解释器和样式布局

3 WebKit布局

3.1 基础

        当WebKit创建RenderObject对象之后,每个对象是不知道自己的位置、大小等信息的,WebKit根据框模型来计算它们的位置、大小等信息的过程称为布局计算(或者称为排版)。

        图描述了这一过程中涉及的主要WebKit类。第5章描述过Frame类,用于表示网页的框结构,每个框都有一个FrameView类,用于表示框的视图结构。

                                        图布局计算中的主要WebKit类

        FrameView类主要负责视图方面的任务,例如网页视图大小、滚动、布局计算、绘图等,它是一个总入口类。图中标注了两个跟布局计算密切相关的函数——“layout”和“needsLayout”,它们用来布局计算和决定是否需要布局计算,实际的布局计算则是在RenderObject类中。

        布局计算根据其计算的范围大致可以分为两类:第一类是对整个RenderObject树进行的计算;第二类是对RenderObject树中某个子树的计算,常见于文本元素或者是overflow:auto块的计算,这种情况一般是其子树布局的改变不会影响其周围元素的布局,因而不需要重新计算更大范围内的布局。

3.2 布局计算

        布局计算是一个递归的过程,这是因为一个节点的大小通常需要先计算它的子女节点的位置、大小等信息。

        下图描述了RenderObject节点计算布局的主要过程,中间省略了很多判断和步骤,主要逻辑都是由RenderObject类的“layout”函数来完成。

                                        图布局计算过程

        首先,该函数会判断RenderObject节点是否需要重新计算,通常这需要通过检查位数组中的相应标记位、子女是否需要计算布局等来确定。

        其次,该函数会确定网页的宽度和垂直方向上的外边距,这是因为网页通常是在垂直方向上滚动,而水平方向尽量不需要滚动。

        再次,该函数会遍历其每一个子女节点,依次计算它们的布局。每一个元素会实现自己的“layout”函数,根据特定的算法来计算该类型元素的布局。如果页面元素定义了自身的宽高,那么WebKit按照定义的宽高来确定元素的大小,而对于像文本节点这样的内联元素则需要结合其字号大小及文字的多少等来确定其对应的宽高。如果页面元素所确定的宽高超过了布局容器包含块所能提供的宽高,同时其overflow的属性为visible或auto,WebKit则会提供滚动条来保证可以显示其所有内容。除非网页定义了页面元素的宽高,一般来说页面元素的宽高是在布局的时候通过相关计算得出来的。如果元素它有子女,则WebKit需要递归这一过程。

        最后,节点根据它的子女们的大小计算得出自己的高度,整个过程结束。

        哪些情况下需要重新计算布局呢?总体来讲,只要样式发生变化,WebKit都需要重新计算,但是实际场景中,有以下一些情况。

        首先,当网页首次被打开的时候,浏览器设置网页的可视区域(viewport),并调用计算布局的方法。这其实也描述了一种常见的情景,就是当可视区域发生变化的时候,WebKit都需要重新计算布局,这是因为网页的包含块的大小发生了改变。

        其次,网页的动画会触发布局计算。当网页显示结束后,动画可能改变样式属性,那么WebKit就需要重新计算。

        然后,JavaScript代码通过CSSOM等直接修改样式信息,它们也会触发WebKit重新计算布局。

        最后,用户的交互也会触发布局计算,例如翻滚网页,这会触发新区域布局的计算。

        CSS的布局计算是以包含块和框模型为基础的,这表示这些元素的布局计算都依赖于块,例如“div”通常就是一个块,如前面所述它们通常是在垂直方向上展开。但是,CSS标准也规定了行布局形式,这就是内联元素。内联元素表现的是行布局形式,就是说这些元素以行进行显示。以“div”元素为例,如果设置属性“style”为“display:inline”时,则该元素是内联元素,那么它可能与前面的元素在同一行。如果该元素没有设置这个属性时,则是块元素,那么在新的行里显示。这显然会增加处理的复杂性,为此,WebKit的处理方式是——对于一个块元素对应的RenderObject对象,它的子女要么都是块元素的RenderObject对象,要么都是非内联元素对应的RenderObject对象,这可以通过建立匿名块(Anonymous Block)对象来实现,在下一章也会作介绍。 (2)

        布局计算相对也是比较耗时间的,更糟糕的是,一旦布局发生变化,WebKit就需要后面的重新绘制操作。另一方面,减少样式的变动而依赖现在HTML5的新功能可以有效地提高网页的渲染效率,这些在后面介绍绘图的时候一并分析。

3.3 布局测试

        在这里介绍布局测试(Layout Tests)貌似也有点文不对题,因为其实布局测试不仅测试布局,还包括渲染等综合渲染结果。本章主要介绍CSS的样式计算和布局计算,不过它们也或多或少存在联系。

        布局测试可以说是WebKit中最重要并且最著名的测试了,用于测试网页的整个渲染结果,包括网页加载和渲染整个过程。渲染引擎要处理各式各样越来越复杂的网页,这需要布局测试来保证引擎的渲染结果的正确性。基本测试工作方式是:预先准备大量用于单元测试的网页和期望的渲染结果,然后使用WebKit编译出来的DumpRenderTree(DRT)来测试网页,把得到的结果和期望的结果进行对比,以检查WebKit引擎对网页排版布局等的正确性。每个WebKit的移植都会提供一个DumpRenderTree, (3) 通常由于移植的差异性,它们的期望结果也不一样,所以通常每个移植都有特殊的期望结果。

        每个测试都会有一个或者多个期望结果,一般情况下,期望结果是一些文本结果。但是,对一些复杂的测试,单纯的文本不能够满足需求,因为测试渲染结果可能需要比较布局、字体、图片等,所以这时候期望结果其实是一幅图片(还有其他类型),这个图片其实才是网页应该渲染的结果。可惜的是,由于字体、平台的样式等差异性(如Qt、GTK等就不一样),相同的网页渲染出的结果可能不一样,所以,读者可以看到布局测试对不同的移植会有不同的期望结果。

        一般来讲,当开发者提交新的代码补丁包时,需要先进行布局测试,只有当该测试通过并且没有造成其他的测试出现新错误的时候,才有可能被WebKit项目所接受。如果读者提交代码的目的是解决一个新问题,那么,强烈建议读者提交一个新的测试用例来保证代码的正确性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/337842.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

浅谈 ret2text

文章目录 ret2text无需传参重构传参函数调用约定x86x64 ret2text ret2text就是执行程序中已有的代码,例如程序中写有system等系统的调用函数 无需传参 如果程序的后门函数参数已经满足 getshell 的需求,那么就可以直接溢出覆盖 ret 地址不用考虑传参问…

SystemC学习笔记(三) - 查看模块的波形

简述 波形在Simulation/Emulation中地位十分重要,尤其是在研发初期,只能通过波形来查看软件hang住的位置。 对于TLM来说,查看波形一般是指查看pvbus上的transaction,而对于SystemC本身来说,查看波形就是使用Gtkwave或…

WeChall

WeChall-Scored Challenges 一、Get Sourced二、Stegano I三、Crypto - Caesar I四、WWW-Robots五、 ASCII六、URL七、Christmas Hippety八、No DNS 网站链接:https://www.wechall.net/challs/Training/by/chall_score/ASC/page-1 一、Get Sourced 题目链接&#…

HTML+JavaScript-01

说明 之前有一篇JavaWeb-JavaScript中只是简单介绍了一点JavaScript的内容,这篇笔记算是续写的,但是从01开始编号。 引入js文件 html、css、js俗称前端三剑客,一般都是分开写,先写框架、再写css、最后写js。因此在工程量大的情…

HarmonyOS—配置开发环境

应用/服务支持API Version 4至9,首次使用DevEco Studio,工具的配置向导会引导您下载SDK及工具链。配置向导默认下载 API Version 9的SDK及工具链,如需下载API Version 4至8,可在工程配置完成后,进入HarmonyOS SDK界面手…

福建专业建筑清水模板 — 安全可靠的选择

在福建地区的建筑工程中,选择高质量的清水模板对于确保结构的美观和工程的安全至关重要。我们能强优品木业提供的专业建筑清水模板,以其卓越的质量和安全性,成为施工团队的首选。 产品特性 优质材料制作:选用高品质木材制作&…

机械设计-哈工大课程学习-螺纹连接

圆柱螺纹主要几何参数螺纹参数 ①外径(大径),与外螺纹牙顶或内螺纹牙底相重合的假想圆柱体直径。螺纹的公称直径即大径。 ②内径(小径),与外螺纹牙底或内螺纹牙顶相重合的假想圆柱体直径。 ③中径&#xff…

React 初次接触

背景 还是为了完善高大上的在线文档系统,虽然比着葫芦画瓢的修改了一些所谓的代码,慢慢的才发现,原来这就是传说中的React,所以有比较又要囫囵吞枣一下React。 基本原理 参照《React技术揭秘》 网上有电子版 ,应该是…

selenium-java中切换iframe

1、当iframe中有固定的name或者id时可以通过name和id进行切换,代码如下 driver.switchTo().frame("name"); 2、当iframe中没有固定的name或者id时可以通过iframe角标进行切换,在浏览器通过ctrlf快捷键,搜索标签框输入//iframe;来查看当前ifr…

11、Kafka ------ Kafka 核心API 及 生产者API 讲解

目录 Kafka核心API 及 生产者API讲解★ Kafka的核心APIKafka包含如下5类核心API: ★ 生产者APIKafka 的API 文档 ★ 使用生产者API发送消息 Kafka核心API 及 生产者API讲解 官方文档 ★ Kafka的核心API Kafka包含如下5类核心API: Producer API&#x…

一维数组2和二维数组1

1.一维数组在内存中的储存 在前面创建的数组中,每个元素是怎么储存的呢?我们通过观察元素的地址来看看吧。 %p是用来打印地址的。 结果为: 由此可看出每个地址都相隔一个int类型的距离,可以看出数组在内存中是连续存放的。也就是…

Pytest 测试框架与Allure 测试报告——Allure2测试报告-L1

目录: allure2安装 Allure2介绍Allure2报告展示Allure2报告展示-首页概览Allure2报告展示-用例详情页Allure2安装Allure2下载与安装Allure环境验证插件安装-Python插件安装-Java验证插件安装-Javaallure2运行方式 生成测试报告流程使用Allure2运行方式-Python使用A…

Android逆向之指令集和CPU架构

文章目录 前言引子 指令集复杂指令集(CISC)精简指令集(RISC)RISC-VARM和x86的区别指令集和汇编汇编语言是用人类看得懂的语言来描述指令集不同指令集对应不同的汇编语言 ARM和x86指令集差异ARM指令集x86指令集 CPU架构和ABI什么是…

YARN节点故障的容错方案

YARN节点故障的容错方案 1. RM高可用1.1 选主和HA切换逻辑 2. NM高可用2.1 感知NM节点异常2.2 异常NM上的任务处理 4. 疑问和思考4,1 RM感知NM异常需要10min,对于app来说是否太长了? 5. 参考文档 本文主要探讨yarn集群的高可用容错方案和容错能力的探讨。…

HCIP之BGP联邦实验

华子目录 实验拓扑及要求规划网段和IP地址实验步骤配置IP地址先让IGP通建BGP邻居修改ospf下环回接口网络类型修改联邦之间的最大跳数每台运行BGP的路由器批量宣告路由修改本地下一跳测试 实验拓扑及要求 规划网段和IP地址 实验步骤 配置IP地址 r1配置,依次类推 […

软件需求规格说明书-word

软件需求规格说明书编写规范 1.项目背景 2.项目目标 3.系统架构 4.总体流程 5.名称解释 6.功能模块 软件开发全文档获取:软件项目开发全套文档下载_软件项目文档-CSDN博客

【Linux学习】进程信号

目录 十七.进程信号 导言 17.1 linux中的信号列表 17.2 标准信号与实时信号 17.3 信号的产生 17.3.1 通过终端按键产生信号 17.3.2 调用系统函数产生信号 17.3.3 软件条件产生信号 17.3.4 硬件异常产生信号 17.3.5 【补充】核心转储 Core Dump 17.4 信号的阻塞 17.4.1 信号相关…

Hive-SQL语法大全

Hive SQL 语法大全 基于语法描述说明 CREATE DATABASE [IF NOT EXISTS] db_name [LOCATION] path; SELECT expr, ... FROM tbl ORDER BY col_name [ASC | DESC] (A | B | C)如上语法,在语法描述中出现: [],表示可选,如上[LOCATI…

vue3-模版引用

模版引用 ref 属性 场景&#xff1a;需要直接访问底层 DOM 元素。 方法&#xff1a;使用特殊的 ref 属性。 <input ref"input">ref 属性 允许我们在一个特定的 DOM 元素或子组件实例被挂载后&#xff0c;获得对它的直接引用。 访问模板引用 小 Demo: 当 i…

游戏渲染管道

高级的渲染步骤是由管道&#xff08;软件架构&#xff09;实现&#xff0c;各个阶段会操作输入流中的数据项&#xff0c;并对输出流产生数据。 管道每个阶段独立于其他阶段&#xff0c;所以管道的最大有点在于非常适合并行化。 渲染管道分为3个概要阶段。但在这里多讲几个阶段…
最新文章