Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: third_party/WebKit/Source/core/frame/FrameSerializer.cpp

Issue 2364923004: Add UMA histograms to MHTML save operations. (Closed)
Patch Set: Address code review comments. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 #include "core/frame/LocalFrame.h" 52 #include "core/frame/LocalFrame.h"
53 #include "core/html/HTMLFrameElementBase.h" 53 #include "core/html/HTMLFrameElementBase.h"
54 #include "core/html/HTMLImageElement.h" 54 #include "core/html/HTMLImageElement.h"
55 #include "core/html/HTMLInputElement.h" 55 #include "core/html/HTMLInputElement.h"
56 #include "core/html/HTMLLinkElement.h" 56 #include "core/html/HTMLLinkElement.h"
57 #include "core/html/HTMLMetaElement.h" 57 #include "core/html/HTMLMetaElement.h"
58 #include "core/html/HTMLStyleElement.h" 58 #include "core/html/HTMLStyleElement.h"
59 #include "core/html/ImageDocument.h" 59 #include "core/html/ImageDocument.h"
60 #include "core/style/StyleFetchedImage.h" 60 #include "core/style/StyleFetchedImage.h"
61 #include "core/style/StyleImage.h" 61 #include "core/style/StyleImage.h"
62 #include "platform/Histogram.h"
62 #include "platform/SerializedResource.h" 63 #include "platform/SerializedResource.h"
63 #include "platform/TraceEvent.h" 64 #include "platform/TraceEvent.h"
64 #include "platform/graphics/Image.h" 65 #include "platform/graphics/Image.h"
65 #include "platform/heap/Handle.h" 66 #include "platform/heap/Handle.h"
66 #include "wtf/HashSet.h" 67 #include "wtf/HashSet.h"
67 #include "wtf/text/CString.h" 68 #include "wtf/text/CString.h"
68 #include "wtf/text/StringBuilder.h" 69 #include "wtf/text/StringBuilder.h"
69 #include "wtf/text/TextEncoding.h" 70 #include "wtf/text/TextEncoding.h"
70 #include "wtf/text/WTFString.h" 71 #include "wtf/text/WTFString.h"
71 72
73 namespace {
74
75 const int32_t secondsToMicroseconds = 1000 * 1000;
76 const int32_t maxSerializationTimeUmaMicroseconds = 10 * secondsToMicroseconds;
77
78 } // namespace
79
72 namespace blink { 80 namespace blink {
73 81
74 static bool shouldIgnoreElement(const Element& element) 82 static bool shouldIgnoreElement(const Element& element)
75 { 83 {
76 if (isHTMLScriptElement(element)) 84 if (isHTMLScriptElement(element))
77 return true; 85 return true;
78 if (isHTMLNoScriptElement(element)) 86 if (isHTMLNoScriptElement(element))
79 return true; 87 return true;
80 return isHTMLMetaElement(element) && toHTMLMetaElement(element).computeEncod ing().isValid(); 88 return isHTMLMetaElement(element) && toHTMLMetaElement(element).computeEncod ing().isValid();
81 } 89 }
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 // documents which leads to bugs like <https://crbug.com/251898>. Not being 244 // documents which leads to bugs like <https://crbug.com/251898>. Not being
237 // able to rewrite URLs inside CSS documents means that resources imported from 245 // able to rewrite URLs inside CSS documents means that resources imported from
238 // url(...) statements in CSS might not work when rewriting links for the 246 // url(...) statements in CSS might not work when rewriting links for the
239 // "Webpage, Complete" method of saving a page. It will take some work but it 247 // "Webpage, Complete" method of saving a page. It will take some work but it
240 // needs to be done if we want to continue to support non-MHTML saved pages. 248 // needs to be done if we want to continue to support non-MHTML saved pages.
241 249
242 FrameSerializer::FrameSerializer( 250 FrameSerializer::FrameSerializer(
243 Vector<SerializedResource>& resources, 251 Vector<SerializedResource>& resources,
244 Delegate& delegate) 252 Delegate& delegate)
245 : m_resources(&resources) 253 : m_resources(&resources)
254 , m_isSerializingCss(false)
246 , m_delegate(delegate) 255 , m_delegate(delegate)
247 { 256 {
248 } 257 }
249 258
250 void FrameSerializer::serializeFrame(const LocalFrame& frame) 259 void FrameSerializer::serializeFrame(const LocalFrame& frame)
251 { 260 {
252 TRACE_EVENT0("page-serialization", "FrameSerializer::serializeFrame"); 261 TRACE_EVENT0("page-serialization", "FrameSerializer::serializeFrame");
253 ASSERT(frame.document()); 262 ASSERT(frame.document());
254 Document& document = *frame.document(); 263 Document& document = *frame.document();
255 KURL url = document.url(); 264 KURL url = document.url();
256 265
257 // If frame is an image document, add the image and don't continue 266 // If frame is an image document, add the image and don't continue
258 if (document.isImageDocument()) { 267 if (document.isImageDocument()) {
259 ImageDocument& imageDocument = toImageDocument(document); 268 ImageDocument& imageDocument = toImageDocument(document);
260 addImageToResources(imageDocument.cachedImage(), url); 269 addImageToResources(imageDocument.cachedImage(), url);
261 return; 270 return;
262 } 271 }
263 272
264 TRACE_EVENT_BEGIN0("page-serialization", "FrameSerializer::serializeFrame HT ML");
265 HeapVector<Member<Node>> serializedNodes; 273 HeapVector<Member<Node>> serializedNodes;
266 SerializerMarkupAccumulator accumulator(m_delegate, document, serializedNode s); 274 {
267 String text = serializeNodes<EditingStrategy>(accumulator, document, Include Node); 275 TRACE_EVENT0("page-serialization", "FrameSerializer::serializeFrame HTML ");
276 SCOPED_BLINK_UMA_HISTOGRAM_TIMER("PageSerialization.SerializationTime.Ht ml");
277 SerializerMarkupAccumulator accumulator(m_delegate, document, serialized Nodes);
278 String text = serializeNodes<EditingStrategy>(accumulator, document, Inc ludeNode);
268 279
269 CString frameHTML = document.encoding().encode(text, WTF::EntitiesForUnencod ables); 280 CString frameHTML = document.encoding().encode(text, WTF::EntitiesForUne ncodables);
270 m_resources->append(SerializedResource(url, document.suggestedMIMEType(), Sh aredBuffer::create(frameHTML.data(), frameHTML.length()))); 281 m_resources->append(SerializedResource(url, document.suggestedMIMEType() , SharedBuffer::create(frameHTML.data(), frameHTML.length())));
271 TRACE_EVENT_END0("page-serialization", "FrameSerializer::serializeFrame HTML "); 282 }
272 283
273 for (Node* node: serializedNodes) { 284 for (Node* node: serializedNodes) {
274 ASSERT(node); 285 ASSERT(node);
275 if (!node->isElementNode()) 286 if (!node->isElementNode())
276 continue; 287 continue;
277 288
278 Element& element = toElement(*node); 289 Element& element = toElement(*node);
279 // We have to process in-line style as it might contain some resources ( typically background images). 290 // We have to process in-line style as it might contain some resources ( typically background images).
280 if (element.isStyledElement()) { 291 if (element.isStyledElement()) {
281 retrieveResourcesForProperties(element.inlineStyle(), document); 292 retrieveResourcesForProperties(element.inlineStyle(), document);
(...skipping 23 matching lines...) Expand all
305 if (CSSStyleSheet* sheet = styleElement.sheet()) 316 if (CSSStyleSheet* sheet = styleElement.sheet())
306 serializeCSSStyleSheet(*sheet, KURL()); 317 serializeCSSStyleSheet(*sheet, KURL());
307 } 318 }
308 } 319 }
309 } 320 }
310 321
311 void FrameSerializer::serializeCSSStyleSheet(CSSStyleSheet& styleSheet, const KU RL& url) 322 void FrameSerializer::serializeCSSStyleSheet(CSSStyleSheet& styleSheet, const KU RL& url)
312 { 323 {
313 TRACE_EVENT2("page-serialization", "FrameSerializer::serializeCSSStyleSheet" , 324 TRACE_EVENT2("page-serialization", "FrameSerializer::serializeCSSStyleSheet" ,
314 "type", "CSS", "url", url.elidedString().utf8().data()); 325 "type", "CSS", "url", url.elidedString().utf8().data());
326 // Only report UMA metric if this is not a reentrant CSS serialization call.
327 double cssStartTime = 0;
328 if (!m_isSerializingCss) {
329 m_isSerializingCss = true;
330 cssStartTime = monotonicallyIncreasingTime();
331 }
332
315 StringBuilder cssText; 333 StringBuilder cssText;
316 cssText.append("@charset \""); 334 cssText.append("@charset \"");
317 cssText.append(styleSheet.contents()->charset().lower()); 335 cssText.append(styleSheet.contents()->charset().lower());
318 cssText.append("\";\n\n"); 336 cssText.append("\";\n\n");
319 337
320 for (unsigned i = 0; i < styleSheet.length(); ++i) { 338 for (unsigned i = 0; i < styleSheet.length(); ++i) {
321 CSSRule* rule = styleSheet.item(i); 339 CSSRule* rule = styleSheet.item(i);
322 String itemText = rule->cssText(); 340 String itemText = rule->cssText();
323 if (!itemText.isEmpty()) { 341 if (!itemText.isEmpty()) {
324 cssText.append(itemText); 342 cssText.append(itemText);
325 if (i < styleSheet.length() - 1) 343 if (i < styleSheet.length() - 1)
326 cssText.append("\n\n"); 344 cssText.append("\n\n");
327 } 345 }
328 346
329 // Some rules have resources associated with them that we need to retrie ve. 347 // Some rules have resources associated with them that we need to retrie ve.
330 serializeCSSRule(rule); 348 serializeCSSRule(rule);
331 } 349 }
332 350
333 if (shouldAddURL(url)) { 351 if (shouldAddURL(url)) {
334 WTF::TextEncoding textEncoding(styleSheet.contents()->charset()); 352 WTF::TextEncoding textEncoding(styleSheet.contents()->charset());
335 ASSERT(textEncoding.isValid()); 353 ASSERT(textEncoding.isValid());
336 String textString = cssText.toString(); 354 String textString = cssText.toString();
337 CString text = textEncoding.encode(textString, WTF::CSSEncodedEntitiesFo rUnencodables); 355 CString text = textEncoding.encode(textString, WTF::CSSEncodedEntitiesFo rUnencodables);
338 m_resources->append(SerializedResource(url, String("text/css"), SharedBu ffer::create(text.data(), text.length()))); 356 m_resources->append(SerializedResource(url, String("text/css"), SharedBu ffer::create(text.data(), text.length())));
339 m_resourceURLs.add(url); 357 m_resourceURLs.add(url);
340 } 358 }
359
360 if (cssStartTime != 0) {
361 m_isSerializingCss = false;
362 DEFINE_STATIC_LOCAL(CustomCountHistogram, cssHistogram, ("PageSerializat ion.SerializationTime.CSSElement", 0, maxSerializationTimeUmaMicroseconds, 50));
363 cssHistogram.count(static_cast<int64_t>((monotonicallyIncreasingTime() - cssStartTime) * secondsToMicroseconds));
364 }
341 } 365 }
342 366
343 void FrameSerializer::serializeCSSRule(CSSRule* rule) 367 void FrameSerializer::serializeCSSRule(CSSRule* rule)
344 { 368 {
345 ASSERT(rule->parentStyleSheet()->ownerDocument()); 369 ASSERT(rule->parentStyleSheet()->ownerDocument());
346 Document& document = *rule->parentStyleSheet()->ownerDocument(); 370 Document& document = *rule->parentStyleSheet()->ownerDocument();
347 371
348 switch (rule->type()) { 372 switch (rule->type()) {
349 case CSSRule::kStyleRule: 373 case CSSRule::kStyleRule:
350 retrieveResourcesForProperties(&toCSSStyleRule(rule)->styleRule()->prope rties(), document); 374 retrieveResourcesForProperties(&toCSSStyleRule(rule)->styleRule()->prope rties(), document);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 m_resourceURLs.add(url); 431 m_resourceURLs.add(url);
408 } 432 }
409 433
410 void FrameSerializer::addImageToResources(ImageResource* image, const KURL& url) 434 void FrameSerializer::addImageToResources(ImageResource* image, const KURL& url)
411 { 435 {
412 if (!image || !image->hasImage() || image->errorOccurred() || !shouldAddURL( url)) 436 if (!image || !image->hasImage() || image->errorOccurred() || !shouldAddURL( url))
413 return; 437 return;
414 438
415 TRACE_EVENT2("page-serialization", "FrameSerializer::addImageToResources", 439 TRACE_EVENT2("page-serialization", "FrameSerializer::addImageToResources",
416 "type", "image", "url", url.elidedString().utf8().data()); 440 "type", "image", "url", url.elidedString().utf8().data());
441 double imageStartTime = monotonicallyIncreasingTime();
442
417 RefPtr<const SharedBuffer> data = image->getImage()->data(); 443 RefPtr<const SharedBuffer> data = image->getImage()->data();
418 addToResources(*image, data, url); 444 addToResources(*image, data, url);
445
446 // If we're already reporting time for CSS serialization don't report it for
447 // this image to avoid reporting the same time twice.
448 if (!m_isSerializingCss) {
449 DEFINE_STATIC_LOCAL(CustomCountHistogram, imageHistogram, ("PageSerializ ation.SerializationTime.ImageElement", 0, maxSerializationTimeUmaMicroseconds, 5 0));
450 imageHistogram.count(static_cast<int64_t>((monotonicallyIncreasingTime() - imageStartTime) * secondsToMicroseconds));
451 }
419 } 452 }
420 453
421 void FrameSerializer::addFontToResources(FontResource* font) 454 void FrameSerializer::addFontToResources(FontResource* font)
422 { 455 {
423 if (!font || !font->isLoaded() || !font->resourceBuffer() || !shouldAddURL(f ont->url())) 456 if (!font || !font->isLoaded() || !font->resourceBuffer() || !shouldAddURL(f ont->url()))
424 return; 457 return;
425 458
426 RefPtr<const SharedBuffer> data(font->resourceBuffer()); 459 RefPtr<const SharedBuffer> data(font->resourceBuffer());
427 460
428 addToResources(*font, data, font->url()); 461 addToResources(*font, data, font->url());
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 continue; 517 continue;
485 } 518 }
486 emitsMinus = ch == '-'; 519 emitsMinus = ch == '-';
487 builder.append(ch); 520 builder.append(ch);
488 } 521 }
489 CString escapedUrl = builder.toString().ascii(); 522 CString escapedUrl = builder.toString().ascii();
490 return String::format("saved from url=(%04d)%s", static_cast<int>(escapedUrl .length()), escapedUrl.data()); 523 return String::format("saved from url=(%04d)%s", static_cast<int>(escapedUrl .length()), escapedUrl.data());
491 } 524 }
492 525
493 } // namespace blink 526 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/frame/FrameSerializer.h ('k') | third_party/WebKit/Source/web/WebFrameSerializer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698