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

Unified Diff: extensions/renderer/script_injection.cc

Issue 2633253002: Split content script injections into multiple tasks (Closed)
Patch Set: rebase Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: extensions/renderer/script_injection.cc
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc
index 121def13fc31c357257b9ab2bbfe4261a805228d..b61fe9b888422173d027b7538e6a8645df96f877 100644
--- a/extensions/renderer/script_injection.cc
+++ b/extensions/renderer/script_injection.cc
@@ -15,6 +15,7 @@
#include "content/public/child/v8_value_converter.h"
#include "content/public/renderer/render_frame.h"
#include "extensions/common/extension_messages.h"
+#include "extensions/common/feature_switch.h"
#include "extensions/common/host_id.h"
#include "extensions/renderer/dom_activity_logger.h"
#include "extensions/renderer/extension_frame_helper.h"
@@ -77,6 +78,30 @@ int GetIsolatedWorldIdForInstance(const InjectionHost* injection_host,
return id;
}
+// This class manages its own lifetime.
+class TimedScriptInjectionCallback : public ScriptInjectionCallback {
+ public:
+ TimedScriptInjectionCallback(base::WeakPtr<ScriptInjection> injection)
+ : ScriptInjectionCallback(
+ base::Bind(&TimedScriptInjectionCallback::OnCompleted,
+ base::Unretained(this))),
+ injection_(injection) {}
+ ~TimedScriptInjectionCallback() override {}
+
+ void OnCompleted(const std::vector<v8::Local<v8::Value>>& result) {
+ if (injection_) {
+ base::TimeDelta elapsed = base::TimeTicks::Now() - start_time_;
+ injection_->OnJsInjectionCompleted(result, elapsed);
+ }
+ }
+
+ void willExecute() override { start_time_ = base::TimeTicks::Now(); }
+
+ private:
+ base::WeakPtr<ScriptInjection> injection_;
+ base::TimeTicks start_time_;
+};
+
} // namespace
// Watches for the deletion of a RenderFrame, after which is_valid will return
@@ -258,9 +283,7 @@ void ScriptInjection::InjectJs(std::set<std::string>* executing_scripts,
bool is_user_gesture = injector_->IsUserGesture();
std::unique_ptr<blink::WebScriptExecutionCallback> callback(
- new ScriptInjectionCallback(
- base::Bind(&ScriptInjection::OnJsInjectionCompleted,
- weak_ptr_factory_.GetWeakPtr())));
+ new TimedScriptInjectionCallback(weak_ptr_factory_.GetWeakPtr()));
base::ElapsedTimer exec_timer;
if (injection_host_->id().type() == HostID::EXTENSIONS && log_activity_)
@@ -273,11 +296,23 @@ void ScriptInjection::InjectJs(std::set<std::string>* executing_scripts,
is_user_gesture,
callback.release());
} else {
+ blink::WebLocalFrame::ScriptExecutionType option;
+ if (injector_->script_type() == UserScript::CONTENT_SCRIPT &&
+ FeatureSwitch::yield_between_content_script_runs()->IsEnabled()) {
+ switch (run_location_) {
+ case UserScript::DOCUMENT_END:
+ case UserScript::DOCUMENT_IDLE:
+ option = blink::WebLocalFrame::AsyncBlockingOnload;
+ break;
+ default:
+ option = blink::WebLocalFrame::Synchronous;
+ break;
+ }
+ } else {
+ option = blink::WebLocalFrame::Synchronous;
+ }
web_frame->requestExecuteScriptInIsolatedWorld(
- world_id,
- &sources.front(),
- sources.size(),
- is_user_gesture,
+ world_id, &sources.front(), sources.size(), is_user_gesture, option,
callback.release());
}
@@ -286,9 +321,13 @@ void ScriptInjection::InjectJs(std::set<std::string>* executing_scripts,
}
void ScriptInjection::OnJsInjectionCompleted(
- const std::vector<v8::Local<v8::Value>>& results) {
+ const std::vector<v8::Local<v8::Value>>& results,
+ base::TimeDelta elapsed) {
DCHECK(!did_inject_js_);
+ if (injection_host_->id().type() == HostID::EXTENSIONS)
+ UMA_HISTOGRAM_TIMES("Extensions.InjectedScriptExecutionTime", elapsed);
Devlin 2017/03/02 02:33:17 Did you forget to add this metric to histograms.xm
Kunihiko Sakamoto 2017/03/06 09:11:05 Oops, added.
+
bool expects_results = injector_->ExpectsResults();
if (expects_results) {
if (!results.empty() && !results[0].IsEmpty()) {
@@ -311,6 +350,7 @@ void ScriptInjection::OnJsInjectionCompleted(
// If |async_completion_callback_| is set, it means the script finished
// asynchronously, and we should run it.
if (!async_completion_callback_.is_null()) {
+ complete_ = true;
injector_->OnInjectionComplete(std::move(execution_result_), run_location_,
render_frame_);
// Warning: this object can be destroyed after this line!

Powered by Google App Engine
This is Rietveld 408576698