joelpurra / talkie

Text-to-speech browser extension button. Select text on any web page, and have the computer read it out loud for you by simply clicking the Talkie button.
https://joelpurra.com/projects/talkie/
GNU General Public License v3.0
70 stars 17 forks source link

Improve suspension resource usage #5

Closed joelpurra closed 7 years ago

joelpurra commented 7 years ago

Reported by @rob--w:

1) The suspension logic in background.js is unnecessary in Firefox because Firefox does not support event pages yet. I suggest to disable the SuspensionManager in Firefox.

2) In Chrome, your SuspensionManager will fail if the current tab cannot be scripted. This can happen on privileged URLs (chrome://, Chrome Web Store). I suggest to change the logic as follows:

  • Insert a frame in the background page with an onConnect listener. This listener does not have to do anything.
  • When the event page should stay alive, call browser.runtime.connect from your main background script.
  • The previous step will trigger browser.runtime.onConnect in all other extension contexts (not content scripts), including the frame from the first step. This means that there is now an active port between your main background script and the frame from the first step - this prevents the event page from suspending.
  • When the event page should be allowed to unload, call .disconnect() on the port (either the port returned by browser.runtime.connect(), or the port in the browser.runtime.onConnect event).

By following this suggestion, your add-on does not only become more reliable, but it will also consume less resources.

joelpurra commented 7 years ago
  1. I'd rather keep the logic for now, than monitor when Firefox enables background pages.
  2. Good idea. For now I merely accept that some pages are "special" and ignore errors. Will look at it.
joelpurra commented 7 years ago

Unless I've broken something else, I can't seem to get background-to-background iframe to prevent suspension. Will investigate more.

joelpurra commented 7 years ago

The v3.0.0 fix did not seem to work properly. For this reason it has not been published to the chrome web store nor firefox add-ons publicly. Reopening.

joelpurra commented 7 years ago

The problem seemed to be related to be (what I presume is) related to memory management/garbage collection, and keeping references to utterance objects. Basically logging, which has recently been reduced (see #7), prevented the speech synthesis from loosing weak references to individual utterances after the garbage collector killed the popup (which triggers speech when clicking the Talkie button) objects/memory.

This seems to be related to long-standing bugs in Chrome; see comments in code example (//IMPORTANT!! Do not remove: Logging the object out fixes some onend firing issues.). https://bugs.chromium.org/p/chromium/issues/detail?id=335907#c34

Either way, keeping attaching a reference to the current const utterance = new window.SpeechSynthesisUtterance(textPart); on the background's window object (despite it being created from there) seems to prevent problems after the popup (where the speech was triggered from) has been unloaded.