Commit 7012b38d authored by panicker's avatar panicker Committed by Commit bot

Track frame context URL using first script heuristic

BUG=635596

Review-Url: https://codereview.chromium.org/2296923004
Cr-Commit-Position: refs/heads/master@{#418931}
parent 5b1f4e3e
...@@ -1126,6 +1126,7 @@ source_set("unit_tests") { ...@@ -1126,6 +1126,7 @@ source_set("unit_tests") {
"html/track/vtt/BufferedLineReaderTest.cpp", "html/track/vtt/BufferedLineReaderTest.cpp",
"html/track/vtt/VTTScannerTest.cpp", "html/track/vtt/VTTScannerTest.cpp",
"input/EventHandlerTest.cpp", "input/EventHandlerTest.cpp",
"inspector/InspectorWebPerfAgentTest.cpp",
"inspector/ProtocolParserTest.cpp", "inspector/ProtocolParserTest.cpp",
"layout/ImageQualityControllerTest.cpp", "layout/ImageQualityControllerTest.cpp",
"layout/InlineTextBoxTest.cpp", "layout/InlineTextBoxTest.cpp",
......
...@@ -4,22 +4,39 @@ ...@@ -4,22 +4,39 @@
#include "core/inspector/InspectorWebPerfAgent.h" #include "core/inspector/InspectorWebPerfAgent.h"
#include "core/dom/Document.h"
#include "core/dom/ExecutionContext.h"
#include "core/frame/LocalFrame.h" #include "core/frame/LocalFrame.h"
#include "core/frame/Location.h"
#include "core/inspector/InspectedFrames.h" #include "core/inspector/InspectedFrames.h"
#include "public/platform/Platform.h"
namespace blink { namespace blink {
InspectorWebPerfAgent::InspectorWebPerfAgent(InspectedFrames* inspectedFrames) InspectorWebPerfAgent::InspectorWebPerfAgent(InspectedFrames* inspectedFrames)
: m_inspectedFrames(inspectedFrames) : m_inspectedFrames(inspectedFrames)
{ {
Platform::current()->currentThread()->addTaskTimeObserver(this);
Platform::current()->currentThread()->addTaskObserver(this);
} }
InspectorWebPerfAgent::~InspectorWebPerfAgent() InspectorWebPerfAgent::~InspectorWebPerfAgent()
{ {
Platform::current()->currentThread()->removeTaskTimeObserver(this);
Platform::current()->currentThread()->removeTaskObserver(this);
} }
void InspectorWebPerfAgent::willExecuteScript(ExecutionContext* context) void InspectorWebPerfAgent::willExecuteScript(ExecutionContext* context)
{ {
// Heuristic for minimal frame context attribution: note the Location URL
// for each script execution. When a long task is encountered,
// if there is only one Location URL involved, then report it.
// Otherwise don't report Location URL.
// NOTE: This heuristic is imperfect and will be improved in V2 API.
// In V2, timing of script execution along with style & layout updates will be
// accounted for detailed and more accurate attribution.
if (context->isDocument())
m_frameContextLocations.add(toDocument(context)->location());
} }
void InspectorWebPerfAgent::didExecuteScript() void InspectorWebPerfAgent::didExecuteScript()
...@@ -28,6 +45,9 @@ void InspectorWebPerfAgent::didExecuteScript() ...@@ -28,6 +45,9 @@ void InspectorWebPerfAgent::didExecuteScript()
void InspectorWebPerfAgent::willProcessTask() void InspectorWebPerfAgent::willProcessTask()
{ {
// Reset m_frameContextLocations. We don't clear this in didProcessTask
// as it is needed in ReportTaskTime which occurs after didProcessTask.
m_frameContextLocations.clear();
} }
void InspectorWebPerfAgent::didProcessTask() void InspectorWebPerfAgent::didProcessTask()
...@@ -41,6 +61,7 @@ void InspectorWebPerfAgent::ReportTaskTime(double startTime, double endTime) ...@@ -41,6 +61,7 @@ void InspectorWebPerfAgent::ReportTaskTime(double startTime, double endTime)
DEFINE_TRACE(InspectorWebPerfAgent) DEFINE_TRACE(InspectorWebPerfAgent)
{ {
visitor->trace(m_inspectedFrames); visitor->trace(m_inspectedFrames);
visitor->trace(m_frameContextLocations);
} }
} // namespace blink } // namespace blink
...@@ -14,6 +14,7 @@ namespace blink { ...@@ -14,6 +14,7 @@ namespace blink {
class ExecutionContext; class ExecutionContext;
class LocalFrame; class LocalFrame;
class Location;
class InspectedFrames; class InspectedFrames;
// Inspector Agent for Web Performance APIs // Inspector Agent for Web Performance APIs
...@@ -22,6 +23,7 @@ class CORE_EXPORT InspectorWebPerfAgent final ...@@ -22,6 +23,7 @@ class CORE_EXPORT InspectorWebPerfAgent final
, public WebThread::TaskObserver , public WebThread::TaskObserver
, public scheduler::TaskTimeObserver { , public scheduler::TaskTimeObserver {
WTF_MAKE_NONCOPYABLE(InspectorWebPerfAgent); WTF_MAKE_NONCOPYABLE(InspectorWebPerfAgent);
friend class InspectorWebPerfAgentTest;
public: public:
explicit InspectorWebPerfAgent(InspectedFrames*); explicit InspectorWebPerfAgent(InspectedFrames*);
~InspectorWebPerfAgent(); ~InspectorWebPerfAgent();
...@@ -39,6 +41,7 @@ public: ...@@ -39,6 +41,7 @@ public:
private: private:
Member<InspectedFrames> m_inspectedFrames; Member<InspectedFrames> m_inspectedFrames;
HeapHashSet<Member<Location>> m_frameContextLocations;
}; };
} // namespace blink } // namespace blink
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/inspector/InspectorWebPerfAgent.h"
#include "core/frame/Location.h"
#include "core/inspector/InspectedFrames.h"
#include "core/testing/DummyPageHolder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "wtf/PtrUtil.h"
#include <memory>
namespace blink {
class InspectorWebPerfAgentTest : public ::testing::Test {
protected:
void SetUp() override;
LocalFrame* frame() const { return m_pageHolder->document().frame(); }
ExecutionContext* executionContext() const { return &m_pageHolder->document(); }
ExecutionContext* anotherExecutionContext() const { return &m_anotherPageHolder->document(); }
String frameContextURL();
int numUniqueFrameContextsSeen();
Persistent<InspectorWebPerfAgent> m_agent;
std::unique_ptr<DummyPageHolder> m_pageHolder;
std::unique_ptr<DummyPageHolder> m_anotherPageHolder;
};
void InspectorWebPerfAgentTest::SetUp()
{
m_pageHolder = DummyPageHolder::create(IntSize(800, 600));
m_pageHolder->document().setURL(KURL(KURL(), "https://example.com/foo"));
m_agent = new InspectorWebPerfAgent(InspectedFrames::create(frame()));
// Create another dummy page holder and pretend this is the iframe.
m_anotherPageHolder = DummyPageHolder::create(IntSize(400, 300));
m_anotherPageHolder->document().setURL(KURL(KURL(), "https://iframed.com/bar"));
}
String InspectorWebPerfAgentTest::frameContextURL()
{
// This is reported only if there is a single frameContext URL.
if (m_agent->m_frameContextLocations.size() != 1)
return "";
for (Member<Location> location : m_agent->m_frameContextLocations) {
return String(location->protocol()) + "//"
+ location->hostname() + location->pathname();
}
return "";
}
int InspectorWebPerfAgentTest::numUniqueFrameContextsSeen()
{
return m_agent->m_frameContextLocations.size();
}
TEST_F(InspectorWebPerfAgentTest, SingleScriptInTask)
{
m_agent->willProcessTask();
EXPECT_EQ(0, numUniqueFrameContextsSeen());
m_agent->willExecuteScript(executionContext());
EXPECT_EQ(1, numUniqueFrameContextsSeen());
m_agent->didExecuteScript();
m_agent->didProcessTask();
m_agent->ReportTaskTime(3719349.445172, 3719349.5561923); // Long task
EXPECT_EQ(1, numUniqueFrameContextsSeen());
EXPECT_EQ("https://example.com/foo", frameContextURL());
}
TEST_F(InspectorWebPerfAgentTest, MultipleScriptsInTask_SingleContext)
{
m_agent->willProcessTask();
EXPECT_EQ(0, numUniqueFrameContextsSeen());
m_agent->willExecuteScript(executionContext());
EXPECT_EQ(1, numUniqueFrameContextsSeen());
m_agent->didExecuteScript();
EXPECT_EQ("https://example.com/foo", frameContextURL());
m_agent->willExecuteScript(executionContext());
EXPECT_EQ(1, numUniqueFrameContextsSeen());
m_agent->didExecuteScript();
m_agent->didProcessTask();
m_agent->ReportTaskTime(3719349.445172, 3719349.5561923); // Long task
EXPECT_EQ(1, numUniqueFrameContextsSeen());
EXPECT_EQ("https://example.com/foo", frameContextURL());
}
TEST_F(InspectorWebPerfAgentTest, MultipleScriptsInTask_MultipleContexts)
{
m_agent->willProcessTask();
EXPECT_EQ(0, numUniqueFrameContextsSeen());
m_agent->willExecuteScript(executionContext());
EXPECT_EQ(1, numUniqueFrameContextsSeen());
m_agent->didExecuteScript();
EXPECT_EQ("https://example.com/foo", frameContextURL());
m_agent->willExecuteScript(anotherExecutionContext());
EXPECT_EQ(2, numUniqueFrameContextsSeen());
m_agent->didExecuteScript();
m_agent->didProcessTask();
m_agent->ReportTaskTime(3719349.445172, 3719349.5561923); // Long task
EXPECT_EQ(2, numUniqueFrameContextsSeen());
EXPECT_EQ("", frameContextURL());
}
TEST_F(InspectorWebPerfAgentTest, NoScriptInLongTask)
{
m_agent->willProcessTask();
m_agent->willExecuteScript(executionContext());
m_agent->didExecuteScript();
m_agent->didProcessTask();
m_agent->ReportTaskTime(3719349.445172, 3719349.445182);
m_agent->willProcessTask();
m_agent->didProcessTask();
m_agent->ReportTaskTime(3719349.445172, 3719349.5561923); // Long task
// Without presence of Script, FrameContext URL is not available
EXPECT_EQ(0, numUniqueFrameContextsSeen());
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment