blink渲染知识10 - render tree的构建点

何时在哪里thread构建的,先找到构建rendertree的code.

有RenderTreeBuilder类。

上面1.16rendering basics中讲了,RenderTree是通过对dom节点执行attach操作建立的。在dom被建立时,对其节点执行attach操作,即可创建renderobject, 建立rendertree. 当docuemnt关闭,或从dom中移除一个节点时,对该节点执行detach操作,就可将他对应的rendreobject从rendertree中移除。









下面看看最简单的调用element::attach的callstack,是在收到了html数据加载完之后,先对document节点执行attach,他会对子节点执行attach.

#0 WebCore::Element::attach(this=0x3ea08068, context=...) at../../third_party/WebKit/Source/core/dom/Element.cpp:1357

#1 0x60d15a9c inWebCore::Node::reattach(this=this@entry=0x3ea08068, context=...) at../../third_party/WebKit/Source/core/dom/Node.cpp:973

#2 0x60d0cbce inWebCore::Element::recalcOwnStyle(this=this@entry=0x3ea08068, change=change@entry=WebCore::Force) at../../third_party/WebKit/Source/core/dom/Element.cpp:1552

#3 0x60d0cd0a inWebCore::Element::recalcStyle(this=0x3ea08068, change=WebCore::Force, nextTextSibling=0x0) at../../third_party/WebKit/Source/core/dom/Element.cpp:1518

#4 0x60d034f6 inWebCore::Document::updateStyle(this=this@entry=0x3ea04000, change=<optimized out>,change@entry=WebCore::NoChange) at../../third_party/WebKit/Source/core/dom/Document.cpp:1946

#5 0x60d038e6 inWebCore::Document::updateRenderTree(this=this@entry=0x3ea04000,change=change@entry=WebCore::NoChange) at../../third_party/WebKit/Source/core/dom/Document.cpp:1882

#6 0x60d03a32 inWebCore::Document::updateRenderTreeIfNeeded(this=this@entry=0x3ea04000) at../../third_party/WebKit/Source/core/dom/Document.h:486

#7 0x60d04744 inWebCore::Document::finishedParsing(this=0x3ea04000) at../../third_party/WebKit/Source/core/dom/Document.cpp:4705

#8 0x60b9e1bc inWebCore::HTMLConstructionSite::finishedParsing (this=<optimizedout>) at../../third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp:543

#9 0x60bae026 inWebCore::HTMLTreeBuilder::finished(this=<optimized out>) at../../third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp:2796

#10 0x60b9f71c inWebCore::HTMLDocumentParser::end (this=this@entry=0x2e46c480) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:828

#11 0x60b9f730 inWebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd(this=this@entry=0x2e46c480) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:839

#12 0x60ba008c inWebCore::HTMLDocumentParser::prepareToStopParsing (this=0x2e46c480)at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:240

#13 0x60ba13d6 inWebCore::HTMLDocumentParser::processParsedChunkFromBackgroundParser(this=this@entry=0x2e46c480, popChunk=...) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:491

#14 0x60ba1538 inWebCore::HTMLDocumentParser::pumpPendingSpeculations(this=this@entry=0x2e46c480) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:530

#15 0x60ba1770 inWebCore::HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(this=0x2e46c480, chunk=...) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:363

#16 0x60b9b6c2 in operator()(p1=..., c=..., this=<optimized out>) at../../third_party/WebKit/Source/wtf/Functional.h:210

#17WTF::BoundFunctionImpl<WTF::FunctionWrapper<void(WebCore::HTMLDocumentParser::*)(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>,void (WTF::WeakPtr<WebCore::HTMLDocumentParser>,WTF::PassOwnPtr<W

#18 0x6154d7fc in operator()(this=0x650edab8) at../../third_party/WebKit/Source/wtf/Functional.h:577

#19 WTF::callFunctionObject(context=0x650edab8) at../../third_party/WebKit/Source/wtf/MainThread.cpp:62

