Commit 49bed176 authored by crystallambert@chromium.org's avatar crystallambert@chromium.org Committed by Commit Bot

[Extension Doc]Performance Documentation

This article serves as a central location for best practices
to write a high performance extension.

Bug: none
Change-Id: Ie458a57b48dd0213e9effca9b69dd7a67910227e
Reviewed-on: https://chromium-review.googlesource.com/821690
Commit-Queue: Crystal Lambert <crystallambert@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551034}
parent 2f88261b
<h1>Reach Peak Performance</h1>
<p>
Extensions are an addition to the browser,
designed to provide supplementary and customized functionality.
An extension that slows down or impairs the browsing experience
is problematic to the user and counter to the Chrome extension objective.
In addition to general good coding habits,
developers should follow these practices
to ensure their extension is running at peak performance.
</p>
<h2 id="defer_everything">Defer Everything Possible</h2>
<p>
Refrain from loading resources until they are needed.
Include only what is needed to open an extension
in its startup function.
Do not load things during startup that are only needed if the user
clicks a button,
or features that work only when the user is logged in
before they have a chance to do so.
</p>
<h2 id="background_pages">Manage Important Events</h2>
<p>
An efficient <a href="/background_pages">background script</a>
contains registered events that are important to their extension.
They lie dormant until a listener is triggered,
act accordingly,
then return to a dormant state.
It is a drain on system resources to keep an unneeded script running.
</p>
<p>
Background scripts should be registered in the manifest
with their persistence set to false if possible.
</p>
<pre data-filename="manifest.json">
{
"name": "High Performance Extension",
"description" : "Sleepy Background Script",
"version": "1.0",
...
<b>"background": {</b>
<b>"scripts": ["background.js"],</b>
<b>"persistent": false</b>
<b>},</b>
...
}
</pre>
<p>
The only occasion to keep a background script persistently active
is if the extension uses
<a href="/webRequest"><code>chrome.webRequest</code> API</a>
to block or modify network requests.
The webRequest API is incompatible with non-persistent background pages.
</p>
<pre data-filename="manifest.json">
{
"name": "High Performance Extension",
"description" : "Persistent Background Script",
"version": "1.0",
...
"background": {
"scripts": ["background.js"],
<b>"persistent": true</b>
},
<b>"permissions": [</b>
<b>"webRequest",</b>
<b>"webRequestBlocking",</b>
<b>"https://&lt;distracting social media site&gt;.com/*"</b>
<b>]</b>,
...
}
</pre>
<pre data-filename="background.js">
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {redirectUrl: "https://developer.chrome.com/"};
},
{urls: ["https://social.media.distraction.com/*"]},
["blocking"]
);
</pre>
<h2 id="content_script">Contain Content Scripts</h2>
<p>
<a href="/content_scripts">Content scripts</a>
should work as the secret agents of an extension,
subtly reading from or modifying the webpage
while relying on the extension core to work heavier logic.
They should have clear targets to avoid invasive activity on irrelevant pages.
Ideally, content scripts should go unnoticed in the browsing experience
aside from purposeful behavior.
</p>
<h3 id="declare_targets">Declare Targets</h3>
<p>
An extension running content scripts in unnecessary locations
or at inappropriate times can cause the browser to slow down
and potentially create functionality errors.
Avoid this by providing <a href="/match_patterns">match patterns</a>
in the manifest and running the script at <code>document_idle</code>
instead of <code>document_start</code>.
</p>
<pre data-filename="manifest.json">
{
"name": "High Performance Extension",
"description" : "Superfly Superlight Content Scripts",
"version": "1.0",
...
<b>"content_scripts": [</b>
<b>{</b>
<b>"js": ["content_script.js"],</b>
<b>"matches": ["https://developer.chrome.com/*"],</b>
<b>"run_at": "document_idle"</b>
<b>}</b>
<b>]</b>
...
}
</pre>
<p>
If an extension will only need to access a webpage with the user's action,
have it <a href="/content_scripts#pi">injected programmatically</a>.
A programmatic injection will only run when a user invokes it.
</p>
<pre data-filename="background.js">
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript({
code: 'document.body.style.fontSize="100px"'
});
});
</pre>
<h3 id="no_content_scripts">Use Content Scripts Only When Required</h3>
<p>
Many extensions may not need a content script at all
to accomplish desired functionality.
Using the
<a href="/declarativeContent"><code>declarativeContent</code> API</a>
will set rules for the extension
to recognize when relevant conditions are met.
This is more efficient than a content script and uses less code!
</p>
<p>
If an extension needed to display a page action to the user
when they visited a site with an HTML5 <code>&lt;video&gt;</code> element,
it could specify a declarative rule.
</p>
<pre data-filename="background.js">
chrome.runtime.onInstalled.addListener(function() {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
chrome.declarativeContent.onPageChanged.addRules([
{
conditions: [
new chrome.declarativeContent.PageStateMatcher({
css: ["video"],
})
],
actions: [ new chrome.declarativeContent.ShowPageAction() ]
}
]);
});
});
</pre>
<h2 id="code">Evaluate Code Efficiency</h2>
<p>
The same general practices for website performance
can be applied to extensions such as
implement techniques of asynchronous programming
and keeping code minimal and compact.
</p>
<p>
Use tools, such as
<a href="https://developers.google.com/web/tools/lighthouse">
Lighthouse</a>,
to evaluate an extensions performance and target areas that could improve
on visual extension pages.
</p>
<img src="{{static}}/images/best_practices/lighthouse.gif"
height="400px"
alt="A gif of a lighthouse test on sample extension options">
......@@ -35,6 +35,10 @@
"title": "Design User Interface",
"href": "/extensions/user_interface"
},
{
"title": "Reach Peak Performance",
"href": "/extensions/performance"
},
{
"title": "Protect User Privacy",
"href": "/extensions/user_privacy"
......
{{+partials.standard_extensions_article article:articles.performance/}}
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