Commit 755b5c74 authored by David Black's avatar David Black Committed by Commit Bot

Reduce jank in card loading.

Previously, ManagedWebContents would inform callbacks that it was ready
for embedding after WebView creation. Now, we wait until after the
first load has stopped. This prevents embedding from happening until
all assets have been loaded.

Previously, large cards (e.g. "nearby restaurants") would occasionally
flicker as they were embedded before larger assets (e.g. map image)
were finished loading.

Bug: b:112498878
Change-Id: I0dce539800d5a18056e7d83a1078ccec70e7a25e
Reviewed-on: https://chromium-review.googlesource.com/1172067
Commit-Queue: David Black <dmblack@google.com>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582643}
parent 7237b367
...@@ -25,26 +25,29 @@ ...@@ -25,26 +25,29 @@
// ManagedWebContents ---------------------------------------------------------- // ManagedWebContents ----------------------------------------------------------
class ManagedWebContents : public content::WebContentsDelegate { class ManagedWebContents : public content::WebContentsDelegate,
public content::WebContentsObserver {
public: public:
ManagedWebContents( ManagedWebContents(
ash::mojom::ManagedWebContentsParamsPtr params, ash::mojom::ManagedWebContentsParamsPtr params,
ash::mojom::WebContentsManager::ManageWebContentsCallback callback) { ash::mojom::WebContentsManager::ManageWebContentsCallback callback)
: callback_(std::move(callback)) {
Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByAccountId( Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByAccountId(
params->account_id); params->account_id);
if (!profile) { if (!profile) {
LOG(WARNING) << "Unable to retrieve profile for account_id."; LOG(WARNING) << "Unable to retrieve profile for account_id.";
std::move(callback).Run(base::nullopt); std::move(callback_).Run(base::nullopt);
return; return;
} }
InitWebContents(profile, std::move(params)); InitWebContents(profile, std::move(params));
HandleWebContents(profile, std::move(callback)); HandleWebContents(profile);
} }
~ManagedWebContents() override { ~ManagedWebContents() override {
web_contents_->SetDelegate(nullptr); web_contents_->SetDelegate(nullptr);
Observe(nullptr);
// When WebContents are rendered in the same process as ash, we need to // When WebContents are rendered in the same process as ash, we need to
// release the associated view registered in the // release the associated view registered in the
...@@ -72,6 +75,14 @@ class ManagedWebContents : public content::WebContentsDelegate { ...@@ -72,6 +75,14 @@ class ManagedWebContents : public content::WebContentsDelegate {
return nullptr; return nullptr;
} }
// content::WebContentsObserver:
void DidStopLoading() override {
// After the first load has stopped, notify |callback_| that we're ready for
// embedding. We wait until load completion to reduce UI jank.
if (callback_)
std::move(callback_).Run(embed_token_);
}
private: private:
void InitWebContents(Profile* profile, void InitWebContents(Profile* profile,
ash::mojom::ManagedWebContentsParamsPtr params) { ash::mojom::ManagedWebContentsParamsPtr params) {
...@@ -93,6 +104,7 @@ class ManagedWebContents : public content::WebContentsDelegate { ...@@ -93,6 +104,7 @@ class ManagedWebContents : public content::WebContentsDelegate {
views::WebContentsSetBackgroundColor::CreateForWebContentsWithColor( views::WebContentsSetBackgroundColor::CreateForWebContentsWithColor(
web_contents_.get(), SK_ColorTRANSPARENT); web_contents_.get(), SK_ColorTRANSPARENT);
Observe(web_contents_.get());
web_contents_->SetDelegate(this); web_contents_->SetDelegate(this);
// Load the desired URL into the web contents. // Load the desired URL into the web contents.
...@@ -118,9 +130,7 @@ class ManagedWebContents : public content::WebContentsDelegate { ...@@ -118,9 +130,7 @@ class ManagedWebContents : public content::WebContentsDelegate {
max_size_dip); max_size_dip);
} }
void HandleWebContents( void HandleWebContents(Profile* profile) {
Profile* profile,
ash::mojom::WebContentsManager::ManageWebContentsCallback callback) {
// When rendering WebContents in the same process as ash, we register the // When rendering WebContents in the same process as ash, we register the
// associated view with the AnswerCardContentsRegistry's token-to-view map. // associated view with the AnswerCardContentsRegistry's token-to-view map.
// The token returned from the registry will uniquely identify the view. // The token returned from the registry will uniquely identify the view.
...@@ -132,14 +142,13 @@ class ManagedWebContents : public content::WebContentsDelegate { ...@@ -132,14 +142,13 @@ class ManagedWebContents : public content::WebContentsDelegate {
embed_token_ = app_list::AnswerCardContentsRegistry::Get()->Register( embed_token_ = app_list::AnswerCardContentsRegistry::Get()->Register(
web_view_.get()); web_view_.get());
std::move(callback).Run(embed_token_.value());
} else { } else {
// TODO(dmblack): Handle Mash case. https://crbug.com/854787. // TODO(dmblack): Handle Mash case. https://crbug.com/854787.
std::move(callback).Run(base::nullopt);
} }
} }
ash::mojom::WebContentsManager::ManageWebContentsCallback callback_;
std::unique_ptr<content::WebContents> web_contents_; std::unique_ptr<content::WebContents> web_contents_;
std::unique_ptr<views::WebView> web_view_; std::unique_ptr<views::WebView> web_view_;
base::Optional<base::UnguessableToken> embed_token_; base::Optional<base::UnguessableToken> embed_token_;
......
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