编写您的第一个客户端应用

简介

本文面向的是希望编写可与 PageSpeed Insights API 进行交互的应用的开发者。

PageSpeed Insights 是一款工具,可针对移动设备和桌面设备生成网页的实际性能报告,并提供关于如何改进相应网页的建议,以帮助开发者优化其网页。您可以使用 PageSpeed Insights API 以编程方式生成 PageSpeed 速度得分、优化得分和建议。

前期准备

获取 Google 账号

您需要拥有一个 Google 帐号,才能获取一个 API 密钥来让 Google 识别您的应用。(如下所示。)

熟悉 PageSpeed

如果您不熟悉 PageSpeed,请参阅 PageSpeed 网页性能最佳做法

了解如何让 Google 识别您的应用

您的应用每次向 PageSpeed Insights API 发送请求时,都需要识别自身的身份(通过在每个请求中添加 API 密钥)。

获取和使用 API 密钥

获取密钥

或者在“凭据”页面中创建一个 OAuth 客户端 ID。

在您获得 API 密钥后,您的应用便可在所有请求网址后附加查询参数 key=yourAPIKey

API 密钥可以安全地嵌入网址中,而无需进行任何编码。

PageSpeed Insights API 背景

PageSpeed Insights API 返回的结果包括以下类型的信息:

加载体验
“加载体验”部分包含总体速度类别(FAST、AVERAGE 或 SLOW)和类别分布。
此网页的速度统计信息
“网页统计信息”部分包含一些实用的统计结果,例如所需的往返次数和所用字节的总字节数。通过修改外观和功能,可以指示网页加载速度是否可能会变快。
优化得分
PageSpeed 优化得分 (0-100) 表示网页的优化程度。高分表示改进的空间很小,而低分表示改进的余地更大。
规则
PageSpeed 会使用规则分析网页。每条 PageSpeed 规则都基于网页性能的一般原则,例如资源缓存数据上传和下载大小以及客户端-服务器往返时间。PageSpeed 规则会生成规则结果和对规则的影响(如下所述)。
规则结果
规则结果是指由某条规则生成的建议,如果实施该建议,可加快相应网页的加载速度,并提高该网页的 PageSpeed 得分。例如,如果以未压缩的形式提供可压缩资源,PageSpeed 启用压缩规则会生成结果,建议开发者为该资源启用压缩。
规则影响
每条 PageSpeed 规则都会生成影响数(无界限浮点值),用于表示相对于其他规则,针对该规则实现规则结果建议的重要性或优先级。例如,如果启用压缩功能可节省 1MB 内存,而优化图片可节省 500kB 内存,那么启用压缩功能规则所造成的影响值将是“优化图片”规则的两倍。如果影响值为 0,则表示没有关于相应规则的改进建议。

调用 API

如需调用该 API,请调用 runPagespeed 方法,并在查询字符串中指定网址、API 密钥和其他参数。如需了解详情,请参阅 API 参考文档

API 调用示例

从命令行

您可以使用 curl 等程序从 Linux/UNIX 命令行调用 PageSpeed Insights API。

下例使用这种方法获取网址 https://developers.google.com/speed/pagespeed/insights/ 的移动 PageSpeed 结果。PageSpeed 得分、网页统计信息和 PageSpeed 格式的结果会以 JSON 数据格式返回。

设置了格式的结果以规则标识符(例如 AvoidBadRequestsMinifyJavaScript)为键,并且包含该规则的得分和影响,以及该规则生成的建议(实施这些建议可提高网页加载速度)。要详细了解 JSON 响应中的字段,请参阅 PageSpeed Insights API 参考文档。

请求

$ curl 'https://www.googleapis.com/pagespeedonline/v4/runPagespeed?url=https://developers.google.com/speed/pagespeed/insights/&strategy=mobile&key=yourAPIKey'

响应