#20 0x6144d6d6 in Run (a1=<optimizedout>, this=<synthetic pointer>) at../../base/bind_internal.h:171

#21 MakeItSo (a1=<optimized out>,runnable=...) at ../../base/bind_internal.h:871

#22 base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void(*)(void*)>, void (void*), void (void*)>, void(void*)>::Run(base::internal::BindStateBase*) (base=<optimizedout>)

at../../base/bind_internal.h:1169

#23 0x614f31f0 in Run(this=0x65ce4d00) at ../../base/callback.h:401

#24 base::MessageLoop::RunTask(this=this@entry=0x5abea008, pending_task=...) at../../base/message_loop/message_loop.cc:450

#25 0x614f329c inbase::MessageLoop::DeferOrRunPendingTask (this=this@entry=0x5abea008,pending_task=...) at ../../base/message_loop/message_loop.cc:462

#26 0x614f39b2 inbase::MessageLoop::DoWork (this=0x5abea008) at../../base/message_loop/message_loop.cc:576

#27 0x614f3f02 inbase::MessagePumpDefault::Run (this=0x5abea500, delegate=0x5abea008)at ../../base/message_loop/message_pump_default.cc:32

#28 0x614f35d6 inbase::MessageLoop::RunHandler (this=0x5abea008) at../../base/message_loop/message_loop.cc:400

#29 0x614fab78 in base::RunLoop::Run(this=this@entry=0x65ce4d70) at ../../base/run_loop.cc:49

#30 0x614f2c04 inbase::MessageLoop::Run (this=<optimized out>) at../../base/message_loop/message_loop.cc:293

#31 0x615036d6 inbase::Thread::ThreadMain (this=0x57b80c78) at../../base/threading/thread.cc:225

#32 0x615014fe in base::(anonymousnamespace)::ThreadFunc (params=<optimized out>) at../../base/threading/platform_thread_posix.cc:80

#33 0x40196a5c in __thread_entry ()from /tmp/tshao-adb-gdb-libs/system/lib/libc.so







void Element::attach(constAttachContext& context)

