网站优化

网站优化

Products

当前位置:首页 > 网站优化 >

从Chrome源码看浏览器如何加载资源

GG网络技术分享 2025-03-18 16:08 0


对浏览器加载资源有很多不确定性,例如:

  1. css/font的资源的优化级会比img高,资源的优化级是怎么确定的呢?
  2. 资源优先级又是如何影响加载的先后顺序的?
  3. 有几种情况可能会导致资源被阻止加载?

通过源码可以找到答案。此次源码解读基于Chromium 64(10月28日更新的源码)。

下面通过加载资源的步骤,依次说明。

1. 开始加载

通过以下命令打开Chromium,同时打开一个网页:

chromium --renderer-startup-dialog https://www.baidu.com

Chrome会在DocumentLoader.cpp里面通过以下代码去加载:

main_resource_=RawResource::FetchMainResource(fetch_params,Fetcher(),substitute_data_);

页面资源属于MainRescouce,Chrome把Rescource归为以下几种:

enumType:uint8_t{kMainResource,kImage,kCSSStyleSheet,kScript,kFont,kRaw,kSVGDocument,kXSLStyleSheet,kLinkPrefetch,kTextTrack,kImportResource,kMedia,// Audio or video file requested by a HTML5 media elementkManifest,kMock// Only for testing};

除了常见的image/css/js/font之外,我们发现还有像textTrack的资源,这个是什么东西呢?这个是video的字幕,使用webvtt格式:

<videocontrolsposter="/images/sample.gif"><sourcesrc="sample.mp4"type="video/mp4"><trackkind="captions"src="sampleCaptions.vtt"srclang="en">video>

还有动态请求ajax属于Raw类型。因为ajax可以请求多种资源。

MainResource包括location即导航输入地址得到的页面、使用frame/iframe嵌套的、通过超链接点击的页面以及表单提交这几种。

接着交给稍底层的ResourceFecher去加载,所有资源都是通过它加载:

fetcher->RequestResource(params,RawResourceFactory(Resource::kMainResource),substitute_data)

在这个里面会先对请求做预处理。

2. 预处理请求

每发个请求会生成一个ResourceRequest对象,这个对象包含了http请求的所有信息:

包括url、http header、http body等,还有请求的优先级信息等:

然后会根据页面的加载策略对这个请求做一些预处理,如下代码:

PrepareRequestResultresult=PrepareRequest(params,factory,substitute_data,identifier,blocked_reason);if(result==kAbort)returnnullptr;if(result==kBlock)returnResourceForBlockedRequest(params,factory,blocked_reason);

prepareRequest会做两件事情,一件是检查请求是否合法,第二件是把请求做些修改。如果检查合法性返回kAbort或者kBlock,说明资源被废弃了或者被阻止了,就不去加载了。

被block的原因可能有以下几种:

enumclassResourceRequestBlockedReason{kCSP,// CSP内容安全策略检查kMixedContent,// mixed contentkOrigin,// secure originkInspector,// devtools的检查器kSubresourceFilter,kOther,kNone};

源码里面会在这个函数做合法性检查:

blocked_reason=Context().CanRequest(/*参数省略*/);if(blocked_reason!=ResourceRequestBlockedReason::kNone){returnkBlock;}

CanRequest函数会相应地检查以下内容:

(1)CSP(Content Security Policy)内容安全策略检查

CSP是减少XSS攻击一个策略。如果我们只允许加载自己域的图片的话,可以加上下面这个meta标签:

<metahttp-equiv="Content-Security-Policy"content="img-src "self";">

或者是后端设置这个http响应头。

self表示本域,如果加载其它域的图片浏览器将会报错:

所以这个可以防止一些XSS注入的跨域请求。

源码里面会检查该请求是否符合CSP的设定要求:

constContentSecurityPolicy*csp=GetContentSecurityPolicy();if(csp

标签:

提交需求或反馈

Demand feedback