{
 "captchaResult": "CAPTCHA_NOT_NEEDED",
 "kind": "pagespeedonline#result",
 "id": "https://developers.google.com/speed/pagespeed/insights/",
 "responseCode": 200,
 "title": "PageSpeed Insights",
 "ruleGroups": {
  "SPEED": {
   "score": 99
  }
 },
 "loadingExperience": {
  "id": "https://developers.google.com/speed/pagespeed/insights/",
  "metrics": {
   "FIRST_CONTENTFUL_PAINT_MS": {
    "median": 678,
    "distributions": [
     {
      "min": 0,
      "max": 1567,
      "proportion": 0.8726942914078067
     },
     {
      "min": 1567,
      "max": 2963,
      "proportion": 0.07357226585394444
     },
     {
      "min": 2963,
      "proportion": 0.053733442738248746
     }
    ],
    "category": "FAST"
   },
   "DOM_CONTENT_LOADED_EVENT_FIRED_MS": {
    "median": 559,
    "distributions": [
     {
      "min": 0,
      "max": 2120,
      "proportion": 0.9287991742172268
     },
     {
      "min": 2120,
      "max": 4226,
      "proportion": 0.035877050120426655
     },
     {
      "min": 4226,
      "proportion": 0.0353237756623466
     }
    ],
    "category": "FAST"
   }
  },
  "overall_category": "FAST",
  "initial_url": "https://developers.google.com/speed/pagespeed/insights/"
 },
 "pageStats": {
  "numberResources": 11,
  "numberHosts": 6,
  "totalRequestBytes": "1874",
  "numberStaticResources": 6,
  "htmlResponseBytes": "72494",
  "overTheWireResponseBytes": "324002",
  "cssResponseBytes": "8467",
  "imageResponseBytes": "5363",
  "javascriptResponseBytes": "841488",
  "otherResponseBytes": "14548",
  "numberJsResources": 4,
  "numberCssResources": 1,
  "numTotalRoundTrips": 13,
  "numRenderBlockingRoundTrips": 0
 },
 "formattedResults": {
  "locale": "en_US",
  "ruleResults": {
   "AvoidLandingPageRedirects": {
    "localizedRuleName": "Avoid landing page redirects",
    "ruleImpact": 0.0,
    "groups": [
     "SPEED"
    ],
    "summary": {
     "format": "Your page has no redirects. Learn more about {{BEGIN_LINK}}avoiding landing page redirects{{END_LINK}}.",
     "args": [
      {
       "type": "HYPERLINK",
       "key": "LINK",
       "value": "https://developers.google.com/speed/docs/insights/AvoidRedirects"
      }
     ]
    }
   },
   "EnableGzipCompression": {
    "localizedRuleName": "Enable compression",
    "ruleImpact": 0.0,
    "groups": [
     "SPEED"
    ],
    "summary": {
     "format": "You have compression enabled. Learn more about {{BEGIN_LINK}}enabling compression{{END_LINK}}.",
     "args": [
      {
       "type": "HYPERLINK",
       "key": "LINK",
       "value": "https://developers.google.com/speed/docs/insights/EnableCompression"
      }
     ]
    }
   },
   ...
   "PrioritizeVisibleContent": {
    "localizedRuleName": "Prioritize visible content",
    "ruleImpact": 0.0,
    "groups": [
     "SPEED"
    ],
    "summary": {
     "format": "You have the above-the-fold content properly prioritized. Learn more about {{BEGIN_LINK}}prioritizing visible content{{END_LINK}}.",
     "args": [
      {
       "type": "HYPERLINK",
       "key": "LINK",
       "value": "https://developers.google.com/speed/docs/insights/PrioritizeVisibleContent"
      }
     ]
    }
   }
  }
 },
 "version": {
  "major": 1,
  "minor": 15
 }
}

从 JavaScript

您可以通过浏览器中的 JavaScript 调用 PageSpeed Insights API,只需使用 callback 查询参数和回调函数即可生成 JSON-P 结果。这样,您就可以编写能够显示 PageSpeed 数据的丰富应用,而无需编写任何服务器端代码。

以下示例使用这种方法来显示网址 https://developers.google.com/speed/pagespeed/insights/ 中的 PageSpeed 结果和其他信息。该示例还使用 Google 图表工具来直观显示 PageSpeed Insights API 生成的信息。

首先,指定您的 Google API 密钥(详细了解 API 密钥):

<script>
// Specify your actual API key here:
var API_KEY = 'yourAPIKey';

// Specify the URL you want PageSpeed results for here:
var URL_TO_GET_RESULTS_FOR = 'https://developers.google.com/speed/pagespeed/insights/';
</script>

接下来,从 PageSpeed Insights API 获取 PageSpeed 结果:

<script>
var API_URL = 'https://www.googleapis.com/pagespeedonline/v4/runPagespeed?';
var CHART_API_URL = 'http://chart.apis.google.com/chart?';

// Object that will hold the callbacks that process results from the
// PageSpeed Insights API.
var callbacks = {}

// Invokes the PageSpeed Insights API. The response will contain
// JavaScript that invokes our callback with the PageSpeed results.
function runPagespeed() {
  var s = document.createElement('script');
  s.type = 'text/javascript';
  s.async = true;
  var query = [
    'url=' + URL_TO_GET_RESULTS_FOR,
    'callback=runPagespeedCallbacks',
    'key=' + API_KEY,
  ].join('&');
  s.src = API_URL + query;
  document.head.insertBefore(s, null);
}