{

RenderTreeBuilder(this,//创建本节点的renderer.context.resolvedStyle).createRendererForElementIfNeeded();



ContainerNode::attach(context);//对本节点的childern执行attach.

。。。

}



这里使用RenderTreeBuilder.来针对一个dom节点建立renderobject并加入到rendertree中。

voidRenderTreeBuilder::createRendererForElementIfNeeded()

{

Element* element =toElement(m_node);

RenderStyle& style =this->style();



RenderObject* newRenderer = element->createRenderer(&style);

这里创建renderobject,实际调用RenderObject::createObject.

RenderObject* parentRenderer =this->parentRenderer();

RenderObject* nextRenderer =this->nextRenderer();

element->setRenderer(newRenderer);

newRenderer->setStyle(&style);// setStyle() can depend on renderer() already being set.

parentRenderer->addChild(newRenderer, nextRenderer);

创建renderer,并把其加入parentrenderer的孩子,够在renderobject tree.

}

我们看看如何创建RenderObject:

RenderObject*RenderObject::createObject(Element* element, RenderStyle* style)

{

ASSERT(isAllowedToModifyRenderTreeStructure(element->document()));



// Minimal support for contentproperties replacing an entire element.

// Works only if we have exactlyone piece of content and it's a URL.

// Otherwise acts as if wedidn't support this feature.

const ContentData* contentData =style->contentData();

if (contentData &&!contentData->next() && contentData->isImage() &&!element->isPseudoElement()) {

RenderImage* image = newRenderImage(element);

//RenderImageResourceStyleImage requires a style being present on theimage but we don't want to

// trigger a style changenow as the node is not fully attached. Moving this code to stylechange

// doesn't make sense as itshould be run once at renderer creation.

image->setStyleInternal(style);

if (const StyleImage*styleImage = static_cast<constImageContentData*>(contentData)->image()) {

image->setImageResource(RenderImageResourceStyleImage::create(const_cast<StyleImage*>(styleImage)));

image->setIsGeneratedContent();

} else

image->setImageResource(RenderImageResource::create());

image->setStyleInternal(nullptr);

return image;

}



switch (style->display()) {

case NONE:

return 0;

case INLINE:

return newRenderInline(element);

case BLOCK:

case INLINE_BLOCK:

return newRenderBlockFlow(element);

case LIST_ITEM:

return newRenderListItem(element);

case TABLE:

case INLINE_TABLE:

return newRenderTable(element);

case TABLE_ROW_GROUP:

case TABLE_HEADER_GROUP:

case TABLE_FOOTER_GROUP:

return newRenderTableSection(element);

case TABLE_ROW:

return newRenderTableRow(element);

case TABLE_COLUMN_GROUP:

case TABLE_COLUMN:

return newRenderTableCol(element);

case TABLE_CELL:

return newRenderTableCell(element);

case TABLE_CAPTION:

return newRenderTableCaption(element);

case BOX:

case INLINE_BOX:

return newRenderDeprecatedFlexibleBox(element);

case FLEX:

case INLINE_FLEX:

return newRenderFlexibleBox(element);

case GRID:

case INLINE_GRID:

return newRenderGrid(element);

}



return 0;

}

Codex内置浏览器:DOM直连式前端开发新范式 DOM(文档对象模型)是Web前端的核心运行时抽象,其本质是可编程、可遍历、可响应的结构化界面接口。传统上,开发者需通过DevTools手动探查、用Puppeteer模拟交互、靠OCR或静态HTML解析间接理解页面状态,导致调试低效、跨框架兼容性差、动态渲染信息丢失。Codex内置浏览器突破性地将Chromium渲染进程与AI推理环境深度耦合,实现原生级DOM访问——支持毫秒级获取computedStyle、boundingRect、Vue/React内部状态等真实引擎数据,并允许在页面JS上下文中直接执行 阅读详情

相关推荐

图像质量评估(5) -- 畸变(Distortion)

当图像中原本应该是直线的地方看起来发生了不自然的变形或扭曲时,我们称为图像畸变。有三种类型的镜头畸变:桶形畸变(后文使用英文barrel),枕形畸变(后文使用pincushion)和胡子畸变(后文使用英文wavef或mustache,这种畸变里包含了桶形畸变和枕形畸变)。有一个重要的点需要注意,根据透镜的类型以及透镜是否能够从相机中移除等条件不同,畸变会有不同的表现。 总的来说,旋转对称光学系统功能上会产生和物体几何相似的图形。但也有少数特殊的系统是例外,例如鱼眼镜头,这种镜头几何是故意设计为

vivo01的专栏 2万+

再学Blazor——组件建造者

以上就是组件建造者的完整实现过程,代码不长,但这些功能足以完成手动构建Blazor组件的需求。

knownchen的专栏 856

python-snap7 报错:can‘t find snap7 library. If installed, try running ldconfig

1、使用场景: Python 读取西门子 S7 系列 PLC 信息,会用到 snap7 库,网上也有很多案例。但是,运行时会报错:can't find snap7 library. If installed, try running ldconfig 2、解决方案: A、下载项目需要依赖的 dll、lib 文件: i、Sourceforge下载:https://sourceforge.net/projects/snap7/files/ ii、优快云下载(免费):https://dow.

蜡笔小新历险记的博客 3651

Blazor —— 用更能装X的方式编写组件(RenderTreeBuilder)

用 `razor` 的方式编写组件,这个学习过前端的应该都可以完成,但很多时候,我们需要学习更加高深的技术,**不光是可以来装X,更是可以把X升级成高处不胜寒的王者**。所以就来教教如何使用纯代码的方式来编写组件。

不忘初心 2663

搭建自己的MQTT服务器,实现设备上云(Ubuntu+EMQX)

这篇文章教大家在ECS云服务器上部署EMQX,搭建自己私有的MQTT服务器,配置EMQX实现设备上云,设备数据转发,存储;服务器我采用的华为云的ECS服务器,系统选择Ubuntu系统。

2万+

IgH EtherCAT 从入门到精通:第 30 章 实战:高可用 EtherCAT 系统设计

摘要:构建高可用EtherCAT系统的关键技术 本章详细介绍了工业级EtherCAT系统的高可用性设计方法,主要包括: 冗余链路架构:采用双网卡环形拓扑设计,主备网卡同时工作,通过IgH Master的冗余配置实现线缆故障自动切换。 状态监控机制:提供专用API实时监控主备链路状态,包括从站响应数、链路状态和冗余激活标志,形成完整的故障判断矩阵。 自动恢复功能:系统内置FSM架构支持热插拔自动检测和重配置,从站断线/重连时可自动完成状态恢复,同时允许应用层实施安全措施。 这些技术共同构成了生产环境下Ethe

从事嵌入式linux android驱动开发,拥有全栈能力 247

Blazor 服务端组件 Render, RenderFragment ,RenderTreeBuilder, CascadingValue/CascadingParameter 等等

一、组件 支撑Blazor的是微软的两大成熟技术,Razor模板和SignalR,两者的交汇点就是组件。通常,我们从ComponentBase派生的类型,或者创建的.razor 文件,就可以称作组件。基于这两大技术,组件也就具备了两大功能,1、生成html片段;2、维护组件状态。这里我们来说一下组件最基本的功能,生成html片段。 二、RenderTreeBuilder,RenderFragm...

4624

TPAMI 2025 | 从缺失碎片到杰作:基于上下文自适应扩散的图像修复

图像修复是一项具有挑战性的任务,尤其是要确保生成的内容与图像的现有部分无缝融合。尽管最近的扩散模型展现出了潜力,但它们在保持已知区域和未知(缺失)区域之间的连贯性方面常常遇到困难。这个问题源于扩散过程中缺乏明确的空间和语义对齐,导致生成的内容无法与原始图像平滑融合。此外,扩散模型通常依赖全局学习分布,而非局部特征,这使得生成的图像部分与现有图像部分之间存在不一致。在这项工作中,作者提出了ConFill,这是一个新颖的框架,引入了上下文自适应差异(CAD)模型,以确保在整个扩散过程中,已知区域和未知区域的中间

小白学视觉 240

Chromium网页Render Object Tree创建过程分析

在前面一文中,我们分析了网页DOM Tree的创建过程。网页DOM Tree创建完成之后,WebKit会根据它的内容创建一个Render Object Tree。Render Object Tree是和网页渲染有关的一个Tree。这意味着只有在DOM Tree中需要渲染的节点才会在Render Object Tree中有对应节点。本文接下来就分析网页Render Object Tre...

421

文末含资料链接和视频讲解!YOLOv8+RepVGG+QueryDet小目标检测终极指南:从理论到实战,突破遥感图像检测难题

QueryDet(Query Detection)机制代表了目标检测领域的一个重要范式转变。传统的目标检测方法基于anchor或anchor-free的密集预测,需要为图像中的每个可能位置生成预测。而QueryDet采用了稀疏查询的方式,通过少量的可学习查询向量来直接预测目标。 这种设计灵感来源于Transformer架构中的注意力机制。在自然语言处理中,Transformer通过query-key-value机制实现了高效的序列建模。QueryDet将这一思想引入到目标检测中,将检测问题转化为查询匹配问

FJN110的博客 387

STM32入门教程:无人机控制

我们将会一步一步引导您完成无人机的控制代码,包括无人机的姿态控制、飞行控制和通信控制等。第三步:配置无人机姿态控制 无人机的姿态控制是指控制无人机在空中的倾斜和转向。为了实现姿态控制,我们需要使用加速度计和陀螺仪传感器来获取无人机的姿态信息,并使用PID控制算法来控制无人机的姿态。在这一步骤中,您需要根据您使用的具体传感器和控制算法的要求进行更详细的配置和编码。在通信控制中,您需要考虑到通信的稳定性和可靠性。第五步:通信控制 无人机的通信控制是指与地面站或其他设备进行通信,传输飞行数据和接收飞行指令。

m0_75244442的博客 748

Blazor ——支持 UI 片段的 RenderFragment

使用真实的示例说清楚 RenderFragment 和 RanderFragment<TValue> 的用法和区别

不忘初心 3998

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

blink渲染知识11 - renderlayer tree的构建点

在收到了数据后,网页加载完成,创建rendertree时,也会对应创建renderlayer. 创建renderlayer的Callstack: #0 WebCore::RenderLayer::RenderLayer (this=0x69014000,renderer=0x69004000, type=) at../../third_party/WebKit/Source/cor

477

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

浏览器内核渲染引擎渲染原理

浏览器加载了html和css是怎样呈现在浏览器上面的呢? 这个底层的原理需要我们了解 这样我们才能够进一步做出一些性能优化浏览器渲染大体上分为以下五步 处理html生成 DOM(Document Object Model) Tree 处理css生成 CSSOM(CSS Object Model) Tree DOM树与CSS-DOM树合并为Render树 对Render树进行布局计算 遍历Rend

尐轩web前端网络日志 7297

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

WebKit与Blink工作流程以及显示页面

作为一个Render与Layout引擎,他们的工作步骤 1 Parse HTML document,结果是把取到的TAG生成dom的nodes,存到dom tree中,DOM tree就是网页内容的tree。同时, style的数据也是在这里parse的,CSS和in style element。 2 根据css和html里面的显示信息,对dom的node创建render tree. render...

Neo_Zhang888的博客 569

DOM结点的渲染(attach)

tuhuolong的专栏 1064

浏览器查看HTML源码的三层真相:原始HTML、DOM与渲染树

HTML源码是Web开发与诊断的基础概念,其本质是HTTP响应体中的原始HTML字符串,遵循HTML标准协议解析生成DOM树,并进一步结合CSSOM构建渲染树。理解这三层结构差异,是准确调试页面行为、保障SEO效果、识别安全风险的关键技术前提。Chrome和Firefox等主流浏览器在源码呈现上存在解析容错性差异,而开发者工具Elements面板展示的是JS动态修改后的实时DOM,与右键‘查看网页源代码’所见的静态初始HTML截然不同。掌握这些原理,才能在前端调试、内容运营、搜索引擎优化及安全审计等多元场景

weixin_33739523的博客 720

WebHostView技术解析:浏览器内核中的高级渲染与进程隔离

WebHostView是现代浏览器内核中实现桌面级Web内容渲染的核心组件,它通过独立进程沙箱隔离和硬件加速渲染管线等技术,提供了比传统WebView更强大的功能支持。在浏览器多进程架构中,WebHostView运行在独立的渲染进程,通过Mojo框架实现进程间通信,确保资源隔离与安全性。其技术价值在于支持跨域资源共享(CORS)策略的动态调整,并能通过Native Bindings暴露文件系统访问、窗口管理等桌面能力。在360浏览器等产品中,WebHostView广泛应用于标签页渲染、扩展程序运行等场景,通

weixin_30861459的博客 393

浏览器渲染过程与原理

浏览器发出请求之后浏览器发出请求–》DNS查询–》DNS缓存–》请求到服务器–》服务器代码运行–》返回HTML文档–》浏览器渲染页面浏览器引擎:JS引擎和渲染引擎浏览器渲染引擎:IE(Trident) Chrome(Blink) Firefox(Gecko) Opera(Blink) Safari(Webkit) UC(U3) QQ浏览器/微信webview(X5/Blink):原来是X

Jancy的博客 705

Webkit架构解析与实战:从渲染原理到性能优化

浏览器渲染引擎是现代Web应用的核心技术组件,负责将HTML、CSS和JavaScript代码转换为用户可视的网页界面。其工作原理遵循从解析、构建对象模型到布局、绘制、合成的完整流水线,这一流程直接决定了页面的加载速度、交互流畅度和渲染一致性。在工程实践中,深入理解渲染引擎的内部机制,特别是布局(Reflow)与绘制(Painting)的触发条件与性能开销,对于进行有效的前端性能优化至关重要。通过开发者工具深入分析渲染过程,并结合对内存管理与图层合成机制的理解,开发者可以系统性解决常见的性能瓶颈,如布局抖动

weixin_34357928的博客 355

Inlyne技术架构深度解析:GPU驱动的无浏览器Markdown渲染引擎实现原理

Inlyne作为一款创新的GPU加速无浏览器Markdown查看工具,其技术架构代表了现代文档渲染技术的前沿方向。本文将深入剖析Inlyne的设计理念、核心实现机制以及在实际开发场景中的应用价值,为技术开发者提供全面的架构分析。 ## 渲染引擎底层架构设计 ### 基于WGPU的图形渲染管线 Inlyne的渲染引擎摒弃了传统浏览器的复杂渲染流程,直接采用WGPU(WebGPU的Rust实现)

gitblog_00119的博客 371

IE浏览器退役与现代浏览器核心技术解析

浏览器作为互联网入口,其架构演进直接影响用户体验与网络安全。现代浏览器采用多进程架构,通过独立渲染进程与严格沙箱机制确保稳定性与安全性,解决了传统IE浏览器单进程架构导致的安全漏洞与崩溃问题。核心技术栈包括WebKit/Blink渲染引擎实现的高效页面渲染,以及扩展生态支持的企业级功能定制。随着PWA(渐进式Web应用)和WebAssembly等技术的普及,浏览器已从简单的网页查看器发展为功能强大的应用平台。在IE退役背景下,企业迁移需重点关注兼容性评估与渐进式改造策略,以适应现代Web标准。

weixin_33841503的博客 475

浏览器工作原理

hadry123的博客 2755

福瑞兽剧动画预告片制作全流程:从角色资产到渲染输出

在动画制作领域,角色资产的质量直接决定成片表现,尤其面对福瑞兽剧这类特殊题材时,兽人角色的头部拓扑、骨骼绑定与毛发材质都远超常规人物模型的复杂度。理解这些技术原理,是构建高效动画制作管线的基础。通过合理的项目目录规范、版本管理与渲染参数控制,团队能够在保证画面质量的同时,显著减少返工与渲染等待时间。这类能力广泛应用于独立游戏开发、动画短片量产、视频创作等场景,无论是角色预告片还是完整剧集,都依赖从建模、绑定、动画到渲染输出的稳定流程。当制作节奏进入第二支预告片的迭代阶段,更需要以资产复用与镜头表管理为核心,

weixin_33904756的博客 298

告别Electron:GPUIX如何用React+Rust打造原生GPU加速桌面应用

GPUIX 是一个开源框架,帮助开发者用 **React + Rust** 构建**原生 GPU 加速桌面应用**。它不需要 Electron,也没有任何 Web 视图(WebView)——你的 React 组件通过 Metal、DirectX 或 Vulkan 直接渲染到 GPU 上,布局由 Rust 端的 Flexbox 引擎完成。对 React 开发者来说,上手成本几乎为零:照写 JSX 和

gitblog_00006的博客 1110
上一篇: blink渲染知识9-chromium webview硬件渲染的演进
下一篇: blink渲染知识11 - renderlayer tree的构建点
csshell2002
博客等级 码龄11年 30粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值