From 43a97878ce14b72f0981164f87f2e35e14151312 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:22:09 +0200 Subject: Adding upstream version 110.0.1. Signed-off-by: Daniel Baumann --- .../tabunloader/content/aboutUnloads.css | 25 ++++ .../tabunloader/content/aboutUnloads.html | 66 +++++++++++ .../components/tabunloader/content/aboutUnloads.js | 127 +++++++++++++++++++++ browser/components/tabunloader/docs/fullmode.png | Bin 0 -> 70005 bytes browser/components/tabunloader/docs/index.rst | 58 ++++++++++ browser/components/tabunloader/docs/lightmode.png | Bin 0 -> 52756 bytes browser/components/tabunloader/jar.mn | 8 ++ browser/components/tabunloader/moz.build | 12 ++ 8 files changed, 296 insertions(+) create mode 100644 browser/components/tabunloader/content/aboutUnloads.css create mode 100644 browser/components/tabunloader/content/aboutUnloads.html create mode 100644 browser/components/tabunloader/content/aboutUnloads.js create mode 100644 browser/components/tabunloader/docs/fullmode.png create mode 100644 browser/components/tabunloader/docs/index.rst create mode 100644 browser/components/tabunloader/docs/lightmode.png create mode 100644 browser/components/tabunloader/jar.mn create mode 100644 browser/components/tabunloader/moz.build (limited to 'browser/components/tabunloader') diff --git a/browser/components/tabunloader/content/aboutUnloads.css b/browser/components/tabunloader/content/aboutUnloads.css new file mode 100644 index 0000000000..150610a416 --- /dev/null +++ b/browser/components/tabunloader/content/aboutUnloads.css @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +body { + display: block; +} + +.control-panel { + float: inline-end; + margin: 10px 0; +} + +#button-unload { + float: inherit; + margin-inline-end: 0; +} + +.top-level-process { + font-weight: bold; +} + +.shared-process { + font-style: italic; +} diff --git a/browser/components/tabunloader/content/aboutUnloads.html b/browser/components/tabunloader/content/aboutUnloads.html new file mode 100644 index 0000000000..8d1e846b61 --- /dev/null +++ b/browser/components/tabunloader/content/aboutUnloads.html @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + +

+

+

+ + +