// Our JSONP callback. Checks for errors, then invokes our callback handlers.
function runPagespeedCallbacks(result) {
  if (result.error) {
    var errors = result.error.errors;
    for (var i = 0, len = errors.length; i < len; ++i) {
      if (errors[i].reason == 'badRequest' && API_KEY == 'yourAPIKey') {
        alert('Please specify your Google API key in the API_KEY variable.');
      } else {
        // NOTE: your real production app should use a better
        // mechanism than alert() to communicate the error to the user.
        alert(errors[i].message);
      }
    }
    return;
  }

  // Dispatch to each function on the callbacks object.
  for (var fn in callbacks) {
    var f = callbacks[fn];
    if (typeof f == 'function') {
      callbacks[fn](result);
    }
  }
}

// Invoke the callback that fetches results. Async here so we're sure
// to discover any callbacks registered below, but this can be
// synchronous in your code.
setTimeout(runPagespeed, 0);
</script>

现在,利用上述代码从 PageSpeed Insights API 获取结果,我们可以使用以下示例,在用户的浏览器中显示感兴趣的信息。

示例 1:显示热门 PageSpeed 建议

该示例以无序列表的形式,针对所分析的网页显示了热门 PageSpeed 建议的名称。例如:

  • 使用浏览器缓存
  • 暂缓 JavaScript 解析
  • 缩减 HTML
  • 缩减 JavaScript

请注意:显示完整的 PageSpeed 结果所需的数据由 PageSpeed Insights API 提供,但为了简化示例,此处并未使用全部数据。

<script>
callbacks.displayTopPageSpeedSuggestions = function(result) {
  var results = [];
  var ruleResults = result.formattedResults.ruleResults;
  for (var i in ruleResults) {
    var ruleResult = ruleResults[i];
    // Don't display lower-impact suggestions.
    if (ruleResult.ruleImpact < 3.0) continue;
    results.push({name: ruleResult.localizedRuleName,
                  impact: ruleResult.ruleImpact});
  }
  results.sort(sortByImpact);
  var ul = document.createElement('ul');
  for (var i = 0, len = results.length; i < len; ++i) {
    var r = document.createElement('li');
    r.innerHTML = results[i].name;
    ul.insertBefore(r, null);
  }
  if (ul.hasChildNodes()) {
    document.body.insertBefore(ul, null);
  } else {
    var div = document.createElement('div');
    div.innerHTML = 'No high impact suggestions. Good job!';
    document.body.insertBefore(div, null);
  }
};

// Helper function that sorts results in order of impact.
function sortByImpact(a, b) { return b.impact - a.impact; }
</script>

示例 2:显示资源大小细分饼图

此示例展示的饼图显示了所分析网页的资源大小细分数据。例如:

<script>
var RESOURCE_TYPE_INFO = [
  {label: 'JavaScript', field: 'javascriptResponseBytes', color: 'e2192c'},
  {label: 'Images', field: 'imageResponseBytes', color: 'f3ed4a'},
  {label: 'CSS', field: 'cssResponseBytes', color: 'ff7008'},
  {label: 'HTML', field: 'htmlResponseBytes', color: '43c121'},
  {label: 'Flash', field: 'flashResponseBytes', color: 'f8ce44'},
  {label: 'Text', field: 'textResponseBytes', color: 'ad6bc5'},
  {label: 'Other', field: 'otherResponseBytes', color: '1051e8'},
];

callbacks.displayResourceSizeBreakdown = function(result) {
  var stats = result.pageStats;
  var labels = [];
  var data = [];
  var colors = [];
  var totalBytes = 0;
  var largestSingleCategory = 0;
  for (var i = 0, len = RESOURCE_TYPE_INFO.length; i < len; ++i) {
    var label = RESOURCE_TYPE_INFO[i].label;
    var field = RESOURCE_TYPE_INFO[i].field;
    var color = RESOURCE_TYPE_INFO[i].color;
    if (field in stats) {
      var val = Number(stats[field]);
      totalBytes += val;
      if (val > largestSingleCategory) largestSingleCategory = val;
      labels.push(label);
      data.push(val);
      colors.push(color);
    }
  }
  // Construct the query to send to the Google Chart Tools.
  var query = [
    'chs=300x140',
    'cht=p3',
    'chts=' + ['000000', 16].join(','),
    'chco=' + colors.join('|'),
    'chd=t:' + data.join(','),
    'chdl=' + labels.join('|'),
    'chdls=000000,14',
    'chp=1.6',
    'chds=0,' + largestSingleCategory,
  ].join('&');
  var i = document.createElement('img');
  i.src = 'http://chart.apis.google.com/chart?' + query;
  document.body.insertBefore(i, null);
};
</script>

演示视频

2011 年 Google I/O BootCamp 上的 PageSpeed Insights API 演示。