WebCore Rendering I – The Basics

本文介绍了WebKit浏览器中的渲染机制,详细探讨了DOM树的概念及其组成部分,包括Document、Element和Text等节点类型。此外,还深入讲解了渲染树的构建与销毁过程、样式信息的获取以及CSS盒模型的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WebCoreRendering I – The Basics

原文地址:https://www.webkit.org/blog/114/webcore-rendering-i-the-basics/

 

DOMtree

  网页会被parse成一棵包含很多nodes的tree,称为DocumentObject Model(DOM)。DOM tree中所有nodes的基本类为Node。

相关代码:

Webkit/Source/WebCore/dom/Node.h

  这些nodes可以分成很多种类,其中与rendering代码相关的是以下几类:

Ø  Document :树的根总是document实例。一共有三个document类,Document, HTMLDocument 和SVGDocument, 第一个可以用于所有除了SVGdocuments 以为的XML documents,第二个只能用于HTML documents,并且是从Document继承而来的,第三个适用于SVG document,也是从Document继承而来。

相关代码:

Webkit/Source/WebCore/dom/Document.h

Webkit/Source/WebCore/html/HTMLDocument.h

Ø  Elements:所有在HTML和XML文件中的出现tag构成elements。从rendering 的角度来看,一个element就是一个有tag名的节点,可以获得其对应的子类和渲染时所需要的数据。

相关代码:

Webkit/Source/WebCore/dom/Element.h

Ø  Text: elements tags之间出现的一些原始文本就是文本节点。文本节点保存这些原始文本,render tree可以通过查询获得其字符数据。

相关代码:

Webkit/Source/WebCore/dom/Text.h

 

TheRender Tree

Rendering 的核心就是Render Tree,它与DOM tree类似,是一棵由对象组成的树,这些对象可以找到与DOM Tree中相对应的节点,但是Render Tree也包含一些在DOM Tree中找不到对应节点的对象。Render Tree中的所有对象的基本类型是RenderObject。

相关代码:

Webkit/Source/WebCore/rendering/RenderObject.h

下面列出的是最常用来遍历rendertree的方法:

RenderObject* firstChild() const;

RenderObject* lastChild() const;

RenderObject* previousSibling() const;

RenderObject* nextSibling() const;

下面的一个遍历renderer孩子节点的例子,这时render tree代码中非常普遍的一种遍历子节点方法。

for (RenderObject* child = firstChild();child; child = child->nextSibling()) {

   ...

}

 

创建Render Tree

 Renderers是通过在DOM tree上执行“attachment”操作获得的。当一个document已被解析,DOM nodes已被添加到其中,attach方法被调用,作用于这个DOM tree变可以获得其对应的renders。

Void attach()

  Attach方法会计算DOM node的style信息,如果一个node的display为none,或者它在一个display为none的父辈容器中,那么就不需要为它创建render。一个节点的子类和css样式值共同决定需要为它创建什么样的render。Attach方式是自顶向下的递归操作,所以子孙节点的render创建总是要晚于祖先节点。

 

销毁render tree

当相应的DOM nodes从document中被删除,或者是document被关掉(如document对应的tab或者窗口被关闭)时,detach方法被作用于DOM nodes上,就可以拆除并销毁对应的renders。

Void detach()

Detach方法是自底向上的递归操作,所以子孙节点的render销毁总是要先于祖先节点。

 

访问样式信息

在attachment过程中DOM会查询节点的CSS样式信息,该信息会被保存在一个RenderStyle对象中。相关代码:

Webkit/Source/WebCore/rendering/style/RenderStyle.h

Webkit支持的每一个css属性都可以通过这个对象来查询。RenderStyle对象是对引用计数的。如果一个DOM node创建了render,那么通过setStyle方法来链接render和样式信息。

Void setStyle(RenderStyle *)

一旦链接,render会增加改RenderStyle的引用计数,这个引用计数一直有效除非node的样式更新或者render被销毁。

RenderStyle对象可以通过RenderObject,用style方法获得:

RenderStyle * style() const

 

TheCSS Box Model

RenderObject中一个非常重要的子类是RenderBox,这个子类代表css box模型。其中包括很多对象,如borders, padding, margins, width and height.有些不是css box模型中的对象也是RenderBox的子类(如,SVG 对象)这实质上是个差错,将来再重构render tree部分代码时会被改正。

图1:css boxmodel

下面这些方法可以用来获得border/margin/padding widths。除非想要看原始的样式信息,否则RenderStyle是不应该被用到的。因为RenderObject中真正计算出来的数据与原始值可能会有很大的差别,特别是表格,表格中的cell padding可以有重叠部分,cell之间的boders也可以被收缩。

 

int marginTop() const;

int marginBottom() const;

int marginLeft() const;

int marginRight() const;

 

int paddingTop() const;

int paddingBottom() const;

int paddingLeft() const;

int paddingRight() const;

 

int borderTop() const;

int borderBottom() const;

int borderLeft() const;

int borderRight() const;

 

方法width()和height()给出的结果包括边框。

int width() const;

int height() const;

 

client box是指不包括边框和滚动条但包括padding的区域。

int clientLeft() const { returnborderLeft(); }

int clientTop() const { returnborderTop(); }

int clientWidth() const;

int clientHeight() const;

 

content box则是表示不包括边框,也不包括padding被区域。

IntRect contentBox() const;

int contentWidth() const { returnclientWidth() - paddingLeft() - paddingRight(); }

int contentHeight() const { returnclientHeight() - paddingTop() - paddingBottom(); }

当一个css box有横向或者纵向的滚动条时,滚动条会被放在边框与padding之间。滚动条的大小被包含在client width 和 client height中,但是滚动条不是content box的部分。滚动条的大小以及现在的位置也是可以通过RenderObject获得的。

int scrollLeft() const;

int scrollTop() const;

int scrollWidth() const;

int scrollHeight() const;

 

css boxes还有x,y坐标信息,这是相对坐标位置,相对于那个决定box具体位置的祖先。然而,也有很多例外,这部分是render tree代码中最容易混淆的地方。

 

int xPos() const;

int yPos() const;


资源下载链接为: https://pan.quark.cn/s/140386800631 通用大模型文本分类实践的基本原理是,借助大模型自身较强的理解和推理能力,在使用时需在prompt中明确分类任务目标,并详细解释每个类目概念,尤其要突出类目间的差别。 结合in-context learning思想,有效的prompt应包含分类任务介绍及细节、类目概念解释、每个类目对应的例子和待分类文本。但实际应用中,类目和样本较多易导致prompt过长,影响大模型推理效果,因此可先通过向量检索缩小范围,再由大模型做最终决策。 具体方案为:离线时提前配置好每个类目的概念及对应样本;在线时先对给定query进行向量召回,再将召回结果交给大模型决策。 该方法不更新任何模型参数,直接使用开源模型参数。其架构参考GPT-RE并结合相关实践改写,加入上下文学习以提高准确度,还使用BGE作为向量模型,K-BERT提取文本关键词,拼接召回的相似例子作为上下文输入大模型。 代码实现上,大模型用Qwen2-7B-Instruct,Embedding采用bge-base-zh-v1.5,向量库选择milvus。分类主函数的作用是在向量库中召回相似案例,拼接prompt后输入大模型。 结果方面,使用ICL时accuracy达0.94,比bert文本分类的0.98低0.04,错误类别6个,处理时添加“家居”类别,影响不大;不使用ICL时accuracy为0.88,错误58项,可能与未修改prompt有关。 优点是无需训练即可有较好结果,例子优质、类目界限清晰时效果更佳,适合围绕通用大模型api打造工具;缺点是上限不高,仅针对一个分类任务部署大模型不划算,推理速度慢,icl的token使用多,用收费api会有额外开销。 后续可优化的点是利用key-bert提取的关键词,因为核心词语有时比语意更重要。 参考资料包括
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值