Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRX: persistent background page -> event page #1487

Merged
merged 4 commits into from
Jan 19, 2017
Merged

Conversation

ebidel
Copy link
Contributor

@ebidel ebidel commented Jan 18, 2017

R: all

I'm not sure why the crx uses a persistent background page, but it doesn't need it. They are generally discouraged in favor of on-demand event pages, which consume less memory in Chrome and are better for perf.

The changes here are mostly:

  • Moving to an event page. This requires using chrome.runtime.getBackgroundPage which is async. I've created a promise and wrapped code that needs the background page in it.
  • Moving code around (aka doing less work in DOMContentLoaded). We were defining a bunch of functions and delaying all work until DOMContentLoaded.

@brendankenny
Copy link
Member

I'm not sure why the crx uses a persistent background page

It might just be because of the generator we originally used to get an extension up and running.

How does this affect the extension debugging story?

@brendankenny
Copy link
Member

How does this affect the extension debugging story?

looks like the answer is that the extension is persisted while being debugged. Not sure if that's good or bad for accurately debugging :)

@ebidel
Copy link
Contributor Author

ebidel commented Jan 18, 2017

How does this affect the extension debugging story?

You mean dev'ing the extension? I only saw it go inactive a few times during testing but it fired right back up when I pressed the browser action button.

Apart from that, the background page should remain live as long as LH is doing its thing during a run.

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly looking good. Made some style suggestions on old variable names and completing the flattening of things out of DOMContentLoaded as long as you're in there.

Testing the extension everything appears to be working. The one difference I see is that when running lighthouse, clicking outside of the popup to close it, then reopening the popup it now does the very brief opacity transition to loading the status subpage every time, while before it appeared to be visible instantly. Fixable?


siteURL = new URL(tabs[0].url);

document.querySelector('header h2').textContent = siteURL.origin;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment here? or intermediate originEl (or whatever) variable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


siteURL = new URL(tabs[0].url);
siteNameEl.textContent = siteURL.origin;
const generateReportEl = document.getElementById('generate-report');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generateReportButton?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

* @param {!Object<boolean>} selectedAggregations
* @return {!DocumentFragment}
*/
function generateOptionsList(list, selectedAggregations) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this outside of the DOMContentLoaded block? It's already used asynchronously, so fine if it's asyc as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. but needed to add a background page param to make that work.

const checkedAggregations = Array.from(optionsEl.querySelectorAll(':checked'))
.map(input => input.value);
background.saveSelectedAggregations(checkedAggregations);
if (background.isRunning()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move all the rest of this to a named setup function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

function buildReportErrorLink(err) {
const reportErrorEl = document.createElement('a');
reportErrorEl.className = 'button button--report-error';
function startSpinner() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not just a spinner...showStatusSubpage/hideStatusSubpage?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

qsBody += '**Error Message**: ' + err.message + '\n';
qsBody += '**Stack Trace**:\n ```' + err.stack + '```';
function buildReportErrorLink(err) {
const MAX_ISSUE_ERROR_LENGTH = 60;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

top level const is normal for this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

const reportErrorEl = document.createElement('a');
reportErrorEl.className = 'button button--report-error';
function startSpinner() {
statusEl.classList.add(subpageVisibleClass);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe do document.querySelector('.status') rather than keeping global around?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@brendankenny
Copy link
Member

also @paulirish had a big refactor involving this file to make aggregation categories play well with devtools, so this will be fun to come home to :)

@ebidel
Copy link
Contributor Author

ebidel commented Jan 19, 2017

PTAL

});

return frag;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't use the first list argument in here.

I was thinking you could also just have it fetch the background itself (though it doesn't really matter), and since selectedAggregations is only used in here (not in the parent), you could even absorb that too:

/**
 * Generates a document fragment containing a list of checkboxes and labels
 * for the aggregation categories.
 * @return {!Promise<!DocumentFragment>}
 */
function generateOptionsList() {
  const frag = document.createDocumentFragment();

  return getBackgroundPage.then(background => {
    return background.loadSelectedAggregations().then(selectedAggregations => {
      const defaultAggregations = background.getDefaultAggregations();
      defaultAggregations.forEach(aggregation => {
        const isChecked = selectedAggregations[aggregation.name];
        frag.appendChild(createOptionItem(aggregation.name, isChecked));
      });
      return frag;
}

then below it would be
generateOptionsList().then(frag => optionsList.appendChild(frag));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(could still just pass in background, of course, since the caller already has a reference to it)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redid this function a bit.

@brendankenny
Copy link
Member

more important than bikeshedding that :) did you see my earlier comment:

The one difference I see is that when running lighthouse, clicking outside of the popup to close it, then reopening the popup it now does the very brief opacity transition to loading the status subpage every time, while before it appeared to be visible instantly. Fixable?

@ebidel
Copy link
Contributor Author

ebidel commented Jan 19, 2017

I decided to pas background and selectedAggregations references where they were needed. Felt more DRY and less wasteful then having extra promise ticks inside separate functions:

function initPage() {
...
    background.loadSelectedAggregations().then(selectedAggregations => {
      generateOptionsList(background, selectedAggregations);

      const generateReportButton = document.getElementById('generate-report');
      generateReportButton.addEventListener('click', () => {
        onGenerateReportButtonClick(background, selectedAggregations);
      });
    });
...
}

I think the changes also fix the visual jank you were seeing. Because the background page is async, it's a bit harder to control the transitions when the popup first starts and you're already running LH. I think we always had that jank, but it was unnoticeable until now.

@brendankenny
Copy link
Member

ah, good call with selectedAggregations. One weird thing is I'm really not sure why loadSelectedAggregations is in the background page. Seems like it should be in the popup since that's where it's generated and used. But that can wait for another day

@brendankenny
Copy link
Member

I think the changes also fix the visual jank you were seeing. Because the background page is async, it's a bit harder to control the transitions when the popup first starts and you're already running LH. I think we always had that jank, but it was unnoticeable until now.

Yeah, this traded it for a fade in at first launch, but it's pretty unnoticeable either way. I like this better, though others can argue :) I guess we could put the transition in a class we add after load, but I wonder if a flash of the wrong subpage is better than a fast fadeout of the wrong subpage.

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📆📄

@brendankenny brendankenny merged commit 6ad45ac into master Jan 19, 2017
@brendankenny brendankenny deleted the crxeventpage branch January 19, 2017 22:02
@paulirish
Copy link
Member

also @paulirish had a big refactor involving this file to make aggregation categories play well with devtools, so this will be fun to come home to :)

INDEED. 😁

but overall a worthwhile change, so it's all good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants