最近花了点时间看了看chromium加载网页的逻辑。由于这段内容较为复杂,现在只看了一部分。现将主资源的加载记录下来。
注:下面提到的文件,如果没有指明目录,则在third_party/WebKit目录下
1. ContentViewCore执行loadUrl之后,经过一些逻辑(这些逻辑比较简单,这里不做介绍),最终会走到:render_frame_impl.cc的方法:RenderFrameImpl::OnNavigate
该方法中,有代码:frame->loadRequest(request);
2. 上面方法在thirdparty/WebKit目录下,WebFrameImpl.cpp文件中:WebFrameImpl::loadRequest
3. 接着走到:FrameLoader.cpp文件中,FrameLoader::load
4. 接着走到:同文件中方法:FrameLoader::loadWithNavigationAction
在该方法中,创建了DocumentLoader对象。
m_policyDocumentLoader = m_client->createDocumentLoader(m_frame, request, substituteData.isValid() ? substituteData : defaultSubstituteDataForURL(request.url()));
之后该DocumentLoader对象状态发生变化:
m_provisionalDocumentLoader = m_policyDocumentLoader.release();
5. 接着走到:DocumentLoader.cpp文件中方法: DocumentLoader::startLoadingMainResource()
该方法中有代码:m_mainResource = m_fetcher->fetchMainResource(cachedResourceRequest, m_substituteData);
6. 该代码是文件ResourceFetcher.cpp文件中方法:ResourceFetcher::fetchMainResource
7. 接着走到:同文件中的方法:ResourceFetcher::requestResource
该方法中有代码:resource = loadResource(type, request, request.charset()); 会创建Resouce对象。
紧接着有代码:resource->load(this, request.options());
8.上面方法是在文件:Resource.cpp中,Resource::load。
该方法中有代码:m_loader = ResourceLoader::create(fetcher, this, request, options);
m_loader->start();
创建了ResourceLoader对象。
9. 我们接着看 m_loader->start();。该代码是执行的ResourceLoader.cpp文件中方法:ResourceLoader::start()。
在该方法中有代码:m_host->willStartLoadingResource(m_request);
执行的是ResourceFetcher对象的方法:willStartLoadingResource
上面方法会调用文件ApplicationCacheHost.cpp中方法:willStartLoadingResource。
上面方法会调用content目录下文件:web_application_cache_host_impl.cc文件中方法:
WebApplicationCacheHostImpl::willStartSubResourceRequest。
继续看方法:ResourceLoader::start()。
该方法中有代码:m_loader = adoptPtr(blink::Platform::current()->createURLLoader());
这里创建了平台化的WebURLLoader对象。
10. 是面创建的WebURLLoader对象是文件: .../src/webkit/下的文件WebURLLoader_Impl.cc
我们继续看该文件中方法:WebURLLoaderImpl::Context::Start
该方法中,有代码:bridge_.reset(platform->CreateResourceLoader(request_info));
该代码执行的是文件:../src/content/下,webkitplatformsupport_impl.cc中方法:
WebKitPlatformSupportImpl::CreateResourceLoader
11. 上面方法会执行:content目录下:child_thread.cc文件的ChildThread::CreateBridge方法。
12. 上面方法会调用:content目录下:resource_dispatcher.cc文件中的方法:ResourceDispatcher::CreateBridge.
该方法会创建对象:IPCResourceLoaderBridge
13. 我们继续看10中提到的方法:WebURLLoaderImpl::Context::Start。该方法中有代码:bridge_->Start(this)
14. 通过11-12的解释,我们来看content目录下:IPCResourceLoaderBridge对象的Start方法。该方法是在content目录下文件:resource_dispatcher.cc中:IPCResourceLoaderBridge::Start(Peer* peer)
15. 上面方法会发送消息,该消息处理是在content目录下文件:resource_dispatcher_host_impl.cc中方法:ResourceDispatcherHostImpl::OnRequestResource
16. 上面方法会执行同文件的方法:ResourceDispatcherHostImpl::BeginRequest(方法。
17. 上面方法会执行同文件的方法:ResourceDispatcherHostImpl::BeginRequestInternal方法。
18. 上面方法会执行同文件的方法:ResourceDispatcherHostImpl::StartLoading方法
19. 上面方法会调用content目录下文件:resource_loader.cc中方法:ResourceLoader::StartRequest()
20. 上面方法会调用同文件的方法:ResourceLoader::StartRequestInternal()。该方法中有代码:request_->Start();
该request_是.../src/net目录下文件url_request.cc对象。
21. 我们来看.../src/net目录下文件url_request.cc中方法: URLRequest::Start()
22. 上面方法会调用同文件中的方法:URLRequest::StartJob.该函数最后一行:job_->Start();
该job_是.../src/webkit目录下appcache_url_request_job.cc对象。即调用的是文件appcache_url_request_job.cc的方法:AppCacheURLRequestJob::Start()
23. 上面方法又会调用同文件的方法: MaybeBeginDelivery();
24. 上面方法会调用同文件的方法:BeginDelivery
25. 上面方法会调用.../src/net/目录下文件:url_request_job.cc中的方法:URLRequestJob::NotifyRestartRequired
26. 上面方法调用.../src/net/目录下文件:url_request.cc中方法:URLRequest::Restart
27. 上面方法会调用同文件的方法:URLRequest::RestartWithJob
28. 上面方法调用同文件的方法:URLRequest::StartJob()
这次该文件中方法:job_->Start();会调用同目录下文件url_request_http_job.cc中方法:
URLRequestHttpJob::Start()
29. 上面方法调用同文件的方法:
URLRequestHttpJob::AddCookieHeaderAndStart()
30. 上面方法调用同文件的方法:URLRequestHttpJob::CheckCookiePolicyAndLoad
31. 上面方法调用同文件的方法:URLRequestHttpJob::DoStartTransaction()
32. 上面方法调用同文件的方法:URLRequestHttpJob::StartTransaction()。
33 . 上面方法调用同文件的方法:URLRequestHttpJob::StartTransactionInternal()
在这个方法中,主资源会下载下来。
啊,逻辑好多。看了两天代码才理顺清楚,赶紧记录下来,别忘记了。之后再看看子资源的加载和整个资源加载的各个组件之间的逻辑关系。
这里,要记载一点:在chromium34上网页加载的进度条,其数值不是按照主资源的加载来计算的,当主资源加载完毕之后,其进度条数值不到100;当然也不是按照子资源的下载完毕记录的。以百度首页为例,子资源还没有完全load完毕,进度条已经到100。关于进度条这个数值计算后面再去研究下。
还有一点:主资源会有cache么?我在查看百度首页的加载的过程中,明确看到主资源中可以有图片,而这些图片会生成cache。所以,单纯的说主资源没有cache是不正确的。
唉,还得搞其他的,这块以后有时间再深入研究下。理顺了资源的加载,对优化kernel性能是很有帮助的。
原文地址:http://blog.csdn.net/u011882998/article/details/41908973