Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
/** @typedef {LH.Gatherer.Simulation.NodeTiming} NodeTiming */
const UIStrings = {
title: 'Header bidding is parallelized',
failureTitle: 'Parallelize bid requests',
description: 'Send header bidding requests simultaneously, rather than ' +
'serially, to retrieve bids more quickly. [Learn more](' +
'https://developers.google.com/publisher-ads-audits/reference/audits/serial-header-bidding' +
').',
columnBidder: 'Bidder',
columnUrl: 'URL',
columnStartTime: 'Start',
columnDuration: 'Duration',
};
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
// Min record duration (s) to be considered a bid.
const MIN_BID_DURATION = .05;
/**
* @typedef {Object} BidRequest
* @property {string | boolean} bidder
* @property {string} url
* @property {number} startTime
* @property {number} endTime
* @property {number} duration
*/
/**
* Table headings for audits details sections.
* @type {LH.Audit.Details.Table['headings']}
const ComputedAdRenderTime = require('../computed/ad-render-time');
const i18n = require('lighthouse/lighthouse-core/lib/i18n/i18n');
const {auditNotApplicable, runWarning} = require('../messages/common-strings');
const {Audit} = require('lighthouse');
const UIStrings = {
title: 'Latency of first ad render',
failureTitle: 'Reduce time to render first ad',
description: 'This metric measures the time for the first ad iframe to ' +
'render from page navigation. [Learn more](' +
'https://developers.google.com/publisher-ads-audits/reference/audits/first-ad-render' +
').',
displayValue: '{timeInMs, number, seconds} s',
};
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
/**
* Measures the first ad render time.
*/
class FirstAdRender extends Audit {
/**
* @return {LH.Audit.Meta}
* @override
*/
static get meta() {
// @ts-ignore
return {
id: 'first-ad-render',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
const i18n = require('lighthouse/lighthouse-core/lib/i18n/i18n');
const {auditNotApplicable, runWarning} = require('../messages/common-strings');
const {Audit} = require('lighthouse');
const UIStrings = {
title: 'Tag load time',
failureTitle: 'Reduce tag load time',
description: 'This metric measures the time for the ad tag\'s ' +
'implementation script (pubads_impl.js for GPT; adsbygoogle.js for ' +
'AdSense) to load after the page loads. [Learn more](' +
'https://developers.google.com/publisher-ads-audits/reference/audits/tag-load-time' +
').',
displayValue: '{timeInMs, number, seconds} s',
};
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
/**
* Audit to determine time for tag to load relative to page start.
*/
class TagLoadTime extends Audit {
/**
* @return {LH.Audit.Meta}
* @override
*/
static get meta() {
return {
id: 'tag-load-time',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
// @ts-ignore
const {auditNotApplicable} = require('../messages/common-strings');
const {Audit} = require('lighthouse');
const UIStrings = {
title: 'First bid request time',
failureTitle: 'Reduce time to send the first bid request',
description: 'This metric measures the elapsed time from the start of page ' +
'load until the first bid request is made. Delayed bid requests will ' +
'decrease impressions and viewability, and have a negative impact on ad ' +
'revenue. [Learn More](' +
'https://developers.google.com/publisher-ads-audits/reference/audits/bid-request-from-page-start' +
').',
displayValue: '{timeInMs, number, seconds} s',
};
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
/**
* Audit to determine time for first ad request relative to page start.
*/
class BidRequestFromPageStart extends Audit {
/**
* @return {LH.Audit.Meta}
* @override
*/
static get meta() {
return {
id: 'bid-request-from-page-start',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
// @ts-ignore
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
const i18n = require('lighthouse/lighthouse-core/lib/i18n/i18n');
const {group} = require('./messages/common-strings');
const PLUGIN_PATH = 'lighthouse-plugin-publisher-ads';
const UIStrings = {
categoryDescription: 'A Lighthouse plugin to improve ad speed and overall quality that is targeted at sites using GPT or AdSense tag. ' +
'[Learn more](https://developers.google.com/publisher-ads-audits/reference)',
};
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
/** @type {LH.Config.Plugin} */
module.exports = {
audits: [
{path: `${PLUGIN_PATH}/audits/ad-blocking-tasks`},
{path: `${PLUGIN_PATH}/audits/ad-render-blocking-resources`},
{path: `${PLUGIN_PATH}/audits/ad-request-critical-path`},
{path: `${PLUGIN_PATH}/audits/bid-request-from-page-start`},
{path: `${PLUGIN_PATH}/audits/ad-request-from-page-start`},
{path: `${PLUGIN_PATH}/audits/ad-top-of-viewport`},
{path: `${PLUGIN_PATH}/audits/ads-in-viewport`},
{path: `${PLUGIN_PATH}/audits/async-ad-tags`},
{path: `${PLUGIN_PATH}/audits/blocking-load-events`},
{path: `${PLUGIN_PATH}/audits/bottleneck-requests`},
{path: `${PLUGIN_PATH}/audits/duplicate-tags`},
{path: `${PLUGIN_PATH}/audits/first-ad-render`},
const {URL} = require('url');
const UIStrings = {
title: 'No duplicate tags found',
failureTitle: 'Load tags only once',
description: 'Loading a tag more than once in the same page is redundant ' +
'and adds overhead without benefit. [Learn more](' +
'https://developers.google.com/publisher-ads-audits/reference/audits/duplicate-tags' +
').',
failureDisplayValue: '{duplicateTags, plural, =1 {1 duplicate tag} other {# duplicate tags}}',
columnScript: 'Script',
columnNumReqs: 'Duplicate Requests',
columnFrameId: 'Frame ID',
};
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
const tags = [
'googletagservices.com/tag/js/gpt.js',
'securepubads.g.doubleclick.net/tag/js/gpt.js',
'pagead2.googlesyndication.com/pagead/js/adsbygoogle.js',
'pagead2.googlesyndication.com/pagead/js/show_ads.js',
];
/**
* Table headings for audits details sections.
* @type {LH.Audit.Details.Table['headings']}
*/
const HEADINGS = [
{key: 'script', itemType: 'url', text: str_(UIStrings.columnScript)},
{key: 'numReqs', itemType: 'text', text: str_(UIStrings.columnNumReqs)},
];
NOT_APPLICABLE__NO_VISIBLE_SLOTS: 'No visible slots',
NOT_APPLICABLE__NO_TAG: 'No tag requested',
NOT_APPLICABLE__NO_TAGS: 'No tags requested',
NOT_APPLICABLE__NO_TASKS: 'No tasks to compare',
NOT_APPLICABLE__NO_VALID_AD_WIDTHS: 'No requested ads contain ads of valid width',
ERRORS__AREA_LARGER_THAN_VIEWPORT: 'Calculated ad area is larger than viewport',
ERRORS__VIEWPORT_AREA_ZERO: 'Viewport area is zero',
WARNINGS__NO_ADS: 'No ads were requested when fetching this page.',
WARNINGS__NO_AD_RENDERED: 'No ads were rendered when rendering this page.',
WARNINGS__NO_TAG: 'The GPT tag was not requested.',
};
const i18n = require('lighthouse/lighthouse-core/lib/i18n/i18n');
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
/**
* Returns object for a notApplicable audit given a message string
* @param {string} message
* @return {Object}
*/
const notApplicableObj = (message) => ({
notApplicable: true,
score: 1,
displayValue: str_(message),
});
/**
* Returns notApplicable object for a given property.
* @return {Object}
*/
title: 'Ads not blocked by load events',
failureTitle: 'Avoid waiting on load events',
description: 'Waiting on load events increases ad latency. ' +
'To speed up ads, eliminate the following load event handlers. ' +
'[Learn More](' +
'https://developers.google.com/publisher-ads-audits/reference/audits/blocking-load-events' +
').',
displayValue: '{timeInMs, number, seconds} s blocked',
columnEvent: 'Event Name',
columnTime: 'Event Time',
columnScript: 'Script',
columnBlockedUrl: 'Blocked URL',
columnFunctionName: 'Function',
};
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
/**
* Table headings for audits details sections.
* @type {LH.Audit.Details.Table['headings']}
*/
const HEADINGS = [
{key: 'eventName', itemType: 'text', text: str_(UIStrings.columnEvent)},
{key: 'time', itemType: 'ms', text: str_(UIStrings.columnTime), granularity: 1},
{key: 'url', itemType: 'url', text: str_(UIStrings.columnScript)},
{key: 'functionName', itemType: 'text', text: str_(UIStrings.columnFunctionName)},
];
/** @typedef {import('../utils/graph').SimpleRequest} SimpleRequest */
/**
* @param {SimpleRequest} request
const UIStrings = {
title: 'Ad request waterfall',
failureTitle: 'Reduce critical path for ad loading',
description: 'Consider reducing the number of resources, loading multiple ' +
'resources simultaneously, or loading resources earlier to improve ad ' +
'speed. Requests that block ad loading can be found below. [Learn more](' +
'https://developers.google.com/publisher-ads-audits/reference/audits/ad-request-critical-path' +
').',
displayValue: '{serialResources, plural, =1 {1 serial resource} other {# serial resources}}',
columnUrl: 'Request',
columnType: 'Type',
columnStartTime: 'Start',
columnEndTime: 'End',
};
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
/**
* Table headings for audits details sections.
* @type {LH.Audit.Details.Table['headings']}
*/
const HEADINGS = [
{
key: 'url',
itemType: 'url',
text: str_(UIStrings.columnUrl),
},
{
key: 'type',
itemType: 'text',
text: str_(UIStrings.columnType),
},
const MINIMUM_LOAD_TIME_MS = 400;
const UIStrings = {
title: 'Ad scripts are loaded statically',
failureTitle: 'Load ad scripts statically',
description: 'Load the following scripts directly with ' +
'`