OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/paint/FirstMeaningfulPaintDetector.h" | 5 #include "core/paint/FirstMeaningfulPaintDetector.h" |
6 | 6 |
7 #include "core/paint/PaintTiming.h" | 7 #include "core/paint/PaintTiming.h" |
8 #include "core/testing/DummyPageHolder.h" | 8 #include "core/testing/DummyPageHolder.h" |
| 9 #include "platform/scheduler/test/fake_web_task_runner.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
10 #include "wtf/text/StringBuilder.h" | 11 #include "wtf/text/StringBuilder.h" |
11 | 12 |
12 namespace blink { | 13 namespace blink { |
13 | 14 |
14 class FirstMeaningfulPaintDetectorTest : public testing::Test { | 15 class FirstMeaningfulPaintDetectorTest : public testing::Test { |
15 protected: | 16 protected: |
16 void SetUp() override { | 17 void SetUp() override { |
17 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); | 18 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); |
18 s_timeElapsed = 0.0; | 19 s_timeElapsed = 0.0; |
19 m_originalTimeFunction = setTimeFunctionsForTesting(returnMockTime); | 20 m_originalTimeFunction = setTimeFunctionsForTesting(returnMockTime); |
| 21 m_taskRunner = adoptRef(new scheduler::FakeWebTaskRunner); |
| 22 detector().m_network0QuietTimer.moveToNewTaskRunner(m_taskRunner); |
| 23 detector().m_network2QuietTimer.moveToNewTaskRunner(m_taskRunner); |
20 } | 24 } |
21 | 25 |
22 void TearDown() override { | 26 void TearDown() override { |
23 setTimeFunctionsForTesting(m_originalTimeFunction); | 27 setTimeFunctionsForTesting(m_originalTimeFunction); |
24 } | 28 } |
25 | 29 |
26 Document& document() { return m_dummyPageHolder->document(); } | 30 Document& document() { return m_dummyPageHolder->document(); } |
27 PaintTiming& paintTiming() { return PaintTiming::from(document()); } | 31 PaintTiming& paintTiming() { return PaintTiming::from(document()); } |
28 FirstMeaningfulPaintDetector& detector() { | 32 FirstMeaningfulPaintDetector& detector() { |
29 return paintTiming().firstMeaningfulPaintDetector(); | 33 return paintTiming().firstMeaningfulPaintDetector(); |
30 } | 34 } |
31 | 35 |
32 void simulateLayoutAndPaint(int newElements) { | 36 void simulateLayoutAndPaint(int newElements) { |
33 StringBuilder builder; | 37 StringBuilder builder; |
34 for (int i = 0; i < newElements; i++) | 38 for (int i = 0; i < newElements; i++) |
35 builder.append("<span>a</span>"); | 39 builder.append("<span>a</span>"); |
36 document().write(builder.toString()); | 40 document().write(builder.toString()); |
37 document().updateStyleAndLayout(); | 41 document().updateStyleAndLayout(); |
38 detector().notifyPaint(); | 42 detector().notifyPaint(); |
39 } | 43 } |
40 | 44 |
41 void simulateNetworkStable() { detector().networkStableTimerFired(nullptr); } | 45 void simulateNetworkStable() { |
| 46 document().setParsingState(Document::FinishedParsing); |
| 47 detector().network0QuietTimerFired(nullptr); |
| 48 detector().network2QuietTimerFired(nullptr); |
| 49 } |
| 50 |
| 51 void simulateNetwork0Quiet() { |
| 52 document().setParsingState(Document::FinishedParsing); |
| 53 detector().network0QuietTimerFired(nullptr); |
| 54 } |
| 55 |
| 56 void simulateNetwork2Quiet() { |
| 57 document().setParsingState(Document::FinishedParsing); |
| 58 detector().network2QuietTimerFired(nullptr); |
| 59 } |
| 60 |
| 61 void setActiveConnections(int connections) { |
| 62 double time0 = 0.0; |
| 63 double time2 = 0.0; |
| 64 m_taskRunner->setTime(returnMockTime()); |
| 65 if (isNetwork0QuietTimerActive()) |
| 66 time0 = detector().m_network0QuietTimer.nextFireInterval(); |
| 67 if (isNetwork2QuietTimerActive()) |
| 68 time2 = detector().m_network2QuietTimer.nextFireInterval(); |
| 69 |
| 70 detector().setNetworkQuietTimers(connections); |
| 71 |
| 72 m_0QuietTimerRestarted = |
| 73 isNetwork0QuietTimerActive() && |
| 74 detector().m_network0QuietTimer.nextFireInterval() != time0; |
| 75 m_2QuietTimerRestarted = |
| 76 isNetwork2QuietTimerActive() && |
| 77 detector().m_network2QuietTimer.nextFireInterval() != time2; |
| 78 } |
| 79 |
| 80 bool isNetwork0QuietTimerActive() { |
| 81 return detector().m_network0QuietTimer.isActive(); |
| 82 } |
| 83 |
| 84 bool isNetwork2QuietTimerActive() { |
| 85 return detector().m_network2QuietTimer.isActive(); |
| 86 } |
| 87 |
| 88 bool isNetwork0QuietTimerRestarted() { return m_0QuietTimerRestarted; } |
| 89 bool isNetwork2QuietTimerRestarted() { return m_2QuietTimerRestarted; } |
42 | 90 |
43 private: | 91 private: |
44 static double returnMockTime() { | 92 static double returnMockTime() { |
45 s_timeElapsed += 1.0; | 93 s_timeElapsed += 1.0; |
46 return s_timeElapsed; | 94 return s_timeElapsed; |
47 } | 95 } |
48 | 96 |
49 std::unique_ptr<DummyPageHolder> m_dummyPageHolder; | 97 std::unique_ptr<DummyPageHolder> m_dummyPageHolder; |
| 98 RefPtr<scheduler::FakeWebTaskRunner> m_taskRunner; |
50 TimeFunction m_originalTimeFunction; | 99 TimeFunction m_originalTimeFunction; |
| 100 bool m_0QuietTimerRestarted; |
| 101 bool m_2QuietTimerRestarted; |
51 static double s_timeElapsed; | 102 static double s_timeElapsed; |
52 }; | 103 }; |
53 | 104 |
54 double FirstMeaningfulPaintDetectorTest::s_timeElapsed; | 105 double FirstMeaningfulPaintDetectorTest::s_timeElapsed; |
55 | 106 |
56 TEST_F(FirstMeaningfulPaintDetectorTest, NoFirstPaint) { | 107 TEST_F(FirstMeaningfulPaintDetectorTest, NoFirstPaint) { |
57 simulateLayoutAndPaint(1); | 108 simulateLayoutAndPaint(1); |
58 simulateNetworkStable(); | 109 simulateNetworkStable(); |
59 EXPECT_EQ(paintTiming().firstMeaningfulPaint(), 0.0); | 110 EXPECT_EQ(paintTiming().firstMeaningfulPaint(), 0.0); |
60 } | 111 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 TEST_F(FirstMeaningfulPaintDetectorTest, | 171 TEST_F(FirstMeaningfulPaintDetectorTest, |
121 FirstMeaningfulPaintShouldNotBeBeforeFirstContentfulPaint) { | 172 FirstMeaningfulPaintShouldNotBeBeforeFirstContentfulPaint) { |
122 paintTiming().markFirstPaint(); | 173 paintTiming().markFirstPaint(); |
123 simulateLayoutAndPaint(10); | 174 simulateLayoutAndPaint(10); |
124 paintTiming().markFirstContentfulPaint(); | 175 paintTiming().markFirstContentfulPaint(); |
125 simulateNetworkStable(); | 176 simulateNetworkStable(); |
126 EXPECT_GE(paintTiming().firstMeaningfulPaint(), | 177 EXPECT_GE(paintTiming().firstMeaningfulPaint(), |
127 paintTiming().firstContentfulPaint()); | 178 paintTiming().firstContentfulPaint()); |
128 } | 179 } |
129 | 180 |
| 181 TEST_F(FirstMeaningfulPaintDetectorTest, Network2QuietThen0Quiet) { |
| 182 paintTiming().markFirstContentfulPaint(); |
| 183 |
| 184 simulateLayoutAndPaint(1); |
| 185 double afterFirstPaint = monotonicallyIncreasingTime(); |
| 186 simulateNetwork2Quiet(); |
| 187 |
| 188 simulateLayoutAndPaint(10); |
| 189 simulateNetwork0Quiet(); |
| 190 |
| 191 // The first paint is FirstMeaningfulPaint. |
| 192 EXPECT_GT(paintTiming().firstMeaningfulPaint(), 0.0); |
| 193 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterFirstPaint); |
| 194 } |
| 195 |
| 196 TEST_F(FirstMeaningfulPaintDetectorTest, Network0QuietThen2Quiet) { |
| 197 paintTiming().markFirstContentfulPaint(); |
| 198 |
| 199 simulateLayoutAndPaint(1); |
| 200 double afterFirstPaint = monotonicallyIncreasingTime(); |
| 201 simulateNetwork0Quiet(); |
| 202 |
| 203 simulateLayoutAndPaint(10); |
| 204 double afterSecondPaint = monotonicallyIncreasingTime(); |
| 205 simulateNetwork2Quiet(); |
| 206 |
| 207 // The second paint is FirstMeaningfulPaint. |
| 208 EXPECT_GT(paintTiming().firstMeaningfulPaint(), afterFirstPaint); |
| 209 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterSecondPaint); |
| 210 } |
| 211 |
| 212 TEST_F(FirstMeaningfulPaintDetectorTest, NetworkQuietTimers) { |
| 213 setActiveConnections(3); |
| 214 EXPECT_FALSE(isNetwork0QuietTimerActive()); |
| 215 EXPECT_FALSE(isNetwork2QuietTimerActive()); |
| 216 |
| 217 setActiveConnections(2); |
| 218 EXPECT_FALSE(isNetwork0QuietTimerActive()); |
| 219 EXPECT_TRUE(isNetwork2QuietTimerActive()); |
| 220 |
| 221 setActiveConnections(1); |
| 222 EXPECT_FALSE(isNetwork0QuietTimerActive()); |
| 223 EXPECT_TRUE(isNetwork2QuietTimerActive()); |
| 224 EXPECT_FALSE(isNetwork2QuietTimerRestarted()); |
| 225 |
| 226 setActiveConnections(2); |
| 227 EXPECT_TRUE(isNetwork2QuietTimerRestarted()); |
| 228 |
| 229 setActiveConnections(0); |
| 230 EXPECT_TRUE(isNetwork0QuietTimerActive()); |
| 231 EXPECT_TRUE(isNetwork2QuietTimerActive()); |
| 232 EXPECT_FALSE(isNetwork2QuietTimerRestarted()); |
| 233 |
| 234 setActiveConnections(0); |
| 235 EXPECT_TRUE(isNetwork0QuietTimerActive()); |
| 236 EXPECT_TRUE(isNetwork0QuietTimerRestarted()); |
| 237 EXPECT_TRUE(isNetwork2QuietTimerActive()); |
| 238 EXPECT_FALSE(isNetwork2QuietTimerRestarted()); |
| 239 } |
| 240 |
130 } // namespace blink | 241 } // namespace blink |
OLD | NEW |