+
+
+ +
+ + + + + + + + + + +
+ + + + + + +
+ + + + diff --git a/browser/components/tabunloader/content/aboutUnloads.js b/browser/components/tabunloader/content/aboutUnloads.js new file mode 100644 index 0000000000..0bc330aaa0 --- /dev/null +++ b/browser/components/tabunloader/content/aboutUnloads.js @@ -0,0 +1,127 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +const { TabUnloader } = ChromeUtils.import( + "resource:///modules/TabUnloader.jsm" +); + +async function refreshData() { + const sortedTabs = await TabUnloader.getSortedTabs(null); + const tabTable = document.querySelector(".tab-table > tbody"); + const getHost = uri => { + try { + return uri?.host; + } catch (e) { + return uri?.spec; + } + }; + const updateTimestamp = () => { + document.l10n.setAttributes( + document.getElementById("label-last-updated"), + "about-unloads-last-updated", + { date: Date.now() } + ); + }; + + // Reset the table + // Don't delete the first row showing the "no unloadable tab" message + while (tabTable.rows.length > 1) { + tabTable.deleteRow(1); + } + if (!sortedTabs.length) { + document.getElementById("button-unload").disabled = true; + document.getElementById("no-unloadable-tab-message").hidden = false; + updateTimestamp(); + return; + } + document.getElementById( + "button-unload" + ).disabled = !TabUnloader.isDiscardable(sortedTabs[0]); + document.getElementById("no-unloadable-tab-message").hidden = true; + + const fragmentRows = new DocumentFragment(); + const templateRow = document.querySelector("template[name=tab-table-row]"); + + let ordinal = 0; + for (const tabInfo of sortedTabs) { + if (!("tab" in tabInfo)) { + continue; + } + + const fragment = templateRow.content.cloneNode(true); + const row = fragment.querySelector("tr"); + + row.children[0].textContent = TabUnloader.isDiscardable(tabInfo) + ? ++ordinal + : "-"; + row.children[1].textContent = getHost( + tabInfo.tab?.linkedBrowser?.currentURI + ); + if ("lastAccessed" in tabInfo.tab) { + document.l10n.setAttributes( + row.children[2], + "about-unloads-last-accessed", + { date: tabInfo.tab.lastAccessed } + ); + } + row.children[3].textContent = tabInfo.weight; + row.children[4].textContent = tabInfo.sortWeight; + if ("memory" in tabInfo) { + document.l10n.setAttributes( + row.children[5], + "about-unloads-memory-in-mb", + { mem: tabInfo.memory / 1024 / 1024 } + ); + } + + if (tabInfo.processes) { + for (const [pid, procEntry] of tabInfo.processes) { + if (pid < 0) { + // Tab is hosted by the main process + continue; + } + + const procLabel = document.createElement("span"); + const procInfo = procEntry.entryToProcessMap; + + if (procEntry.isTopLevel) { + procLabel.classList.add("top-level-process"); + } + if (procInfo.tabSet.size > 1) { + procLabel.classList.add("shared-process"); + } + procLabel.textContent = pid; + document.l10n.setAttributes( + procLabel, + "about-unloads-memory-in-mb-tooltip", + { mem: procInfo.memory / 1024 / 1024 } + ); + row.children[6].appendChild(procLabel); + row.children[6].appendChild(document.createTextNode(" ")); + } + } + + fragmentRows.appendChild(fragment); + } + + tabTable.appendChild(fragmentRows); + updateTimestamp(); +} + +async function onLoad() { + document + .getElementById("button-unload") + .addEventListener("click", async () => { + await TabUnloader.unloadLeastRecentlyUsedTab(null); + await refreshData(); + }); + await refreshData(); +} + +try { + document.addEventListener("DOMContentLoaded", onLoad, { once: true }); +} catch (ex) { + Cu.reportError(ex); +} diff --git a/browser/components/tabunloader/docs/fullmode.png b/browser/components/tabunloader/docs/fullmode.png new file mode 100644 index 0000000000..70d44ccd35 Binary files /dev/null and b/browser/components/tabunloader/docs/fullmode.png differ diff --git a/browser/components/tabunloader/docs/index.rst b/browser/components/tabunloader/docs/index.rst new file mode 100644 index 0000000000..534a10b4fd --- /dev/null +++ b/browser/components/tabunloader/docs/index.rst @@ -0,0 +1,58 @@ +Tab Unloading +============= + +Tab Unloading is a feature that automatically unloads tabs to prevent Firefox +from crashing due to insufficient memory when the system’s available memory is +low. + +The feature consists of two parts: memory pressure detector and tab unloader. +When the memory pressure detector detects a low memory situation, it triggers +the tab unloader that prioritizes tabs and chooses a tab to unload, or if there +are no unloadable tabs, triggers the internal memory-pressure warning allowing +the browser’s subsystems to reduce their memory use. + +There are two modes to prioritize tabs. + +Firefox basically unloads tabs in least-recently-used order, excluding +tabs playing media, using Picture-in-Picture, or using WebRTC. Pinned +tabs are deprioritized and are less likely to be unloaded. + +When there are more tabs opened, in most cases when there are more than +eleven tabs, Firefox does extra calculations identifying processes hosting +tabs and estimates memory usage of each tab, and then unloads tabs with +larger memory and more processes that will be terminated by tab unloading. + +You may disable the feature by setting the preference +``browser.tabs.unloadOnLowMemory`` to ``false``. + +about:unloads +------------- + +The about:unloads page shows how Firefox prioritizes tabs and which tab will +be unloaded when the tab unloader is triggered. You can trigger tab unloading +manually by clicking the **Unload** button in the page. + +The page contains a table where existing tabs are displayed in the same order +used by Firefox to choose the next tab to unload. When you click the button, +a tab shown in the first row, which has the lowest value in the **Priority**, +is unloaded. If the value of **Priority** is a hyphen (-), the corresponding +tab is not unloadable. + +In the first of the two modes mentioned above, Firefox calculates **Last Accessed** +and **Base Weight** for each tab and orders tabs by those values, not calculating +the other attributes such as **Secondary Weight** to save CPU power. Below is +an example of this case. + +.. image:: lightmode.png + +In the second mode, Firefox identifies processes hosting each tab and shows +their process IDs in the **Process IDs** column. Process IDs are displayed in +**bold** when they are hosting the tab’s top frame, and in *italic* when the +process is shared between different tabs. + +After identifying the processes of all tabs, Firefox estimates memory usage of +tabs and calculates the secondary weight for tabs that are not recently accessed. +For recently accessed tabs, Firefox does not calculate the **Secondary Weight** +and **Memory**, leaving those columns empty. + +.. image:: fullmode.png diff --git a/browser/components/tabunloader/docs/lightmode.png b/browser/components/tabunloader/docs/lightmode.png new file mode 100644 index 0000000000..8b6237f5f3 Binary files /dev/null and b/browser/components/tabunloader/docs/lightmode.png differ diff --git a/browser/components/tabunloader/jar.mn b/browser/components/tabunloader/jar.mn new file mode 100644 index 0000000000..f2b6effcd8 --- /dev/null +++ b/browser/components/tabunloader/jar.mn @@ -0,0 +1,8 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +browser.jar: + content/browser/tabunloader/aboutUnloads.css (content/aboutUnloads.css) + content/browser/tabunloader/aboutUnloads.html (content/aboutUnloads.html) + content/browser/tabunloader/aboutUnloads.js (content/aboutUnloads.js) diff --git a/browser/components/tabunloader/moz.build b/browser/components/tabunloader/moz.build new file mode 100644 index 0000000000..b4408d3f36 --- /dev/null +++ b/browser/components/tabunloader/moz.build @@ -0,0 +1,12 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +JAR_MANIFESTS += ["jar.mn"] + +with Files("**"): + BUG_COMPONENT = ("Firefox", "Tabbed Browser") + +SPHINX_TREES["/browser/tabunloader"] = "docs" -- cgit v1.2.3