Moving sitespeed.io over to github pages #1240

Moving index page and about us page to github pages #1240

Adding remaining pages to documentation ported from 4.0 branch of the docs.sitespeed.io repo #1240

Missed a couple of images. #1240

More minor tweaks #1240

Hardcoded 404 image path relative to github root for now #1240

Converting 404 to markdown #1240

Fix first blog post #1240
This commit is contained in:
Jonathan Lee 2016-10-11 00:11:32 -04:00
parent b24a3da2c8
commit 4b54ff5a67
230 changed files with 6259 additions and 0 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ node_modules
.vscode
sitespeed-result
configs
docs/_site

View File

@ -0,0 +1,96 @@
---
layout: default
title: Browsers - Documentation - sitespeed.io
description: How to get browser timings using sitespeed.io for Firefox, Chrome, Safari and Internet Explorer.
keywords: browsers, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Browser timings for the sitespeed.io.
---
[Documentation 3.x](/documentation/) / Browsers
# Browsers
{:.no_toc}
* Lets place the TOC here
{:toc}
You can fetch timings and execute your own Javascript. The following browsers are supported:
Firefox, Chrome, Internet Explorer and Safari.
## Firefox
Firefox will work out of the box, as long as you have Firefox installed on your machine.
## Chrome
You need to install Chrome and the [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/) to be able to collect metrics from Chrome.
## Internet Explorer
Windows only. To get Internet Explorer to work, follow the [instructions](https://code.google.com/p/selenium/wiki/InternetExplorerDriver#Required_Configuration).
## Safari
You need Safari 8 to get timings from your browser (Mac only). To get it to work, you need to install the [SafariDriver extension - SafariDriver.safariextz](http://selenium-release.storage.googleapis.com/index.html?path=2.45/) in your browser. With the current version no HAR-file is created.
# Fetching timings
You can fetch timings ([Navigation Timing](http://www.w3.org/TR/navigation-timing/) and [User Timings](http://www.w3.org/TR/user-timing/)) using using the **-b** flag. We use [Browsertime](https://github.com/tobli/browsertime) to collect the data.
~~~ bash
$ sitespeed.io -u http://yoursite.com -b firefox
~~~
What we do is run a couple of [Javascripts](https://github.com/tobli/browsertime/tree/master/lib/scripts) that collects metrics from the browser. The browser stops collecting metrics when the *window.performance.timing.loadEventEnd* happens (but you can configure that yourself).
## Simulate the connection speed
You can throttle the connection when you are fetching metrics using the browser. Choose between:
* **mobile3g** - 1.6 Mbps/768 Kbps - 300 RTT
* **mobile3gfast** - 1.6 Mbps/768 Kbps - 150 RTT
* **cable** - 5 Mbps/1 Mbps - 28 RTT
* **native** - the current connection
And run it like this:
~~~ bash
$ sitespeed.io -u http://yoursite.com -b chrome --connection mobile3g
~~~
## Choose when to end your test
By default the browser will collect data until the *window.performance.timing.loadEventEnd* happens + aprox 2 seconds more. That is perfectly fine for most sites, but if you do ajax loading and you mark them with user timings, you probably want to include them in your test. Do that by changing the script that will end the test (*--waitScript*). When the scripts returns true the browser will close or if the timeout time (default 60 seconds) will be reached:
~~~ bash
sitespeed.io -u https://www.sitespeed.io -b chrome --waitScript 'return window.performance.timing.loadEventEnd>0'
~~~
## Custom metrics
You can collect your own metrics in the browser by supplying a directory with Javascript files. Each file need to return a metric/value and it will be picked up and returned in the JSON. If you return a number, statistics will automatically be generated for the value (like median/percentiles etc). Check out the [scripts](https://github.com/tobli/browsertime/tree/master/scripts) we use.
Say we have a folder called *scripts* and in there we have one file called *scripts.js* that checks how many javascript that is loaded. The script looks like this:
~~~
return document.getElementsByTagName("script").length;
~~~
Then to pick up the script, run like this:
~~~ bash
sitespeed.io -u https://www.sitespeed.io --customScripts scripts -b firefox
~~~
The basename of the file *script* will be used as the metric name. If the script return a number, the value will be sent to Graphite and will be summarized on the summary page. Other values will be shown on the specific result page.
# Collected timing metrics
All the metrics are collected using an empty cache.
* *backEndTime* - The time it takes for the network and the server to generate and start sending the HTML. Definition: responseStart - navigationStart
* *domContentLoadedTime* - The time the browser takes to parse the document and execute deferred and parser-inserted scripts including the network time from the users location to your server. Definition: domContentLoadedEventStart - navigationStart
* *domInteractiveTime* - The time the browser takes to parse the document, including the network time from the users location to your server. Definition: domInteractive - navigationStart
* *domainLookupTime* - The time it takes to do the DNS lookup. Definition: domainLookupEnd - domainLookupStart
* *frontEndTime* - The time it takes for the browser to parse and create the page. Definition: loadEventStart - responseEnd
* *pageDownloadTime* - How long time does it take to download the page (the HTML). Definition: responseEnd - responseStart
* *pageLoadTime* - The time it takes for page to load, from initiation of the page view (e.g., click on a page link) to load completion in the browser. Important: this is only relevant to some pages, depending on how you page is built. Definition: loadEventStart - navigationStart
* *redirectionTime* - Time spent on redirects. Definition: fetchStart - navigationStart
* *serverConnectionTime* - How long time it takes to connect to the server. Definition: connectEnd - connectStart
* *firstPaint* - This is when the first paint happens on the screen. If the browser support this metric, we use that. Else we use the time of the last non-async script or css from the head. You can easily verify if the first paint metrics is valid for you, by record a video using WebPageTest, and then check exactly when the first paint happens and compare that with the timing from the browser.
* [RUM-SpeedIndex](https://github.com/WPO-Foundation/RUM-SpeedIndex) - created by Pat Meenan
and calculate SpeedIndex measurements using Resource Timings. It iss not as perfect as Speed Index in WPT but a good start.

View File

@ -0,0 +1,372 @@
---
layout: default
title: Configuration - Documentation - sitespeed.io
description: How to configure sitespeed.io
keywords: configuration, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Configuration for the sitespeed.io.
---
[Documentation 3.x](/documentation/) / Configuration
# Configuration
{:.no_toc}
* Lets place the TOC here
{:toc}
# Configuration
Sitespeed.io is highly configurable, let's check it out!
## The options
You have the following options running sitespeed.io:
~~~help
Usage: node sitespeed.js [options]
Options:
-u <URL>, --url <URL> The start url that will be used when crawling.
-f <FILE>, --file <FILE> The path to a plain text file with one URL on each row. Each URL will be analyzed.
--sites <FILE> The path to a plain text file with one URL on each row. You can use the parameter multiple times to point out many files
-V, --version Display the sitespeed.io version.
--silent Only output info in the logs, not to the console.
-v, --verbose Enable verbose logging.
--noColor Don't use colors in console output. [false]
-d <INTEGER>, --deep <INTEGER> How deep to crawl. [1]
-c <KEYWORD>, --containInPath <KEYWORD> Only crawl URLs that contains this in the path.
-s <KEYWORD>, --skip <KEYWORD> Do not crawl pages that contains this in the path.
-t <NOOFTHREADS>, --threads <NOOFTHREADS> The number of threads/processes that will analyze pages. [5]
--name <NAME> Give your test a name, it will be added to all HTML pages.
--memory <INTEGER> How much memory the Java processed will have (in mb). [256]
-r <DIR>, --resultBaseDir <DIR> The result base directory, the base dir where the result ends up. [sitespeed-result]
--outputFolderName Default the folder name is a date of format yyyy-mm-dd-HH-MM-ss
--suppressDomainFolder Do not use the domain folder in the output directory
--userAgent <USER-AGENT> The full User Agent string, default is Chrome for MacOSX. [userAgent|ipad|iphone]. [Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36]
--viewPort <WidthxHeight> The view port, the page viewport size WidthxHeight like 400x300. [1280x800]
-y <FILE>, --yslow <FILE> The compiled YSlow file. Use this if you have your own rules.
--headless Choose which backend to use for headless [phantomjs|slimerjs] [phantomjs]
--ruleSet <RULE-SET> Which ruleset to use. [sitespeed.io-desktop]
--limitFile <PATH> The path to the limit configuration file.
--basicAuth <USERNAME:PASSWORD> Basic auth user & password.
-b <BROWSER>, --browser <BROWSER> Choose which browser to use to collect timing data. Use multiple browsers in a comma separated list (firefox|chrome|headless)
--connection Limit the speed by simulating connection types. Choose between mobile3g,mobile3gfast,cable,native [cable]
--waitScript Supply a javascript that decides when a browser run is finished. Use it to fetch timings happening after the loadEventEnd. [ if (window.performance && window.performance.timing){ return ((window.performance.timing.loadEventEnd > 0) && ((new Date).getTime() - window.performance.timing.loadEventEnd > 2000 ));} else { return true;}]
--customScripts The path to an extra script folder with scripts that will be executed in the browser. See https://www.sitespeed.io/documentation/browsers/#custom-metrics
--seleniumServer URL Configure the path to the Selenium server when fetching timings using browsers. If not configured the supplied NodeJS/Selenium version is used.
--btConfig <FILE> Additional BrowserTime JSON configuration as a file
--profile <desktop|mobile> Choose between testing for desktop or mobile. Testing for desktop will use desktop rules & user agents and vice verca. [desktop]
-n <NUMBEROFTIMES>, --no <NUMBEROFTIMES> The number of times you should test each URL when fetching timing metrics. Default is 3 times. [3]
--screenshot Take screenshots for each page (using the configured view port).
--junit Create JUnit output to the console.
--tap Create TAP output to the console.
--skipTest <ruleid1,ruleid2,...> A comma separated list of rules to skip when generating JUnit/TAP/budget output.
--testData Choose which data to send test when generating TAP/JUnit output or testing a budget. Default is all available [rules,page,timings,wpt,gpsi] [all]
--budget <FILE> A file containing the web perf budget rules. See https://www.sitespeed.io/documentation/performance-budget/
-m <NUMBEROFPAGES>, --maxPagesToTest <NUMBEROFPAGES> The max number of pages to test. Default is no limit.
--storeJson Store all collected data as JSON.
-p <PROXY>, --proxy <PROXY> http://proxy.soulgalore.com:80
--cdns <cdn1.com,cdn.cdn2.net> A comma separated list of additional CDNs.
--postTasksDir <DIR> The directory where you have your extra post tasks.
--boxes <box1,box2> The boxes showed on site summary page, see https://www.sitespeed.io/documentation/configuration/#configure-boxes-on-summary-page
-c <column1,column2>, --columns <column1,column2> The columns showed on detailed page summary table, see https://www.sitespeed.io/documentation/configuration/#configure-columns-on-pages-page
--configFile <PATH> The path to a sitespeed.io config.json file, if it exists all other input parameters will be overridden.
--aggregators <PATH> The path to a directory with extra aggregators.
--collectors <PATH> The path to a directory with extra collectors.
--graphiteHost <HOST> The Graphite host.
--graphitePort <INTEGER> The Graphite port. [2003]
--graphiteNamespace <NAMESPACE> The namespace of the data sent to Graphite. [sitespeed.io]
--graphiteData Choose which data to send to Graphite by a comma separated list. Default all data is sent. [summary,rules,pagemetrics,timings,requests,domains] [all]
--graphiteUseQueryParameters Choose if you want to use query paramaters from the URL in the Graphite keys or not
--graphiteUseNewDomainKeyStructure Use the updated domain section when sending data to Graphite "http.www.sitespeed.io" to "http.www_sitespeed_io" (issue #651)
--gpsiKey Your Google API Key, configure it to also fetch data from Google Page Speed Insights.
--noYslow Set to true to turn off collecting metrics using YSlow.
--html Create HTML reports. Default to true. Set no-html to disable HTML reports. [true]
--wptConfig <FILE> WebPageTest configuration, see https://github.com/marcelduran/webpagetest-api runTest method
--wptScript <FILE> WebPageTest scripting. Every occurance of \{\{\{URL\}\}\} will be replaced with the real URL.
--wptCustomMetrics <FILE> Fetch metrics from your page using Javascript
--wptHost <domain> The domain of your WebPageTest instance.
--wptKey <KEY> The API key if running on webpagetest on the public instances.
--requestHeaders <FILE>|<HEADER> Any request headers to use, a file or a header string with JSON form of {"name":"value","name2":"value"}. Not supported for WPT & GPSI.
--postURL <URL> The full URL where the result JSON will be sent by POST. Warning: Testing many pages can make the result JSON massive.
--phantomjsPath <PATH> The full path to the phantomjs binary, to override the supplied version
~~~
Yep, that was a lot, we know. Lets go into some standard use cases.
## The basics
If you installed with the global option (-g), run the command *sitespeed.io* else run the script *lib/sitespeed.js*. In the examples we will use the script but you know what to do if you have it installed.
You can analyze a site either by crawling or feed sitespeed.io with the URL:s you want to analyze.
### Analyze by crawling
The crawler needs a start URL (the parameter **u**, from where it will start the crawl). It will fetch all links within the same domain as the URL that you provide. You can then choose how deep you want to crawl with the **d** parameter. Zero will fetch only the
URL that you provide. One will fetch all links on that page and analyze these, two will go one level deeper and so on. If you want to analyze a site and the links with a depth of two, you do like this:
~~~ bash
$ sitespeed.io -u http://www.yoursite.com -d 2
~~~
Remember that you can start your crawl deep into your path structure like http://yoursite.com/my/path
{: .note .note-info}
### Analyze by URL:s
Instead of giving a start URL for the crawl, you can supply a plain text file with one URL on each row. Then each of these URL will be analyzed, no more or no less. A file like this will do:
~~~
http://www.yoursite.com/path/
http://www.yoursite.com/my/really/important/page/
http://www.yoursite.com/where/we/are/
~~~
Then you feed the file to the script:
~~~ bash
$ sitespeed.io -f myurls.txt
~~~
This is good for testing and keep tracks of your site in production and you have a LARGE site with many pages and a couple of them are more important than the rest.
{: .note .note-info}
### Analyze sites and benchmark
If you want to test and benchmark sites you can do like this:
~~~
http://www.yoursite.com/path/
http://www.mycompetition.com/
http://www.mycompetition2.com/
~~~
Then you feed the file to the script and each URL will be crawled. You can run the crawl the exact same way as usual, by feeding parameters.
~~~ bash
$ sitespeed.io --sites mysitesurls.txt
~~~
If you instead want to compare a couple specific URL:s between sites (pre defined URL:s instead of crawling), do like this: Create multiple plain text files with URL:s on each line:
Here's theguardian.txt:
~~~
http://www.theguardian.com/uk
http://www.theguardian.com/uk/sport
http://www.theguardian.com/uk/culture
~~~
And nytimes.txt:
~~~
http://www.nytimes.com/
http://www.nytimes.com/pages/sports/index.html
http://www.nytimes.com/pages/fashion/index.html
~~~
You can of course add how many URL:s and sites you want. Then you run the whole thing like this:
~~~ bash
$ sitespeed.io --sites theguardian.txt --sites nytimes.txt -d 0
~~~
Notice the -d 0 will tell sitespeed that we want to test the exact URL:s.
### Include/exclude URL:s when crawling
You want to make sure that parts of your site isn't included in your analyze, then you can add the parameter **s** and a keyword. Every URL with that keyword will not be included.
~~~ bash
$./bin/sitespeed.io -u http://yoursite.com -s /monkey/
~~~
You can also do it the other way around, with the **c** and a keyword. In this case, the analyze will only include URL:s with the keyword.
~~~ bash
$ ./bin/sitespeed.io -u http://yoursite.com -c /the/path/
~~~
### Screenshots
You can get screenshots of every page that you analyze. These will end up on a screenshot page where you can check them all. The screenshots will be taken for the chosen viewport.
~~~ bash
$ sitespeed.io -u http://yoursite.com --screenshot
~~~
### Shortcut: test as desktop or mobile
By default you test as desktop, if you turn on mobile by just setting the profile. If you do that, you will automatically test with
mobile rules, an IOS user agent, view port of 320x444 and on a throttled connection simulating a mobile 3g connection.
~~~ bash
$ sitespeed.io -u http://yoursite.com --profile desktop
~~~
~~~ bash
$ sitespeed.io -u http://yoursite.com --profile mobile
~~~
### Viewport/user agent and mobile
You can set the viewport & user agent, so that you can fake testing a site as a mobile device.
By default the viewport is 1280x800 with the following user agent for Chrome on MacOSX.
~~~ bash
$ sitespeed.io -u http://yoursite.com --viewPort 400x300 --userAgent "My SUPER BROWSER"
~~~
Mobile testing is always best on mobile devices. For tips on how to best do that, read Andy Davies [blog](http://andydavies.me/).
{: .note .note-warning}
### Limit pages to test
Sometimes you want to limit the amount to test (I do that when I compare sites). That will test maximum the amount of pages you supply.
~~~ bash
$ sitespeed.io -u http://yoursite.com -m 10
~~~
### Set a name of your test
You can give your test run a name that will be showed on all the pages
~~~ bash
$ sitespeed.io -u http://yoursite.com/ --name "Swedens top 100 sites"
~~~
### Collect timing metrics
Sitespeed.io collect timing metrics using the Navigation Timing API and the User Timing API. Today you can use Chrome, Firefox, PhantomJS 2.0 and SlimerJS. We also have exprimental support for Internet Explorer (ie) and Safari.
Add the parameter **b** followed by the browser name.
~~~ bash
$ sitespeed.io -u http://yoursite.com -b firefox
~~~
Each page is tested 3 times by default. You can change that with the **n** parameter. Test using Chrome and test each page 9 times, looks like this:
~~~ bash
$ sitespeed.io -u http://yoursite.com -b chrome -n 9
~~~
If you want to test in multiple browsers, you add them in a comma separated list
~~~ bash
$ sitespeed.io -u http://yoursite.com -b firefox,chrome -n 7
~~~
### Throttle the connection
You can throttle the connection when you are fetching metrics using the browser. Choose between:
* **mobile3g** - 1.6 Mbps/768 Kbps - 300 RTT
* **mobile3gfast** - 1.6 Mbps/768 Kbps - 150 RTT
* **cable** - 5 Mbps/1 Mbps - 28 RTT
* **native** - the current connection
And do like this:
~~~ bash
$ sitespeed.io -u http://yoursite.com -b chrome --connection mobile3g
~~~
## A little more nerdy
### Fetch data Google Page Speed Insights
To test each page using GPSI, you need to have a a Google API Key. You can get one [here](https://console.developers.google.com/project). Testing using GPSI will
include the GPSI score in the summary page and all individual data on the detailed page.
~~~ bash
$ sitespeed.io -u http://yoursite.com --gpsiKey MY_SECRET_KEY
~~~
### Fetch data from WebPageTest
Yep, it is true! You can drive WebPageTest from sitespeed.io. You need to either have your own private instance or an API key.
~~~ bash
$ sitespeed.io -u http://yoursite.com --wptHost www.webpagetest.org --wptKey MY_SECRET_API_KEY
~~~
In the background Marcel Durans WPT API is used, specific the [runTest](https://github.com/marcelduran/webpagetest-api#user-content-test-works-for-test-command-only) method.
You can pass all the parameters in the runTest through sitespeed.io by the **--wptConfig** parameter and supply a JSON file.
By default, the following values are passed to WPT:
~~~
pollResults: 10,
timeout: 600,
firstViewOnly: false,
runs: // the number of runs you configure by the n parameter
private: true,
aftRenderingTime: true,
location: 'Dulles:Chrome',
video: true
~~~
And if you configured basic auth, the login/password is also passed to WPT.
If you pass your own **--wptConfig**, a fields matching will override the default configuration.
### Send your data to Graphite
You can choose to send your data to Graphite, to keep track of your performance over time.
You configure four things: the host, port, the namespace and which data to send. Default value for the port is 2003, namespace (the start of the key) is sitespeed and send all collected data.
~~~ bash
$ sitespeed.io -u https://www.sitespeed.io --graphiteHost localhost
~~~
### Set request headers
The headers can be set if you collect rules and timings. It will not work for WPT and GPSI. Supply a JSON file like this:
~~~
{
"mysupercoolheader":"value",
"coolheader2":"value2"
}
~~~
And the run like this:
~~~ bash
$ sitespeed.io -u https://www.sitespeed.io --requestHeaders myheaders.txt
~~~
### Configure boxes on summary page
You can choose which boxes you want to show on the summary page by configure them by their name. You can choose to show to configure them exactly as you want. Then you need to pass every name to the script:
~~~ bash
$ sitespeed.io -u https://www.sitespeed.io --boxes thirdpartyversions,ycdn
~~~
Or if you want to add boxes to the already pre-configured ones, you can add a plus sign before the name(it is perfect
if you have your own User Timings that you want to show):
~~~ bash
$ sitespeed.io -u https://www.sitespeed.io -b chrome --boxes +logoTime,headerTime
~~~
These boxes will then end up in the end of the list.
### Configure columns on pages page
You can choose what kind of data you want to show in the column pages. The naming is far from perfect today or you could say it's broken, lets change that in coming major releases.
If you want to show data that are collected from YSlow, like number of javascripts, you do that like this:
~~~ bash
$ sitespeed.io -u https://www.sitespeed.io -c yslow.assets.js,yslow.assets.css,yslow.requests,yslow.pageWeight
~~~
If you want to fetch timings from your browser, they are following this pattern (headerTime is a User Timing):
~~~ bash
$ sitespeed.io -u https://www.sitespeed.io -c timings.serverResponseTime.median,timings.domContentLoadedTime.median,timings.headerTime.median -b chrome
~~~
If you want to show metric collected from WebPageTest they are published under the following structure: <i>wpt[location][browser][connectivity][view][timing]</i> and the metrics names are the exact same they have in the WebPageTest API (we collect 'SpeedIndex', 'firstPaint', 'render', 'TTFB', 'visualComplete', 'domContentLoadedEventEnd' and 'loadTime').
So if you want to display speed index for first and repeated view tested from Dulles using Chrome and Cable, you need to configure the columns like this:
~~~ bash
-c wpt.dulles.chrome.cable.firstView.SpeedIndex,wpt.dulles.chrome.cable.repeatView.SpeedIndex
~~~
If you have problem, [create an issue](https://github.com/sitespeedio/sitespeed.io/issues/new) and we will help you.

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,153 @@
---
layout: default
title: Continuous integration - Documentation - sitespeed.io
description: Use sitespeed.io in your Continuous Integration setup with Jenkins, Grunt or Team City.
keywords: Continuous Integration, jenkins, grunt, team city, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Use sitespeed.io in your Continuous Integration setup.
---
[Documentation 3.x](/documentation/) / Continous Intergration
# Continuous integration
{:.no_toc}
* Lets place the TOC here
{:toc}
Use sitespeed.io to keep track of what is happening with your site and make sure you know that you don't break the performance best practice rules **before** your changes are released.
Your build can also be broken if your page timings (choose whatever timing you need from the Navigation Timing API or your own custom timing) break your limits. And of course, if you use WebPageTest or Google Page Speed Insights, you can use the metrics from them to break your build.
Sitespeed.io outputs [JUnit XML](http://help.catchsoftware.com/display/ET/JUnit+Format) and [TAP](http://testanything.org/) that test your metrics against your configured limits.
## Generating JUnit XML or TAP
Sitespeed can output **junit.xml** that works perfect with your continuous integration tool. Jenkins, Bamboo and others support it out of the box.
~~~bash
$ sitespeed.io -u https://www.sitespeed.io --junit
~~~
Or if you rather prefer TAP:
~~~bash
$ sitespeed.io -u https://www.sitespeed.io --tap
~~~
## Configure when to break a test
By default these are the values that are tested:
~~~
{
"rules": {
"default": 90
},
"timings": {
"serverResponseTime": 300,
"domContentLoadedTime": 700,
"speedIndex": 1000
},
"wpt": {
"SpeedIndex": 1000
},
"gpsi": {
"score": 90
}
}
~~~
This means that all rules must be 90 or better,serverResponseTime 300 ms or better,
domContentLoadedTime to be faster than 700 ms. If you use WebPageTest, the speed index need to be under 1000. And finally, if you use Goggle Page Speed Insights, the score must be 90 or better.
You can configure to point out a JSON file containing all the values:
~~~bash
$ sitespeed.io -u https://www.sitespeed.io --tap --budget myBudget.json
~~~
## Skip rule tests
By default a all rules is tested against the default number you specify, meaning all rules needs to be 90 or better. Sometimes you have some rules you don't care about and can skip. You do that by feeding the rule names to the script. You find all the names [here](https://github.com/sitespeedio/yslow/blob/master/src/common/rulesets/ruleset_sitespeed.js).
~~~bash
$ sitespeed.io -u https://www.sitespeed.io --skipTest ycdn,textcontent --tap
~~~
## Jenkins
You have can use sitespeed.io in [Jenkins](http://jenkins-ci.org/") either by running as a CLI (*Execute shell*) or by using the [sitespeed.io plugin](https://github.com/sitespeedio/jenkins.sitespeed.io).
You want the browsers to run headless, use the [Xvfb plugin](https://wiki.jenkins-ci.org/display/JENKINS/Xvfb+Plugin) to make it happen!
### Running as CLI
* Choose **New Item** and create a new freestyle project.
* Choose **Add build step** in the Build part and **Execute shell** you will have a box where you add your sitespeed.io CLI magic. Remember that the Jenkins user needs to have NodeJS in the path. It can look like this (sending the data to a local Graphite instance):
~~~
sitespeed.io -u http://www.cybercom.com --graphiteHost localhost --graphiteNamespace cybercom-production -b chrome -n 11
~~~
* If you want to break your build, you can either generate JUnit XML and use the built in post task **Publish JUnit test result report**.
* In the execute shell form: *sitespeed.io -u http://stage.cybercom.com --resultBaseDir ${WORKSPACE}/${BUILD_NUMBER} --junit > junit.xml* And in the post task **Test report XMLs** add: *junit.xml*
* Using TAP, you need to install the [TAP plugin](https://wiki.jenkins-ci.org/display/JENKINS/TAP+Plugin).
* Run the execute shell like this *sitespeed.io -u http://stage.cybercom.com --resultBaseDir ${WORKSPACE}/${BUILD_NUMBER} --tap > sitespeed.tap*
* And choose the post task **Publish TAP Results** and in the Test Results box add: *sitespeed.tap*
### Jenkins plugin
The Jenkins plugin is not yet distributed within Jenkins, so you need to build and install it yourself. Follow [these](https://github.com/sitespeedio/jenkins.sitespeed.io#how-to-run-in-jenkins) instructions on how to do it. Remember that you need to have NodeJS in the path for the user running the plugin and make sure the user has the rights to execute the sitespeed.io executable.
The plugin focus on breaking your build if your budget doesnt't match the real world. You can choose to output the result as JUnit XML (the file is named **sitespeed.io-junit.xml**), TAP (**sitespeed.io-junit.tap**) or a budget file. If you run *budget* the script will return with a error return code, if your budget breaks. JUnit & TAP will always return ok, so then you need to setup the **Test report XMLs** or the **Publish TAP Results** task to break your build.
Add sitespeed.io in your build step:
![Add sitespeed.io as a build step](add-build-step-jenkins.png)
{: .img-thumbnail}
You can configure the plugin like this:
![Configure the plugin](jenkins-plugin-configuration.png)
{: .img-thumbnail}
And remember, if you output TAP, use the [TAP plugin](https://wiki.jenkins-ci.org/display/JENKINS/TAP+Plugin) or JUnit use the built in **Publish JUnit test result report**.
## TeamCity
Here's an example of setting up Team City running sitespeed.io on Windows, thanks [Gustav Tonér](https://github.com/gazab)!
### Running as CLI
* Choose **Create build configuration** or edit an existing build configuration.
* Choose **Add build step** under Build Configuration Settings \ Build Step and add a **Command Line** build step. Add your call to sitespeed.io in the **Custom script** box. Remember that the build agent user needs to have NodeJS in their path and have sitespeed.io installed already. The command line could look like this:
~~~
sitespeed.io.cmd -u https://www.sitespeed.io
~~~
**Screenshot of adding a build step in TeamCity**
![Adding a build step in TeamCity](teamcity-build-step.png)
{: .img-thumbnail}
### JUnit Reporting
* If you want to have sitespeed.io report back results to TeamCity so your build can break if tests fail you first need to edit your command line to make sitespeed.io generate a JUnit XML file like this:
~~~
sitespeed.io.cmd -u https://www.sitespeed.io --junit > sitespeedio_result.xml
~~~
* Then choose **Add build feature** under Build Configuration Settings \ Build Features and add **XML report processing** feature. Set **Report type** to **Ant JUnit** and specify the generated XML report filename in the **Monitoring rules** box.
* TeamCity should now run sitespeed.io and report back its results.
**Screenshot of adding JUnit reporting in TeamCity**
![Adding JUnit reporting in TeamCity](teamcity-build-feature.png)
{: .img-thumbnail}
## Travis integration
Coming soon!
## Grunt plugin
There's a Grunt plugin [grunt-sitespeedio](https://github.com/sitespeedio/grunt-sitespeedio) where you can do all the things you usually do with sitespeed.io. Use it create HTML-reports, send metrics to Graphite or test your performance budget.
## Gulp plugin
Checkout the [gulp-sitespeedio](https://www.npmjs.com/package/gulp-sitespeedio) plugin created by [Ankit Singhal](https://github.com/dreamzmaster).

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,199 @@
---
layout: default
title: Developers - Documentation - sitespeed.io
description: How to add your own post tasks, create rules and other cool stuff.
keywords: developers, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: How to add your own post tasks, create rules and other cool stuff.
---
[Documentation 3.x](/documentation/) / Developers
# Developers
{:.no_toc}
* Lets place the TOC here
{:toc}
You can fork the project at [GitHub](https://github.com/sitespeedio/sitespeed.io) and create your own version or contribute to the existing one. The master branch is the latest release and/or in production-ready state. Clone that and you know it will always work.
## The map
![The sitespeed.io universe](the-sitespeed.io-universe2.png)
{: .img-thumbnail}
## Add your own post tasks
When sitespeed.io collected all the metrics, you have the possibility to add your own post tasks, meaning writing your own NodeJS code to take all the metrics and do whatever you want with it (store it to a database etc).
You add your own post task (you can have multiple) in an directory and feed the directory name and path to sitespeed, like this:
~~~bash
$ sitespeed.io -u https://www.sitespeed.io --postTasksDir myPostTaskDir
~~~
In that directory, create a file and follow the following standard:
~~~javascript
exports.task = function(result, config, cb) {
console.log('yep this is my task running!')
cb();
};
~~~
The task will be called with the following:
* **result** - a JSON that contains all the metrics collected. Print it out to see exactly how it is constructed
* **config** - the sitespeed.io configuration object, contains info about the run and where to store the data
* **cb** - the callback to call when you are finished.
All post tasks runs in parallell.
## Create a new feature request
If you have ideas of how sitespeed.io can be improved or if you have any features that you think is missing, please add it to the [issue list](https://github.com/sitespeedio/sitespeed.io/issues?labels=&amp;milestone=&amp;page=1&amp;state=open").
## Add your own rules
Sitspeed uses [YSlow](http://yslow.org/) as the engine for creating and managing the rules that decides how good the web page is optimized for performance. [Stoyan Stefanov](https://twitter.com/stoyanstefanov) has written three good blog posts of how you develop and write rules for YSlow:
* [Getting started](http://www.phpied.com/yslow-development-getting-started/)
* [Setup](http://www.phpied.com/yslow-development-setup/)
* [Custom ruleset](http://www.phpied.com/yslow-development-custom-rulesets/)
To do it for sitespeed, this is what you need:
Clone the project
~~~
git clone git@github.com:sitespeedio/yslow.git
~~~
There are two files that you need to change, first the [rule file](https://github.com/sitespeedio/yslow/blob/master/src/common/rulesets/ruleset_sitespeed.js), where you add your own rule.
You need to do two changes: Add your rule *YSLOW.registerRule(...)* and register your rule to the ruleset *YSLOW.registerRuleset(...)*
In this example, I will add a rule called **cssprint** that will check for css files used only for printing the page:
~~~
YSLOW.registerRule({
id: 'cssprint',
name: 'Do not load print stylesheets, use @media type print instead',
info: 'Loading a specific stylesheet for printing slows down the page, ' +
'even though it is not used',
category: ['css'],
config: {points: 20},
url: 'http://sitespeed.io/rules/#cssprint',
lint: function (doc, cset, config) {
var i, media, score,url,
offenders = [],
hash = {},
comps = cset.getComponentsByType('css'),
links = doc.getElementsByTagName('link');
for (i = 0, len = links.length; i &lt; len; i += 1) {
if (links[i].media === 'print') {
url = links[i].href;
hash[url] = 1;
}
}
for (var i = 0; i &lt; comps.length; i++) {
if (hash[comps[i].url]) {
offenders.push(comps[i]);
}
}
score = 100 - offenders.length * parseInt(config.points, 20);
return {
score: score,
message: (offenders.length > 0) ? YSLOW.util.plural(
'There %are% %num% print css files included on the page, that should be @media query instead',
offenders.length
) : '',
components: offenders
};
}
});
~~~
When you have written your rule, register it to the ruleset and give it a proper weight (the lines with **cssprint** are the new ones, the rest exists already):
~~~
YSLOW.registerRuleset({
id: 'sitespeed.io-X.Y',
name: 'Sitespeed.io rules vX.Y',
rules: {
...
cssprint: {},
...
weights: {
...
cssprint: 3,
...
~~~
The next step is adding the documentation for the rule, you do that [here](https://github.com/soulgalore/yslow/blob/master/src/common/doc.js). You add one row where you put in the rule info:
~~~
YSLOW.doc.addRuleInfo('rulename','title','description')
~~~
For the **cssprint** rule, it looks like this:
~~~
YSLOW.doc.addRuleInfo('cssprint','Avoid loading specific css for print','Loading a specific stylesheet for print, can block rendering in your browser (depending on browser version) and will for almost all browsers, block the onload event to fire (even though the print stylesheet is not even used!).');
~~~
It is used when you run sitespeed to create the rule definition HTML file that is put into the results, so you always can backtrack which rules you use.
Create the new YSlow javascript file:
~~~
make phantomjs
~~~
Test that it works on one url (standing in root for YSlow):
~~~
phantomjs build/phantomjs/yslow.js d -r sitespeed.io-desktop -f xml http://yoururl.com
~~~
Move the newly created rulefile into a new directory:
~~~
cp build/phantomjs/yslow.js /tmp/myYslow.js
~~~
Run sitespeed in your folder:
~~~
sitespeed.io -u http://yoururl.com -y /tmp/myYslow.js
~~~
## Dependencies
Here are the dependencies for running sitespeed.io:
* *NodeJS* - You need to have NodeJS installed to be able to run sitespeed.io
* *Java 1.7* - You need to have Java 1.7 (or higher) installed because the Crawler and Selenium (who drives the browsers) uses Java.
## Component
The following components are used by sitespeed.io:
* [PhantomJS](http://phantomjs.org/) by Ariya Hidayat.
* [Handlebars](http://handlebarsjs.com/).
* [FastStats](https://github.com/bluesmoon/node-faststats) to do statistical analysis of numeric datasets by Philip Tellis.
* [gpagespeed](https://www.npmjs.org/package/gpagespeed) - nalyze your web page by using Google Page Speed Insights by Geir Gåsodden.
* [YSlow](http://yslow.org) - Sitespeed.io uses the rule engine YSlow, because it is great! YSlow was originally developed by Yahoo and now maintained by **Marcel Duran**, a rule engine & browser plugin created to test your web page against best practices rules.
* [Bootstrap](http://getbootstrap.com/) is a front end framework to create nice looking HTML, all the front end of the result pages produced by sitespeed are built with Bootstrap.
* [Java crawler](https://github.com/soulgalore/crawler) that output all links within a domain to a file, it can follow a specific path or make sure urls containing X not will be fetched.
* [Stupid Table Plugin](https://github.com/joequery/Stupid-Table-Plugin) by Joseph McCullough is a really small table column sorter.
* [BrowserTime](https://github.com/tobli/browsertime) collects browser timings using the Navigation Timing API.
* [WebPageTest API wrapper](https://www.npmjs.org/package/webpagetest) for NodeJS by Marcel Duran to fetch metrics from WebPageTest
* [BrowserMobProxy](https://github.com/lightbody/browsermob-proxy) to collect HAR data.
## Report a bug
If you find a bug, please first make sure you run the [latest version](https://www.npmjs.com/package/sitespeed.io) of sitespeed.io. Then go through the current known [bug list](https://github.com/sitespeedio/sitespeed.io/issues?labels=bug&amp;state=open). If it doesn't exist there, please add it!

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

72
docs/3.x/docker/index.md Normal file
View File

@ -0,0 +1,72 @@
---
layout: default
title: Docker - Documentation - sitespeed.io
description: Use Docker to run sitespeed.io.
keywords: docker, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Use Docker to run sitespeed.io.
---
[Documentation 3.x](/documentation/) / Docker
# Docker
{:.no_toc}
* Lets place the TOC here
{:toc}
## Containers
We have a couple of Docker containers you can use to run sitespeed.io. We have separated them to try to keep the size as small as possible.
* [The base box](https://hub.docker.com/r/sitespeedio/sitespeed.io-standalone/) - only including sitespeed.io. You can use this if you only want to check web performance best practice rules. And soon when PhantomJS 2 is released for Linux you will be able to fetch timing using Phantom.
* [Firefox & Xvfb](https://hub.docker.com/r/sitespeedio/sitespeed.io-firefox/) - makes it possible to fetch timings using Firefox. This it the smallest container using a real browser.
* [Chrome & Xvfb](https://hub.docker.com/r/sitespeedio/sitespeed.io-chrome/) - if you prefer Chrome this is the container to use.
* [Chrome, Firefox & Xvfb](https://hub.docker.com/r/sitespeedio/sitespeed.io/) - here you get all the things you need, the box gets quite large precisely over 1 gb.
## Running in Docker
The simplest way to run is like this fetching the box with Chrome and Firefox:
~~~ bash
sudo docker run --privileged --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io sitespeed.io -u https://www.sitespeed.io -b chrome
~~~
If you want to feed sitespeed with a list of URL:s in a file (here named *myurls.txt*), add the file to your current directory and do like this:
~~~ bash
sudo docker run --privileged --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io sitespeed.io -f myurls.txt -b chrome --seleniumServer http://127.0.0.1:4444/wd/hub
~~~
In the real world you should always specify the exact version (tag) of the Docker container to make sure you use the same version all the time (else you will download the latest tag, meaning you can have old and new versions running on the server and you don't know it). Specify the tag after the container name(X.Y.Z) in this example. The tag/version number will be the same number as the sitespeed.io release:
~~~ bash
sudo docker run --privileged --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:X.Y.Z sitespeed.io -u https://www.sitespeed.io -b chrome
~~~
## Setup the volume
If you want to feed sitespeed.io with a file with URL:s or if you want the HTML result, you should setup a volume. Sitespeed.io will do all the work inside the container in a directory located */sitespeed.io*. To setup your current working directory add the *-v "$(pwd)":/sitespeed.io* to your parameter list. Using "$(pwd)" will default to the root user directory. In order to specify the location, simply define an absolute path: *-v /Users/user/path:/sitespeed.io*
Note: running on Mac OS X and Windows Docker only has rights to write data in your */Users* or *C:\Users* directory. Read more [here](https://docs.docker.com/userguide/dockervolumes/#mount-a-host-directory-as-a-data-volume).
{: .note .note-warning}
## Update version (download newer sitespeed.io version)
Updating to a newer version is easy, change X.Y.Z to the version you want to use:
~~~ bash
docker pull sitespeedio/sitespeed.io:X.Y.Z
~~~
Or alternatively pull the latest version:
~~~ bash
docker pull sitespeedio/sitespeed.io
~~~
And then change your start script (or where you start your container) to use the new version number.
If you don't use version number (you should!) then just pull the container and you will run the latest version.

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

42
docs/3.x/gpsi/index.md Normal file
View File

@ -0,0 +1,42 @@
---
layout: default
title: Run Google Page Speed Insights - Documentation - sitespeed.io
description: Fetch Google Page Speed Insights metrics and include them in your sitespeed.io report.
keywords: gpsi, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Fetch Google Page Speed Insights metrics and include them in your sitespeed.io report.
---
[Documentation 3.x](/documentation/) / GPSI
# Google Page Speed Insights
{:.no_toc}
* Lets place the TOC here
{:toc}
Google Page Speed Insights (GPSI) is Google:s rule/best practices rules to build a web site that are as fast as possible. Follow the rules and your site will be fast.
Sitespeed.io integrates GPSI so you can fetch how good your site is doing. Two things: Your site needs to reachable from the internet (and no basic authentication) and you need to supply your own [Google key](https://console.developers.google.com/project).
Run it like this:
~~~bash
$ sitespeed.io -u http://yoursite.com --gpsiKey MY_SECRET_KEY
~~~
Sitespeed.io will collect all available data from GPSI. On the summary page, the GPSI score will be shown. We also collect number of requests. You can check the implementation [here](https://github.com/sitespeedio/sitespeed.io/tree/master/lib/aggregators/gpsi) and add an issue if you want us to collect more data:
![Google Page Speed Summary](gpsi-summary.png)
{: .img-thumbnail}
On the pages summary, you will also automatically the GPSI score:
![Google Page Speed Pages](gpsi-pages.png)
{: .img-thumbnail}
And on the detailed summary page, we show all the data that are provided by GPSI, it looks like this:
![Google Page Speed details](gpsi-detailed-page-info.png)
{: .img-thumbnail}

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

72
docs/3.x/graphs/index.md Normal file
View File

@ -0,0 +1,72 @@
---
layout: default
title: Graphs - Documentation - sitespeed.io
description: Create graphs for your web performance metrics using Graphite and Grafana.
keywords: graphs, graphite, grafana, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Create graphs for your web performance metrics using Graphite and Grafana.
---
[Documentation 3.x](/documentation/) / Graphs
# Graphs
{:.no_toc}
* Lets place the TOC here
{:toc}
The easiest way to graph your data (and keep track how you are doing over time), is sending the data to [Graphite](http://graphite.wikidot.com/). And then use a tool to create the graphs. I like [Grafana](http://grafana.org/) because it is super simple and look nice. Here's how you do it:
* Install Graphite - if you are on Mac OS X and want to test it out, use a Vagrant setup.
* Install Grafana - either by Vagrant or just download and install InfluxDb & ElasticSearch
* Send the data from sitespeed.io to Graphite
* Create the graphs in Grafana. We will soonish add a video of how to do it.
Here are a couple of examples of what ut can look like. Here we test one site, something like this:
~~~bash
sitespeed.io -u http://www.cybercom.com --graphiteHost localhost -m 5 --graphiteNamespace cybercom -b chrome -n 11
~~~
And setup the following graphs:
![sitespeed.io page metrics sent to Graphite](grafana-page-metrics.png)
{: .img-thumbnail}
![sitespeed.io timing metrics sent to Graphite](grafana-timing-metrics.png)
{: .img-thumbnail}
![sitespeed.io page metrics sent to Graphite](grafana-page-metrics.png)
{: .img-thumbnail}
In this example, we compare four Swedish newspapers, running it like this
~~~bash
$ sitespeed.io --sites /Users/peter/swedish.txt --graphiteHost localhost --graphiteNamespace newspapers -b chrome -n 7
~~~
and the result:
![sitespeed.io comparing multiple sites](grafana-swedish-newspapers.png)
{: .img-thumbnail}
And the last example, we fetch data from WebPageTest and create the following:
![sitespeed.io running WebPageTest and graphing the data](grafana-wpt-dark.png)
{: .img-thumbnail}
~~~bash
$ sitespeed.io -u http://www.cybercom.com --wptHost www.webpagetest.org --wptKey MY_SECRET_API_KEY --graphiteHost localhost --graphiteNamespace wpt
~~~
If you send all the metrics and don't need the other output (HTML/JSON, it can be quite extensive if you run it often), put all the output in **/tmp** with the **r** switch like this **-r /tmp**.
{: .note .note-info}
Doesn't all values reach Graphite (are you missing values), then you should check your **carbon.conf** file.
The configuration **MAX_CREATES_PER_MINUTE** needs to be set to high (we have seen that 50 is too low). To make sure it works, set it like this:
~~~
MAX_CREATES_PER_MINUTE = inf
~~~
{: .note .note-warning}

View File

@ -0,0 +1,51 @@
---
layout: default
title: Headless - Documentation - sitespeed.io
description: Collect browser timings headless using sitespeed.io.
keywords: headless, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Collect browser timings headless using sitespeed.io.
---
[Documentation 3.x](/documentation/) / Headless
# Headless
{:.no_toc}
* Lets place the TOC here
{:toc}
## Headless using Xvfb
If you run on Linux and want to emulate a screen (a.k.a running a browser without a screen), you need to do this before running:
* Install [Xvfb](http://www.x.org/releases/current/doc/man/man1/Xvfb.1.xhtml).
* Setup a start script, checkout how we do it in our [Docker container](https://github.com/sitespeedio/sitespeed.io-docker/blob/master/all/scripts/start.sh).
## PhantomsJS 2
[PhantomJS](http://phantomjs.org/) is used by default when validating the web performance best practice rules. Soon (!) we will upgrade to the (almost) released 2.0 version. If you want to try out the 2.0 and use it when you run sitespeed.io, do like this:
* Follow [these](https://github.com/ariya/phantomjs/wiki/PhantomJS-2) instructions to build PhantomJS 2 or [download](https://bitbucket.org/ariya/phantomjs/downloads) the compiled versions.
* Run sitespeed.io and configure it to use your own version of PhantomJS
~~~bash
sitespeed.io -u https://www.sitespeed.io --phantomjsPath /the/path/to/your/bin
~~~
* If you also want to collect timings using PhantomJS, run it like this:
~~~bash
sitespeed.io -u https://www.sitespeed.io --phantomjsPath /the/path/to/your/bin -b headless
~~~
We have tested PhantomJS 2 on Mac OS X and it works really good when testing the site against the best practice rules. However, it seems to be a couple of timings that don't work as expected. If you have time to test and find things that don't work, please let us know and we will update the docs. We aim to give this more love when the stable 2.0 is released.
{: .note .note-warning}
## SlimerJS
SlimerJS is kind of headless, but you will need Xvfb to have it real headless. Run it like this to collect timing metrics:
~~~bash
sitespeed.io -u https://www.sitespeed.io --headless slimerjs -b headless
~~~

28
docs/3.x/index.md Normal file
View File

@ -0,0 +1,28 @@
---
layout: default
title: Documentation 3.x - sitespeed.io
description: Here's the documentation of how to use sitespeed.io.
keywords: documentation, web performance, sitespeed.io, graphite, navigation timing api
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Documentation for the sitespeed.io.
---
# Documentation 3.x
* [Introduction](/3.x/introduction/)
* [Installation](/3.x/installation/) - install using npm, Vagrant or run our Docker containers.
* [Configuration](/3.x/configuration/) - there's alot of things you can do with sitespeed.io, lets checkout how!
* [The result](/3.x/result/) - get the result as HTML, TAP, JUnit XML or send the metrics to Graphite.
* [Rules and web performance best practice](/3.x/rules-and-best-practices/) - the rules used to create the sitespeed.io score.
* [Browsers](/3.x/browsers/) - collect timings using real browsers. We support Firefox, Chrome, Internet Explorer and Safari.
* [Headless](/3.x/headless/) - collect metrics using PhantomJS, SlimerJS or use Xvfb for your browser.
* [Use Cases](/3.x/use-cases/) - find out best practices for testing a site, compare with other sites.
* [Performance Dashboard](/3.x/performance-dashboard/) - keep track of your metrics and performance.
* [Performance Budget](/3.x/performance-budget/) - make sure you are within your performance budget.
* [Graphs](/3.x/graphs/) - graph you webperf metrics using Graphite and Grafana.
* [Continuous Integration](/3.x/continuous-integration/) - generate JUnit XML/TAP and use Jenkins, Team City, Grunt or the Gulp plugin.
* [Docker](/3.x/docker/) - how to use our Docker containers.
* [WebPageTest](/3.x/webpagetest/) - drive WebPageTest and fetch metrics and graph them.
* [Google Page Speed Insights](/3.x/gpsi/) - include GPSI metrics in your reports.
* [Developers](/3.x/developers/) - more info on how to create your own post tasks or use your own rules.

View File

@ -0,0 +1,63 @@
---
layout: default
title: Installation - Documentation - sitespeed.io
description: How to to install sitespeed.io. Use npm, our Vagrant files or Docker.
keywords: installation, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: How to to install sitespeed.io. Use npm, our Vagrant files or Docker.
---
[Documentation 3.x](/documentation/) / Installation
# Installation
{:.no_toc}
* Lets place the TOC here
{:toc}
# Download and installation
## Install on Mac, Linux & Windows
Prerequisites: Install [NodeJS](http://nodejs.org/download/) ([Linux](https://github.com/creationix/nvm)) and make sure you have [npm](https://github.com/npm/npm) installed.
~~~ bash
$ npm install sitespeed.io
~~~
If you want it installed globally (running it from wherever):
~~~ bash
$ npm install -g sitespeed.io
~~~
Run
~~~ bash
sitespeed.io -h
~~~
or on Windows:
~~~ bash
$ sitespeed.io.cmd -h
~~~
## Vagrant
We have a couple of [Vagrant](https://github.com/sitespeedio/sitespeed.io-vagrant) boxes to get you up and running fast (installing sitespeed.io and browsers).
* [Ubuntu 14](https://github.com/sitespeedio/sitespeed.io-vagrant/tree/master/sitespeed-ubuntu14)
* [CentOS 7](https://github.com/sitespeedio/sitespeed.io-vagrant/tree/master/sitespeed-centos7)
## Docker
We have [Docker images](https://hub.docker.com/u/sitespeedio/) with sitespeed.io, Chrome, Firefox and Xvfb. They are super easy to use (Xvfb is started automatically when you start the container). Here's how to use the container with both Firefox & Chrome (install [Docker](https://docs.docker.com/installation/ubuntulinux/) or [Docker toolbox](https://www.docker.com/toolbox) first and start them).
~~~ bash
$ sudo docker pull sitespeedio/sitespeed.io
$ sudo docker run --privileged --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io sitespeed.io -u https://www.sitespeed.io -b firefox
~~~
That will output the data from the run in the current directory. You can read more about running the containers [here](/documentation/docker/).

View File

@ -0,0 +1,18 @@
---
layout: default
title: Introduction - Documentation - sitespeed.io
description: Introduction for sitespeed.io.
keywords: introduction, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Introduction for sitespeed.io.
---
[Documentation 3.x](/documentation/) / Introduction
# Introduction
Sitespeed.io is an open source tool that helps you understand if your site is fast or not. It tests your site against web performance best practice rules, get timings using Chrome/Firefox or PhantomJS 2 (using the Navigation Timing API and User Timing API).
You can also drive [WebPageTest](http://www.webpagetest.org/) using sitespeed.io, collecting data from multiple URL:s tested using WebPageTest.
Sitespeed.io outputs the information as HTML/JSON or JUnit XML or [TAP](http://testanything.org/). And can automatically send the collected metrics to [Graphite](http://graphite.wikidot.com/).

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

View File

@ -0,0 +1,89 @@
---
layout: default
title: Performance Budget - Documentation - sitespeed.io
description: Performance budget with sitespeed.io.
keywords: performance, budget, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Performance budget with sitespeed.io.
---
[Documentation 3.x](/documentation/) / Performance Budget
# Performance Budget
{:.no_toc}
* Lets place the TOC here
{:toc}
## Performance budget
Have you heard of a performance budget? If not, please read the excellent posts by Tim Kadlec [Setting a performance budget](http://timkadlec.com/2013/01/setting-a-performance-budget/) and [Fast enough](http://timkadlec.com/2014/01/fast-enough/). Also read Daniel Malls [How to make a performance budget](http://danielmall.com/articles/how-to-make-a-performance-budget/). After that, continue setup sitespeed.io :)
### How it works
When you run sitespeed.io configured with a budget, the script will exit with a exit status > 0 if the budget fails. It will log the budget items that are failing and the ones that are working, and create a HTML report for the budget.
The log will look something like this:
~~~
error: The budget for js requests http://www.cybercom.com/da/Denmark/ failed. The number of js requests 10 the limit is 5
error: The budget for css requests http://www.cybercom.com/da/Denmark/ failed. The number of css requests 2 the limit is 1
error: The budget for requests per page http://www.cybercom.com/da/Denmark/ failed. The number of requests is 28 and the limit is 10
info: The budget for image requests http://www.cybercom.com/da/Denmark/ passed [5]
error: The budget for js requests http://www.cybercom.com/Cases-and-clients/SF-BIO-app/ failed. The number of js requests 10 the limit is 5
...
~~~
And the report looks like this.
![Example of the budget](budget.png)
{: .img-thumbnail}
Lets see how you can configure your budgets.
### Testing timings
If you have a budget where you want to test the (RUM) speed index, you add a file like this:
~~~
{
"timings": {
"speedIndex": 1000
}
}
~~~
Then run it like this:
~~~bash
$ sitespeed.io -u https://www.sitespeed.io --budget myBudget.json -b chrome -n 11
~~~
You can test all timings produced by BrowserTime like *domContentLoadedTime* or *backEndTime*.
### Testing user timings
You can have a budget for your own User Timings metrics. For www.sitespeed.io we have two user timing metrics: *logoTime* and *headerTime*. You can add them to the budget like this:
~~~
{
"timings": {
"headerTime": 800,
"logoTime": 500
}
}
~~~
And they will be tested and matched against your configured value.
### Using WebPageTest
If you are using WebPageTest, you can setup a budget matching almost whatever WPT fetches but the most useable things are testing the number of requests, size, TTFB and the speed index score. To test all these four things, you add a JSON file looking like this:
~~~
{
"wpt" : {
"requests": 60,
"TTFB": 200,
"bytesIn": 1000000,
"SpeedIndex" : 1000
}
}
~~~
And change the values to what you want to test. In this example the budget will blow if we have more that 60 requests on a page, a time to first byte larger than 200 ms, a page weight more than 1000 kb and a speed index score larger than 1000.

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

View File

@ -0,0 +1,331 @@
---
layout: default
title: Dashboard - Documentation - sitespeed.io
description: Web performance dashboard using sitespeed.io.
keywords: dashboard, docker, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Web performance dashboard using sitespeed.io.
---
[Documentation 3.x](/documentation/) / Performance Dashboard
# Performance Dashboard
{:.no_toc}
* Lets place the TOC here
{:toc}
## Background
We have put a lot of love into making it easy to create your own performance dashboard. To get it up and running you need [Docker](https://www.docker.com/). That's it :)
The base is the Docker images:
* To collect metrics, use one of the three images: [sitespeed.io with Chrome, Firefox & Xvfb](https://hub.docker.com/r/sitespeedio/sitespeed.io/), [sitespeed.io with Chrome & Xvfb](https://hub.docker.com/r/sitespeedio/sitespeed.io-chrome/) or [sitespeed.io with Firefox & Xvfb](https://hub.docker.com/r/sitespeedio/sitespeed.io-firefox/).
* [Store the metrics using Graphite ](https://hub.docker.com/r/sitespeedio/graphite/). If you have a Graphite server up and running already you can use that one, just make sure to configure *storage-schemas* and *storage-aggregations*.
* [Graph the metrics using Grafana](https://hub.docker.com/r/grafana/grafana/).
* You can also send your Google Analytics metrics to Grafana using [this container](https://hub.docker.com/r/sitespeedio/gatographite/).
You can run these images on your own machine(s) or in the cloud. You only need Docker. But what will you get? We have set up an example site that you can try out yourself. We are proud to present
[dashboard.sitespeed.io](http://dashboard.sitespeed.io/).
## Metrics and what you can graph
There are lots of metrics collected, lets check what kind of views of the data you can create:
* [In deep info about your most important pages](http://dashboard.sitespeed.io/dashboard/db/metrics-for-one-page-american-airlines-home-page) - you can graph and keep track how your page is built (things like number of requests, request types and sizes) and how fast your page is using the Navigation Timing and User Timings.
[![Metrics for one page example](one-page.png)](http://dashboard.sitespeed.io/dashboard/db/metrics-for-one-page-american-airlines-home-page)
{: .img-thumbnail}
* [Keep track how your whole site is doing]((http://dashboard.sitespeed.io/dashboard/db/summary-of-a-site-america-airlines)) - summary for a whole site helps you see keep track of all tested pages. Use it to catch pages that are underperforming. And to keep track for your whole site over time. Do you see the red boxes in the image? That is budgets that haven't been met. You can configure budgets for all metrics making it super easy for all users to understand if the site is doing good or bad.
[![Summary](summary.png)](http://dashboard.sitespeed.io/dashboard/db/summary-of-a-site-america-airlines)
{: .img-thumbnail}
* [Competition ain't nothing](http://dashboard.sitespeed.io/dashboard/db/compare-multiple-sites) - compare multiple sites and keep track of them. This is an awesome way to keep track of your competition, how fast they are and how they are building their web sites.
[![Compare](compare.png)](http://dashboard.sitespeed.io/dashboard/db/compare-multiple-sites)
{: .img-thumbnail}
* [ WebPageTest](http://dashboard.sitespeed.io/dashboard/db/using-webpagetest) - yes we love WebPageTest and in this example we drive WebPageTest through sitespeed.io and graph the data. We use the <a href="http://www.webpagetest.org/getkey.php">free limited API key</a> provided by Akamai and you should setup your own WebPageTest instance so you can test all your important pages, as often as you need.
[![WebPageTest](webpagetest.png)](http://dashboard.sitespeed.io/dashboard/db/using-webpagetest)
{: .img-thumbnail}
* [Keep track of your third party content](http://dashboard.sitespeed.io/dashboard/db/3rd-party-america-airlines) - today most of the consumer web pages have about 40% of third party content. You don't want them to slow you down and so you need to keep track of how they are doing. Thanks <a href="https://twitter.com/JrnVdb">Jeroen Vd Berghe</a> for the help and inspiration with the graphs.
[![3rd party](3rdparty.png)](http://dashboard.sitespeed.io/dashboard/db/3rd-party-america-airlines)
{: .img-thumbnail}
* [Collect Custom Metrics](http://dashboard.sitespeed.io/dashboard/db/user-timing-and-custom-metrics) - collect your own defined metrics using the User Timing API and running your own Javascript snippets in the browser and the values will automatically be sent to Graphite (both for ach page and a summary for all pages). This is perfect if there's a metric that is super important for your site or if there's a metric that is missing in sitespeed.io. You can add it yourself, as long as you can fetch it using Javascript.
[![Custom metrics](custom-metrics2.jpg)](http://dashboard.sitespeed.io/dashboard/db/user-timing-and-custom-metrics)
{: .img-thumbnail}
* [Keep track of every page and every request](http://dashboard.sitespeed.io/dashboard/db/load-timings-per-asset) -
this is maybe a little bit crazy but you can collect
<a href="http://dashboard.sitespeed.io/dashboard/db/load-timings-per-asset">timings per request</a> You can graph things like time spent in *blocked*, *dns*, *connect*, *ssl*, *send*, *wait*, *receive* and *total* time. It will generate a lot of data but is extremely good to find slow loading assets from a 3rd party.
[![Timings per asset](perasset.png)](http://dashboard.sitespeed.io/dashboard/db/load-timings-per-asset)
{: .img-thumbnail}
## Setup the containers
It is easy to setup the containers. The only thing you need to do is set up directories where you store the data and start the containers.
### Graphite
First we want to have have Graphite to store the metrics. You want to store the data outside of your containers, so create an directory where you store the data. In this example we put it in */data/graphite/storage/whisper*
~~~
sudo mkdir -p /data/graphite/storage/whisper
~~~
Then start the image.
~~~
sudo docker run -d \
--name graphite \
-p 8080:80 \
-p 2003:2003 \
--restart="always" \
-v /data/graphite/storage/whisper:/opt/graphite/storage/whisper \
sitespeedio/graphite
~~~
Your Graphite instance will be behind Basic Auth (*guest/guest*), if your server is public you should change that by generating your own .htpasswd file. You can do that with [apache2-utils](http://httpd.apache.org/docs/2.2/programs/htpasswd.html). You run it like this:
~~~
sudo apt-get install apache2-utils
sudo htpasswd -c .htpasswd YOUR_USERNAME
~~~
And add this line when you start the Graphite docker image:
~~~
-v /your/path/.htpasswd:/etc/nginx/.htpasswd \
~~~
The full startup would then look like this:
~~~
sudo docker run -d \
--name graphite \
-p 8080:80 \
-p 2003:2003 \
--restart="always" \
-v /data/graphite/storage/whisper:/opt/graphite/storage/whisper \
-v /your/path/.htpasswd:/etc/nginx/.htpasswd \
sitespeedio/graphite
~~~
### Grafana
Before you start Grafana you want to make sure that the dashboard data is stored on disk. Create a directory that will hold the Grafana database:
~~~
sudo mkdir -p /data/grafana
~~~
And then start Grafana, map the directory, and add a new admin user & password.
~~~
sudo docker run -d -p 3000:3000 \
-v /data/grafana:/var/lib/grafana \
-e "GF_SECURITY_ADMIN_USER=myuser" \
-e "GF_SECURITY_ADMIN_PASSWORD=MY_SUPER_STRONG_PASSWORD" \
--name grafana \
--restart="always" \
grafana/grafana
~~~
The next step is to access your Grafana instance and configure it to use your Graphite instance as backend. Choose *Grafana admin* > *Data Sources* > *Add new*. And then make sure to set it as default and enable Basic Auth.
![Configure Grafana to use Graphite](configure-grafana.jpg)
{: .img-thumbnail}
### Collect metrics
Now we need to collect that precious metrics. Do it by the old crontab. But first create a data dir where you can put the input/output files for sitespeed.io:
~~~
sudo mkdir /sitespeed.io
~~~
Then edit your crontab:
~~~
sudo crontab -e
~~~
And add something like this (make sure to change the URL and the host). In this example we run every 15 minutes, but you can of course change it:
~~~
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0,15,30,45 * * * * docker run --privileged --rm -v /sitespeed.io:/sitespeed.io sitespeedio/sitespeed.io sitespeed.io -u http://mysite.com -b firefox -n 5 --connection cable -r /tmp/ --graphiteHost YOUR_GRAPHITE_HOST --seleniumServer http://127.0.0.1:4444/wd/hub >> /tmp/sitespeed-run.txt 2>&1
~~~
You can of course fetch URL:s from a file and store the output if you want. To do that add a file in you */sitespeed.io/* directory containing all the URL:s and run it like this:
~~~
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0,15,30,45 * * * * docker run --privileged --rm -v /sitespeed.io:/sitespeed.io sitespeedio/sitespeed.io sitespeed.io -f urls.txt -b firefox -n 11 --connection cable -r /tmp/ --graphiteHost YOUR_GRAPHITE_HOST --seleniumServer http://127.0.0.1:4444/wd/hub >> /tmp/sitespeed-run.txt 2>&1
~~~
Note: You need to configure the selenium server to use (there are bugs running it straight with NodeJS and Linux). You do that by adding --**seleniumServer http://127.0.0.1:4444/wd/hub** to your run. Using the selenium server will make your runs more stable.
{: .note .note-warning}
#### Collect from multiple locations
It works perfectly to collect data from different servers/locations and send the data to the same Graphite server. What you need to do is give the keys in Graphite different names so that they don't collide. You do that by setting the *graphiteNamespace* when you run sitespeed and you'll have unique namespaces.
~~~
sitespeed.io -u http://mysite.com -b firefox --graphiteHost YOUR_GRAPHITE_HOST --graphiteNamespace sitespeed.io.newyork
~~~
## Setup your dashboards
To get up and running fast we have a [zip file](dashboards.zip) with example JSON:s that you can use to. Remember though that you need to change the keys to match your keys so you can see values.
If you need help, checkout the [Grafana documentation](http://docs.grafana.org/).
## Limit the amount of data in Graphite
If you test many pages you will have a lot of data stored in Graphite, make sure you set it up correctly for what you need.
### Configure sitespeed.io what metrics to send
You can choose to send the following metrics to Graphite:
* *summary* - the summary of a whole sites, it's the same data as shown on the summary HTML page
* *rules* - how each and every tested page match against the web performance best practice rules
* *pagemetrics* - how each and every page is built, like the number of javascripts, css etc
* *timings* - the timings for every page fetched using the Navigation Timing API and User Timings
* *requests* - send the timings and size data for each and every request: *blocked*, *dns*, *connect*, *ssl*, *send*, *wait*, *receive* and *total* time. This will generate a lot of data.
* *domains* - send the usage and timings per domain.
By default all timings are sent. If you want to change that, remove the metrics you don't need:
~~~
--graphiteData summary,rules,pagemetrics,timings,requests
~~~
### Configure Graphite what data to keep
By default the metrics are stored for 60 days (except request timings they are only stored for 7 days by default) and you can change that. First [read](https://github.com/etsy/statsd/blob/master/docs/graphite.md) Etsy's nice write-up on how you configure Graphite. Create your own [storage-schemas.conf](https://github.com/sitespeedio/docker-graphite-statsd/blob/master/conf/graphite/storage-schemas.conf) file and feed it to the image on startup like this:
~~~
-v /path/to/storage-schemas.conf:/opt/graphite/conf/storage-schemas.conf
~~~
You can also configure how data is aggregated over time. Check out the default configuration [storage-aggregation.conf](https://github.com/sitespeedio/docker-graphite-statsd/blob/master/conf/graphite/storage-aggregation.conf) and reread Etsy's nice write-up :)
## Add events/annotations to the graphs
Graphite comes with an [event API](http://obfuscurity.com/2014/01/Graphite-Tip-A-Better-Way-to-Store-Events) so you can mark specific events like releases. You can simply do that with a curl!
~~~
curl -u LOGIN:PASSWORD -X POST "http://HOSTNAME:8080/events/" -d '{"what": "Deploy", "tags": "production deploy example", "data": "deploy of master branch, version 1.0.0"}'
~~~
Change the LOGIN and PASSWORD to the Basic Auth you are using for Graphite and the HOSTNAME to your host. Then for each dashboard choose *Annotations* and the one you use by the tag(s).
## Memcached (optional)
If you setup a dashboard and you collect many different graphs on one page, it is good to add *memcached* in your setup, that will cache queries done to Graphite. Download and start it. In this example we just open the port, if you have a system reachable from the outside you should link the containers.
~~~
sudo docker pull memcached
sudo docker run --name memcache -p 11211:11211 -d memcached
~~~
The next step is to configure Graphite. You do that by changing your *local_settings.py*. Take a copy of the default one located [here](https://github.com/sitespeedio/docker-graphite-statsd/blob/master/scripts/local_settings.py) and edit it. You can add multiple *memcached* instances, if you want but lets start with one, change *$MY_IP* to the IP of your server running memcached.
~~~
# Array of memcache hosts. domain/ip and port ['10.10.10.10:11211', '10.10.10.11:11211']
MEMCACHE_HOSTS = ['$MY_IP:11211']
# Cache for 1 minute
DEFAULT_CACHE_DURATION = 60
~~~
And then when you start Graphite, make sure to link in the new file.
~~~
-v /my/path/local_settings.py:/opt/graphite/webapp/graphite/local_settings.py \
~~~
## Known problems
Modern browsers uses a lot of CPU and memory, so to avoid browser problems, run the browsers on a dedicated machine or instance. That works best.
Internet can fail. Yep I guess you may know that already. Today we have a fail fast setup, meaning if we get an error when we fetch a page that we can't handle or was prepared for, we fail and stop the run. That's good in a way because we will try it the next run. But it's bad because if we have a problem, we don't retry (it could be a problem that only exists for a second). In coming releases we will add retry and even better error handling.
We use [Loggly](http://loggly.com/) to keep track of errors, you should use something like that to make sure everything works fine.
## Crontab setup for dashboard.sitespeed.io
How do we run the jobs on dashboard.sitespeed.io? We have setup the crontab for the root user like this.
~~~
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0,30 * * * * docker run --privileged --rm -v /sitespeed.io:/sitespeed.io sitespeedio/sitespeed.io sitespeed.io --sites urls/united.txt --sites urls/aa.txt --sites urls/ryanair.txt --sites urls/lufthansa.txt -b firefox -n 3 --connection cable -r /tmp/ -d 0 --graphiteHost MY_SECRET_HOST --no-html --seleniumServer http://127.0.0.1:4444/wd/hub --phantomjsPath /usr/local/phantomjs/bin/phantomjs >> /tmp/sitespeed-run.txt 2>&1
15 * * * * docker run --privileged --rm -v /sitespeed.io:/sitespeed.io sitespeedio/sitespeed.io-standalone sitespeed.io -f urls/nytimes.txt --wptHost www.webpagetest.org --wptKey MY_SUPER_SECRET_KEY --graphiteNamespace webpagetest -d 0 -r /tmp/ --graphiteHost MY_SECRET_HOST --noYslow --wptConfig wpt.json >> /tmp/sitespeed-run-wpt.txt 2>&1
45 * * * * docker run --privileged --rm -v /sitespeed.io:/sitespeed.io sitespeedio/sitespeed.io sitespeed.io -u https://www.sitespeed.io -d 0 -n 3 -b chrome --connection mobile3g -r /tmp/ -d 0 --graphiteHost MY_SECRET_HOST --no-html --customScripts scripts --graphiteNamespace sitespeed.io.custom.mobile3g --seleniumServer http://127.0.0.1:4444/wd/hub --phantomjsPath /usr/local/phantomjs/bin/phantomjs >> /tmp/sitespeed.io-run.txt 2>&1
~~~
# Example setup: Digital Ocean
In this example we will use [Digital Ocean](https://www.digitalocean.com/), because they are super fast. Today they have data centers in San Francisco, New York, London, Amsterdam and Singapore. You can choose to deploy on one or all of them.
When we've been testing, we have seen that you can Firefox or Chrome on a $5 instance (remember to setup the swap space!). In this example we will use a $20 instance and put everything on that.
* Create a new droplet, choose the one with *2 GB / 2 CPUs 40 GB SSD Disk* and the region you want.
Click on the *Application* tab and choose *Docker on 14.04*
* Remember to add the **SSH keys** for your user. Follow the [tutorial](https://www.digitalocean.com/community/tutorials/how-to-use-ssh-keys-with-digitalocean-droplets) of how to create your SSH keys.
* Start your droplet.
* When it is up and running, log into your server *ssh root@YOUR_IP*
* Setup the server following Digital Oceans [Initial Server Setup Guide](https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04) to make your server a little more secure.
* [Add swap space](https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-14-04) and avoid out of memory errors.
* Pull the Docker images:
*sudo docker pull sitespeedio/sitespeed.io* ,
*sudo docker pull sitespeedio/graphite* and *sudo docker pull grafana/grafana*
* Create the directories:
~~~
sudo mkdir -p /data/graphite/storage/whisper
sudo mkdir -p /data/grafana
sudo mkdir /sitespeed.io
~~~
* Start Grafana & Graphite (first create your own .htpasswd file and change the user and admin user password):
~~~
sudo docker run -d \
--name graphite \
-p 8080:80 \
-p 2003:2003 \
--restart="always" \
-v /data/graphite/storage/whisper:/opt/graphite/storage/whisper \
-v /your/path/.htpasswd:/etc/nginx/.htpasswd \
sitespeedio/graphite
sudo docker run -d -p 3000:3000 \
-v /data/grafana:/var/lib/grafana \
-e "GF_SECURITY_ADMIN_USER=myuser" \
-e "GF_SECURITY_ADMIN_PASSWORD=MY_SUPER_STRONG_PASSWORD" \
--name grafana \
--restart="always" \
grafana/grafana
~~~
* Create a file with the URL:s you want to test by *sudo nano /sitespeed.io/urls.txt*:
~~~
http://www.myfirsturl.com
http://www.myfirsturl.com/1/
http://www.myfirsturl.com/2/
http://www.myfirsturl.com/3/
~~~
* **sudo crontab -e** (choose nano and make sure to edit your YOUR_GRAPHITE_HOST to the IP of your server).
~~~
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0,15,30,45 * * * * docker run --privileged --rm -v /sitespeed.io:/sitespeed.io sitespeedio/sitespeed.io sitespeed.io -f urls.txt -b firefox -n 11 --connection cable -r /tmp/ --graphiteHost YOUR_GRAPHITE_HOST --seleniumServer http://127.0.0.1:4444/wd/hub >> /tmp/sitespeed-run.txt 2>&1
~~~
* The next step is to log in to your Grafana instance and configure Graphite as your backend. Then you can start creating your own dashboards.

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

84
docs/3.x/result/index.md Normal file
View File

@ -0,0 +1,84 @@
---
layout: default
title: The result - Documentation - sitespeed.io
description: Result from an analyze using sitespeed.io.
keywords: configuration, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Result from an analyze using sitespeed.io.
---
[Documentation 3.x](/documentation/) / Result
# The Result
{:.no_toc}
* Lets place the TOC here
{:toc}
# HTML
The result of an analyze can be a couple of HTML pages, JUnit XML/TAP and you can
send the metrics to [Graphite](#graphite). Lets first checkout the different HTML pages.
## Site summary page
The summary page is a executive summary page where green is good, yellow means that you should look into it and red is bad (sometimes really bad). The page shows a summary of best practices for good web site performance (and site speed metrics if configured). You can choose which boxes/best practices that will be shown on this page, so you can create different views for different use cases.
![Site summary page](site-summary-3.png)
{: .img-thumbnail}
## The detailed summary page
The detailed summary page will give you almost all the metrics you want for you site. You will get the average, 10th percentile, median, 95th percentile, min, max and standard deviation value for each metrics (this page is based on the **summary.json** file, where you also will find the variance and the 90th percentile, if ever needed when comparing metrics).
![Detailed site summary page](detailed-site-summary-3.png)
{: .img-thumbnail}
## Detailed site report
The detailed site report page shows data collected for each page. You can configure which metrics/data that you want to show in the columns, so you can choose what is extra important for you.
![Detailed site report](detailed-site-report-3.png)
{: .img-thumbnail}
## Full page analyzes
Every page that is tested, also get a corresponding HTML page, where all in deep data is shown. Checkout the [examples](/example/) section to see what it looks like.
![Full page report](full-page-report-3.png)
{: .img-thumbnail}
## Most used assets report
The most used assets report show you the most used assets (a.k.a which asset should you start to change to get the most bang for the money).
You will see the following for each asset: the type, the time since last modification, the cache time, the weight and the number of times the asset has been used.
![Assets report](assets-report-3.png)
{: .img-thumbnail}
## Hotlist
The hotlist is a way of trying to find bad pages/assets that you should focus on to get better performance.
![Hotlist report](hotlist-report-3.png)
{: .img-thumbnail}
## Domains
If you fetch timings using your browser, the domains page will be created, that shows timings per domain, making it easier to spot 3rd party domains that is slow.
![Domains report](domains-report-3.png)
{: .img-thumbnail}
## Screenshots
You can choose to take screenshots of every tested page for the used viewport.
# JSON
All collected data will be stored as a fat JSON file in your data directory if you add *storeJson* when you run sitespeed.io. That is good if you yourself want to harvest the data from the result.
# Graphite
Most of the collected metrics can be stored in Graphite, making it easy for you to graph the metrics. Checkout the [Graph section](/documentation/graphs/).
# TAP and JUnit XML
You can create TAP or JUnit XML from your analyze, head over to the [Continuous Integration section](/documentation/continuous-integration/#generating-junit-xml-or-tap).

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

View File

@ -0,0 +1,185 @@
---
layout: default
title: The performace best practices rules used by Sitespeed.io
description: Here are the list of performance best practices rules used by sitespeed.io when analyzing your website. It will check for SPOF, synchronously loaded javascripts inside head and a lot of more things.
author: Peter Hedenskog
keywords: sitespeed.io, rules, wpo, fast, speed, web performance optimization, best practices
nav: documentation
---
[Documentation 3.x](/documentation/) / Rules and best practices
# The rules
{:.no_toc}
Sitespeed.io uses performance best practices rules to decide if a page is optimized for performance. The idea of rules for performance was started by Steve Souders
[14 rules for faster loading websites](http://stevesouders.com/hpws/rules.php) in 2007. Those rules and a couple of more is implemented in YSlow. Sitespeed.io uses these rules and approx. 20 more (it has happened things since 2007). You can see all rules used [here](#allrules). There are two set of rules; desktop & mobile. Desktop is the default one and described on this page. The mobile rules are the same rules, but they have different weight.
You can see the exact implementation [here](https://github.com/soulgalore/yslow/blob/master/src/common/rulesets/ruleset_sitespeed.js).
## Don't break the rules!
{:.no_toc}
Sitespeed.io is very demanding on your site, it will test/analyze and punish hard if you have broken the most important rules.
Sitespeed.io uses about 20 of the basic rules from YSlow (read about them
[here](http://yslow.org#web_performance_best_practices_and_rules) and [here](https://github.com/marcelduran/yslow/wiki/Ruleset-Matrix) and then there are the sitespeed.io specific rules.
## The rules
{:.no_toc}
* Lets place the TOC here
{:toc}
### Critical Rendering Path
Every request fetched inside of HEAD, will postpone the rendering of the page! Do not load javascript synchronously inside of head, load files from the same domain as the main document (to avoid DNS lookups) and inline CSS for a really fast rendering path. The scoring system for this rule, will give you minus score for synchronously loaded javascript inside of head, CSS files requested inside of head and minus for every DNS lookup inside of head. If you want to have a really fast first paint (and you always want that), make sure to score high on this rule.
You can read more about the critical rendering path in [this](http://calendar.perfplanet.com/2012/deciphering-the-critical-rendering-path/) article by Ilya Grigorik and [this](http://www.phpied.com/css-and-the-critical-path/) post by Stoyan Stefanov.
{: .note .note-info}
### Never scale images in HTML
Images should always be sent with the correct size else the browser will download an image that is larger than necessary. This is more important today with responsive web design, meaning you want to avoid downloading non scaled images to a mobile phone or tablet. Note: This rule doesn't check images with size 0 (images in carousels etc), so they will be missed by the rule.
Set the viewport size when you analyze a page and you will get the real image size & the image screen size with this rule!
{: .note .note-info}
### Frontend single point of failure (SPOF)
A page can be stopped to be loaded in the browser, if a single script, css and in some cases a font couldn't be fetched or loading slow (the white screen of death!). You really want to avoid that. Never load 3rd party components inside of head! One important note, right now this rule treats domain and subdomains as ok, that match the document domain, all other domains is treated as a SPOF. The score is calculated like this: Synchronously loaded javascripts inside of head, hurts you the most & then CSS files inside of head hurts a little less. You can also look for Font Face inside of CSS files and inline font face files, but they are considered minor and not turned on by default. One rule SPOF rule missing is the IE specific feature, that a font face will be SPOF if a script is requested before the font face file.
Read more about SPOF in [this](http://www.stevesouders.com/blog/2010/06/01/frontend-spof/") nice blog post by Steve Souders.
{: .note .note-info}
### Low number of total requests
Avoid have too many requests on your page. The more requests, the slower the page will be. This is extremely important on mobile devices, keep the requests as few as possible. But remember that using SPDY and the forthcoming HTTP 2.0, requests to the same domain will be done at the same time, meaning the total number of requests will be less important.
### Do not load specific CSS file for print
Loading a specific stylesheet for print, can block rendering in your browser (depending on version) and will for almost all browsers, block the onload event to fire (even though the print stylesheet isn't even used). In the old times, it was ok to have own print styles, but nowadays you can keep them in the same CSS file.
You can read more about it [here](http://www.phpied.com/5-years-later-print-css-still-sucks/).
{: .note .note-info}
### Load CSS in HEAD from document domain
CSS files inside of the HEAD tag, should be loaded from the same domain as the main document, in order to avoid DNS lookups. This is extra important for mobile. This rule exist in YSLow don't work on PhantomJS. This modified version do.
### Never load JS synchronously in HEAD
Javascript files should never be loaded synchronously inside the HEAD tag, because it will block the rendering of the page. This rule exist in YSLow don't work on PhantomJS. This modified version do.
### Avoid use of web fonts
Avoid use of web fonts because they will decrease the performance of the page. Web fonts are faster today then they ever has been, but still they will decrease performance.
Read [more](http://www.stevesouders.com/blog/2009/10/13/font-face-and-performance/) about avoiding web fonts.
{: .note .note-info}
### Have expire headers for static components
This is a modified version of YSlow expire rule, it will look for assets without any expire headers, meaning all assets without any expire headers will be reported.
### Have expires headers equals or longer than one year
Having really long cache headers are beneficial for caching.
### Avoid DNS lookups when the page has few request
If you have few requests on a page, they should all be on the same domain to avoid DNS lookups, because the lookups will cost much. This rule only kicks in if you have fewer request than 10 on the page.
### Do not load stylesheet files when the page has few request
When a page has few requests (or actually maybe always if you don't have a massive amount of CSS), it is better to inline the CSS, to make the page to start render as early as possible.
### Have a reasonable percentage of textual content compared to the rest of the page
Make sure you don't have too much styling etc that hides the text you want to deliver.
### Load third party JS asynchronously
Always load third party javascript asynchronously. Third parties that will be checked are Twitter, Facebook, Google (api, analytics, ajax), LinkedIn, Disqus, Pinterest & JQuery.
Read more about asynchronously third party scripts [here](http://www.phpied.com/3PO#async). This rule is borrowed from Stoyan Stefanov :)
{: .note .note-info}
<!-- Genererated from a sitespeed run -->
<h2>The rules</h2>
<p>The rules are a mashup between classic YSlow rules & new sitespeed.io rules, all are based on performance best practices. The current version of the rules is sitespeed.io-desktop.
<h3 id="Avoid slowing down the critical rendering path">Avoid slowing down the critical rendering path<em class="url"> (criticalpath)</em></h3>
<p>Every request fetched inside of HEAD, will postpone the rendering of the page! Do not load javascript synchronously inside of head, load files from the same domain as the main document (to avoid DNS lookups) and inline CSS for a really fast rendering path. The scoring system for this rule, will give you minus score for synchronously loaded javascript inside of head, css files requested inside of head and minus score for every DNS lookup inside of head.<em>Weight: 15</em></p>
<h3 id="Frontend single point of failure">Frontend single point of failure<em class="url"> (spof)</em></h3>
<p> A page can be stopped to be loaded in the browser, if a single script, css and in some cases a font couldn&#x27;t be fetched or loading slow (the white screen of death), and that is something you really want to avoid. Never load 3rd party components inside of head! One important note, right now this rule treats domain and subdomains as ok, that match the document domain, all other domains is treated as a SPOF. The score is calculated like this: Synchronously loaded javascripts inside of head, hurts you the most, then CSS files inside of head hurts a little less, font face inside of css files further less, and least inline font face files. One rule SPOF rule missing is the IE specific feature, that a font face will be SPOF if a script is requested before the font face file.<em>Weight: 5</em></p>
<h3 id="Make fewer HTTP requests for CSS files">Make fewer HTTP requests for CSS files<em class="url"> (cssnumreq)</em></h3>
<p>Decreasing the number of components on a page reduces the number of HTTP requests required to render the page, resulting in faster page loads. Combine your CSS files into as few as possible.<em>Weight: 8</em></p>
<h3 id="Make fewer HTTP requests for CSS image files">Make fewer HTTP requests for CSS image files<em class="url"> (cssimagesnumreq)</em></h3>
<p>Decreasing the number of components on a page reduces the number of HTTP requests required to render the page, resulting in faster page loads. Combine your CSS images files into as few CSS sprites as possible.<em>Weight: 8</em></p>
<h3 id="Make fewer synchronously HTTP requests for Javascript files">Make fewer synchronously HTTP requests for Javascript files<em class="url"> (jsnumreq)</em></h3>
<p>Decreasing the number of components on a page reduces the number of HTTP requests required to render the page, resulting in faster page loads. Combine your Javascript files into as few as possible (and load them asynchronously).<em>Weight: 8</em></p>
<h3 id="Avoid empty src or href">Avoid empty src or href<em class="url"> (yemptysrc)</em></h3>
<p>You may expect a browser to do nothing when it encounters an empty image src. However, it is not the case in most browsers. IE makes a request to the directory in which the page is located; Safari, Chrome, Firefox 3 and earlier make a request to the actual page itself. This behavior could possibly corrupt user data, waste server computing cycles generating a page that will never be viewed, and in the worst case, cripple your servers by sending a large amount of unexpected traffic.<em>Weight: 30</em></p>
<h3 id="Compress components with gzip">Compress components with gzip<em class="url"> (ycompress)</em></h3>
<p>Compression reduces response times by reducing the size of the HTTP response. Gzip is the most popular and effective compression method currently available and generally reduces the response size by about 70%. Approximately 90% of today&#x27;s Internet traffic travels through browsers that claim to support gzip.<em>Weight: 8</em></p>
<h3 id="Put CSS at top">Put CSS at top<em class="url"> (ycsstop)</em></h3>
<p>Moving style sheets to the document HEAD element helps pages appear to load quicker since this allows pages to render progressively.<em>Weight: 4</em></p>
<h3 id="Put JavaScript at bottom">Put JavaScript at bottom<em class="url"> (yjsbottom)</em></h3>
<p>JavaScript scripts block parallel downloads; that is, when a script is downloading, the browser will not start any other downloads. To help the page load faster, move scripts to the bottom of the page if they are deferrable.<em>Weight: 4</em></p>
<h3 id="Avoid CSS expressions">Avoid CSS expressions<em class="url"> (yexpressions)</em></h3>
<p>CSS expressions (supported in IE beginning with Version 5) are a powerful, and dangerous, way to dynamically set CSS properties. These expressions are evaluated frequently: when the page is rendered and resized, when the page is scrolled, and even when the user moves the mouse over the page. These frequent evaluations degrade the user experience.<em>Weight: 3</em></p>
<h3 id="Reduce DNS lookups">Reduce DNS lookups<em class="url"> (ydns)</em></h3>
<p>The Domain Name System (DNS) maps hostnames to IP addresses, just like phonebooks map people&#x27;s names to their phone numbers. When you type URL www.yahoo.com into the browser, the browser contacts a DNS resolver that returns the server&#x27;s IP address. DNS has a cost; typically it takes 20 to 120 milliseconds for it to look up the IP address for a hostname. The browser cannot download anything from the host until the lookup completes.<em>Weight: 3</em></p>
<h3 id="Minify JavaScript and CSS">Minify JavaScript and CSS<em class="url"> (yminify)</em></h3>
<p>Minification removes unnecessary characters from a file to reduce its size, thereby improving load times. When a file is minified, comments and unneeded white space characters (space, newline, and tab) are removed. This improves response time since the size of the download files is reduced.<em>Weight: 4</em></p>
<h3 id="Never do redirects">Never do redirects<em class="url"> (redirects)</em></h3>
<p>Redirects is bad for performance, specially for mobile.<em>Weight: 4</em></p>
<h3 id="Remove duplicate JavaScript and CSS">Remove duplicate JavaScript and CSS<em class="url"> (noduplicates)</em></h3>
<p>Duplicate JavaScript and CSS files hurt performance by creating unnecessary HTTP requests (IE only) and wasted JavaScript execution (IE and Firefox). In IE, if an external script is included twice and is not cacheable, it generates two HTTP requests during page loading. Even if the script is cacheable, extra HTTP requests occur when the user reloads the page. In both IE and Firefox, duplicate JavaScript scripts cause wasted time evaluating the same scripts more than once. This redundant script execution happens regardless of whether the script is cacheable.<em>Weight: 4</em></p>
<h3 id="Configure entity tags (ETags)">Configure entity tags (ETags)<em class="url"> (yetags)</em></h3>
<p>Entity tags (ETags) are a mechanism web servers and the browser use to determine whether a component in the browser&#x27;s cache matches one on the origin server. Since ETags are typically constructed using attributes that make them unique to a specific server hosting a site, the tags will not match when a browser gets the original component from one server and later tries to validate that component on a different server.<em>Weight: 2</em></p>
<h3 id="Make AJAX cacheable">Make AJAX cacheable<em class="url"> (yxhr)</em></h3>
<p>One of AJAX&#x27;s benefits is it provides instantaneous feedback to the user because it requests information asynchronously from the backend web server. However, using AJAX does not guarantee the user will not wait for the asynchronous JavaScript and XML responses to return. Optimizing AJAX responses is important to improve performance, and making the responses cacheable is the best way to optimize them.<em>Weight: 4</em></p>
<h3 id="Use GET for AJAX requests">Use GET for AJAX requests<em class="url"> (yxhrmethod)</em></h3>
<p>When using the XMLHttpRequest object, the browser implements POST in two steps: (1) send the headers, and (2) send the data. It is better to use GET instead of POST since GET sends the headers and the data together (unless there are many cookies). IE&#x27;s maximum URL length is 2 KB, so if you are sending more than this amount of data you may not be able to use GET.<em>Weight: 3</em></p>
<h3 id="Reduce the number of DOM elements">Reduce the number of DOM elements<em class="url"> (mindom)</em></h3>
<p>A complex page means more bytes to download, and it also means slower DOM access in JavaScript. Reduce the number of DOM elements on the page to improve performance.<em>Weight: 3</em></p>
<h3 id="Avoid HTTP 404 (Not Found) error">Avoid HTTP 404 (Not Found) error<em class="url"> (yno404)</em></h3>
<p>Making an HTTP request and receiving a 404 (Not Found) error is expensive and degrades the user experience. Some sites have helpful 404 messages (for example, &quot;Did you mean ...?&quot;), which may assist the user, but server resources are still wasted.<em>Weight: 4</em></p>
<h3 id="Reduce cookie size">Reduce cookie size<em class="url"> (ymincookie)</em></h3>
<p>HTTP cookies are used for authentication, personalization, and other purposes. Cookie information is exchanged in the HTTP headers between web servers and the browser, so keeping the cookie size small minimizes the impact on response time.<em>Weight: 3</em></p>
<h3 id="Use cookie-free domains">Use cookie-free domains<em class="url"> (ycookiefree)</em></h3>
<p>When the browser requests a static image and sends cookies with the request, the server ignores the cookies. These cookies are unnecessary network traffic. To workaround this problem, make sure that static components are requested with cookie-free requests by creating a subdomain and hosting them there.<em>Weight: 3</em></p>
<h3 id="Avoid AlphaImageLoader filter">Avoid AlphaImageLoader filter<em class="url"> (ynofilter)</em></h3>
<p>The IE-proprietary AlphaImageLoader filter attempts to fix a problem with semi-transparent true color PNG files in IE versions less than Version 7. However, this filter blocks rendering and freezes the browser while the image is being downloaded. Additionally, it increases memory consumption. The problem is further multiplied because it is applied per element, not per image.<em>Weight: 4</em></p>
<h3 id="Never scale images in HTML">Never scale images in HTML<em class="url"> (avoidscalingimages)</em></h3>
<p>Images should always be sent with the correct size else the browser will download an image that is larger than necessary. This is more important today with responsive web design, meaning you want to avoid downloading non scaled images to a mobile phone or tablet. Note: This rule doesn check images with size 0 (images in carousels etc), so they will be missed by the rule.The rule also skip images where the difference between the sizes are less than a configurable value (default 100 pixels).<em>Weight: 5</em></p>
<h3 id="Make favicon small and cacheable">Make favicon small and cacheable<em class="url"> (yfavicon)</em></h3>
<p>A favicon is an icon associated with a web page; this icon resides in the favicon.ico file in the server&#x27;s root. Since the browser requests this file, it needs to be present; if it is missing, the browser returns a 404 error (see &quot;Avoid HTTP 404 (Not Found) error&quot; above). Since favicon.ico resides in the server&#x27;s root, each time the browser requests this file, the cookies for the server&#x27;s root are sent. Making the favicon small and reducing the cookie size for the server&#x27;s root cookies improves performance for retrieving the favicon. Making favicon.ico cacheable avoids frequent requests for it.<em>Weight: 2</em></p>
<h3 id="Load third party javascript asynchronously">Load third party javascript asynchronously<em class="url"> (thirdpartyasyncjs)</em></h3>
<p>Always load third party javascript asynchronously. Third parties that will be checked are twitter, facebook, google (api, analythics, ajax), linkedin, disqus, pinterest &amp; jquery.<em>Weight: 10</em></p>
<h3 id="Avoid loading specific css for print">Avoid loading specific css for print<em class="url"> (cssprint)</em></h3>
<p>Loading a specific stylesheet for print, can block rendering in your browser (depending on browser version) and will for almost all browsers, block the onload event to fire (even though the print stylesheet is not even used!).<em>Weight: 3</em></p>
<h3 id="Load CSS in head from document domain">Load CSS in head from document domain<em class="url"> (cssinheaddomain)</em></h3>
<p>CSS files inside of HEAD should be loaded from the same domain as the main document, in order to avoid DNS lookups, because you want to have the HEAD part of the page finished as fast as possible, for the browser to be abe to start render the page. This is extra important for mobile.<em>Weight: 8</em></p>
<h3 id="Never load JS synchronously in head">Never load JS synchronously in head<em class="url"> (syncjsinhead)</em></h3>
<p>Javascript files should never be loaded synchronously in HEAD, because it will block the rendering of the page.<em>Weight: 20</em></p>
<h3 id="Avoid use of web fonts">Avoid use of web fonts<em class="url"> (avoidfont)</em></h3>
<p>Avoid use of webfonts because they will decrease the performance of the page.<em>Weight: 1</em></p>
<h3 id="Reduce number of total requests">Reduce number of total requests<em class="url"> (totalrequests)</em></h3>
<p>Avoid to have too many requests on your page. The more requests, the slower the page will be for the end user.<em>Weight: 10</em></p>
<h3 id="Have expire headers for static components">Have expire headers for static components<em class="url"> (expiresmod)</em></h3>
<p>By adding HTTP expires headers to your static files, the files will be cached in the end users browser.<em>Weight: 10</em></p>
<h3 id="Have expires headers equals or longer than one year">Have expires headers equals or longer than one year<em class="url"> (longexpirehead)</em></h3>
<p>Having really long cache headers are beneficial for caching.<em>Weight: 5</em></p>
<h3 id="Avoid DNS lookups when a page has few requests">Avoid DNS lookups when a page has few requests<em class="url"> (nodnslookupswhenfewrequests)</em></h3>
<p>If you have few requests on a page, they should all be on the same domain to avoid DNS lookups, because the lookups will cost much.<em>Weight: 8</em></p>
<h3 id="Do not load css files when the page has few request">Do not load css files when the page has few request<em class="url"> (inlinecsswhenfewrequest)</em></h3>
<p>When a page has few requests (or actually maybe always if you dont have a massive amount of css), it is better to inline the css, to make the page to start render as early as possible.<em>Weight: 7</em></p>
<h3 id="Have a reasonable percentage of textual content compared to the rest of the page">Have a reasonable percentage of textual content compared to the rest of the page<em class="url"> (textcontent)</em></h3>
<p>Make sure the amount of HTML elements are too many compared to text content.<em>Weight: 1</em></p>
<h3 id="Always use latest versions of third party javascripts">Always use latest versions of third party javascripts<em class="url"> (thirdpartyversions)</em></h3>
<p>Always use the latest &amp; greatest versions of third party javascripts, this is really important for JQuery, since the latest versions is always faster &amp; better.<em>Weight: 5</em></p>
<h3 id="Use a Content Delivery Network (CDN)">Use a Content Delivery Network (CDN)<em class="url"> (ycdn)</em></h3>
<p>User proximity to web servers impacts response times. Deploying content across multiple geographically dispersed servers helps users perceive that pages are loading faster.<em>Weight: 6</em></p>
<h3 id="Do not close the connection">Do not close the connection<em class="url"> (connectionclose)</em></h3>
<p>Check if the site closes a connection to a domain, where we have multiple requests. Use Keep-Alive headers and never close a connection<em>Weight: 7</em></p>
<h3 id="Do not use private headers on static assets">Do not use private headers on static assets<em class="url"> (privateheaders)</em></h3>
<p>Make all static assets cacheable for everyone and don&#x27;t set private cache headers. Will check for private headers for css, images, cssimages, fonts, flash &amp; favicon.<em>Weight: 3</em></p>

View File

@ -0,0 +1,85 @@
---
layout: default
title: Use Cases - Documentation - sitespeed.io
description: Use Cases for running sitespeed.io.
keywords: use case, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Use Cases for running sitespeed.io.
---
[Documentation 3.x](/documentation/) / Use Cases
# Use Cases
{:.no_toc}
* Lets place the TOC here
{:toc}
## Crawl and test one site
One of the most common use case is to crawl a site and analyze and measure the URL:s. Crawling a site is good because it will find new pages that are linked for the pages you crawl.
I use this for sites where the content team creates new pages directly in the CMS and I as developer are out of control of which pages that exist. Crawling will make sure we pick up new pages and measure them. I usually use this in production to pick up pages that could/should be faster.
Crawling too deep can take long time. One way to handle that is to test specific sections one at a time. Say we want to test sport pages for New York Times:
~~~bash
sitespeed.io -u http://www.nytimes.com/pages/sports/ -c /sports/ -d 2
~~~
Will make sure we only pick up pages under /sports/.
## Test specific URL:s for one site
Testing the same URL over and over again is good so you can benchmark it. I use it in my continuous integration tool (to check the performance before changes is released) and when I compare sites to its competitors (matching start pages, product pages, purchase flows etc).
### How do I choose which URL:s to test?
I usually use Google Analytics to check which are the most pages or talk to the business to check that we have the same understanding of which pages are the most important of our site. If we going to test the URL:s in our continuous integration, I try to keep the list of URL:s small, max 10, so we can test each URL many times to get timings that consistent between runs.
### Setup
I create a text file named amazon.txt with all the URL:s
~~~
http://www.amazon.com/
http://www.amazon.com/gp/site-directory/
http://www.amazon.com/dp/B00I15SB16/ref=ods_gw_comb_xmas_kindle
~~~
And run it like this
~~~bash
sitespeed.io -f amazon.txt -b chrome -n 11
~~~
## Compare and benchmark your site against other sites
Comparing your site against competitors is often very interesting. I usually use it to compare how fast pages are loaded and also how the pages are built (how many requests, how much javascript etc).
### Setup the files
I create one file containing the urls for each site that I want to test. Testing apple.com I create file named **apple.txt** with the URL:s I want to test:
~~~
http://www.apple.com/
http://www.apple.com/iphone/
http://www.apple.com/iphone-6/
~~~
and I compare it to Sony Mobile. I create a new text file named **sony.txt** with the following content:
~~~
http://www.sonymobile.com/se/
http://www.sonymobile.com/se/products/phones/
http://www.sonymobile.com/se/products/phones/xperia-z3-compact/
~~~
### Run the test
Then I run it like this:
~~~bash
sitespeed.io --sites apple.txt --sites sony.txt -d 0
~~~
Of course you can add all the parameters as usual to sitespeed, testing your site using Chrome, test 11 times and also test with WebPageTest and Google Page Speed Insights and sending the data to Graphite looks like this:
~~~bash
sitespeed.io --sites apple.txt --sites sony.txt -d 0 -b chrome -n 11 --wptHost your.webpagetest.com --gpsiKey YOUR_GOOGLE_KEY --graphiteHost mygraphitehost.com
~~~

View File

@ -0,0 +1,152 @@
---
layout: default
title: WebPageTest - Documentation - sitespeed.io
description: Drive WebPageTest using sitespeed.io and include the teh metrics in your sitespeed.io report.
keywords: webpagetest, wpt, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Drive WebPageTest using sitespeed.io and include the teh metrics in your sitespeed.io report.
---
[Documentation 3.x](/documentation/) / WebPageTest
# WebPageTest
{:.no_toc}
* Lets place the TOC here
{:toc}
# Using WebPageTest
Yep we all love [WebPageTest](http://www.webpagetest.org) (WPT), so we made it possible to drive an instance of and collect the data from it.
To use WPT you can either get an [API key](http://www.webpagetest.org/getkey.php) (sponsored by Akamai) for the global version or follow Pat Meenans instructions on [how to get a private version up and running in 5 minutes](http://calendar.perfplanet.com/2014/webpagetest-private-instances-in-five-minutes/).
Out of the it will collect [these](https://github.com/sitespeedio/sitespeed.io/tree/master/lib/aggregators/webpagetest) metrics that can be displayed on the summary page. By default, these will be shown:
![WebPageTest summary](wpt-summary.png)
{: .img-thumbnail}
On the pages summary, you will also automatically get the SpeedIndex score:
![WebPageTest pages](wpt-pages.png)
{: .img-thumbnail}
And on the detailed summary page, we show some interesting metrics and the waterfalls
for the median result of both first and repeated view:
![WebPageTest page info](wpt-detailed-page-info.png)
{: .img-thumbnail}
## Configuration
There is some default configuration that is passed to WebPageTest. It looks like this:
~~~
{
pollResults: 10,
timeout: 600,
firstViewOnly: false,
runs: n, // the number of times passed by -n, default 3
private: true,
aftRenderingTime: true,
location: 'Dulles:Chrome',
video: true
}
~~~
And if basic auth is set, it is passed as basic auth.
In the background the test method in Marcel Durans webpagetest-api is used, so you can configure almost everything. Checkout the docs [here](https://github.com/marcelduran/webpagetest-api#user-content-test-works-for-test-command-only). You configure your own stuff by feeding sitespeed.io with a JSON file. Say you want to test form Dulles using a throttled 3G connection:
~~~
{
"location": "Dulles:Firefox",
"connectivity": "3G"
}
~~~
The default location will be overidden and the connectivity will be set to 3G.
Feed it with: *--wptConfig yourFile.json*
If you want to test from multiple locations, browsers or different connectivity, pass an array as configuration:
~~~
[
{
"location": "Dulles:Firefox",
"connectivity": "3G"
},
{
"location": "Dulles:Chrome",
"connectivity": "Cable"
}
]
~~~
### WebPageTest scripting
WebPageTest has scripting capability where you can automate a multi-step test (=login the user and do stuff). That is supported by sitespeed.io by supplying the script. Do like this. Create your script file (checkout WebPageTest [documentation](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/scripting)). It can look something like this (wptScript.txt):
~~~
logData 0
// put any urls you want to navigate
navigate www.aol.com
navigate news.aol.com
logData 1
// this step will get recorded
navigate news.aol.com/world
~~~
Then change your URL you want test (probably the last one) to \{\{\{URL\}\}\} and then all occurrences of &#123;&#123;&#123;URL&#125;&#125;&#125; will then be replaced with the current URL that should be tested.
Then run sitespeed (and add the parameters as you usually do):
~~~
sitespeed.io --wptScript wptScript.txt --wptHost my.wpt.host.com -u http://example.org
~~~
### Custom metrics
Hey we love custom metrics and you can fetch them using WPT. Checkout the [metrics docs](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/custom-metrics) for WPT and then create a file containing your metrics:
~~~
[iframe-count]
return document.getElementsByTagName("iframe").length;
[script-tag-count]
return document.getElementsByTagName("script").length;
[meta-viewport]
var viewport = undefined;
var metaTags=document.getElementsByTagName("meta");
for (var i = 0; i < metaTags.length; i++) {
if (metaTags[i].getAttribute("name") == "viewport") {
viewport = metaTags[i].getAttribute("content");
break;
}
}
return viewport;
~~~
Then run sitespeed.io like this:
~~~
sitespeed.io --wptCustomMetrics myScriptFile.txt --wptHost my.wpt.host.com
~~~
The custom metrics will show up on the individual page and sent to Graphite.
## Graph the WPT metrics
The data collected and showed can also be sent to Graphite. Checkout the Graphite [section](#graphite-full).
## WPT performance budget
The timings and metrics collected by WebPageTest can also be used in you performance budget. More info [budget](#budget).
## Timing metrics collected using WPT
All the metrics are collected both for first and repeated view.
* *firstPaint* - the time from the start of navigation until the first non-white content was painted to the screen
* *loadTime* - the time from the start of the initial navigation until the beginning of the window load event (onload)
* *TTFB* - the time from the start of navigation until the first byte of the base page is returned (after following any redirects)
* *SpeedIndex* - is the average time at which visible parts of the page are displayed. It is expressed in milliseconds and dependent on size of the view port. You need to [read more](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index) to fully understand how it works.
* *VisualComplete*

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

6
docs/404.md Normal file
View File

@ -0,0 +1,6 @@
---
layout: notfound
title: 404 Page not found - sitespeed.io
permalink: /404.html
---
<div class="data"><a href="https://www.sitespeed.io/"><img src="{{site.baseurl}}/img/404c.png" class="cent"></a></div>

2
docs/Gemfile Normal file
View File

@ -0,0 +1,2 @@
source "https://rubygems.org"
gem 'github-pages', group: :jekyll_plugins

139
docs/Gemfile.lock Normal file
View File

@ -0,0 +1,139 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (4.2.7)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.4.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.10.0)
colorator (1.1.0)
ethon (0.9.1)
ffi (>= 1.3.0)
execjs (2.7.0)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
ffi (1.9.14)
forwardable-extended (2.6.0)
gemoji (2.1.0)
github-pages (98)
activesupport (= 4.2.7)
github-pages-health-check (= 1.2.0)
jekyll (= 3.2.1)
jekyll-coffeescript (= 1.0.1)
jekyll-feed (= 0.5.1)
jekyll-gist (= 1.4.0)
jekyll-github-metadata (= 2.1.1)
jekyll-mentions (= 1.2.0)
jekyll-paginate (= 1.1.0)
jekyll-redirect-from (= 0.11.0)
jekyll-sass-converter (= 1.3.0)
jekyll-seo-tag (= 2.0.0)
jekyll-sitemap (= 0.10.0)
jekyll-swiss (= 0.4.0)
jemoji (= 0.7.0)
kramdown (= 1.11.1)
liquid (= 3.0.6)
listen (= 3.0.6)
mercenary (~> 0.3)
minima (= 1.2.0)
rouge (= 1.11.1)
terminal-table (~> 1.4)
github-pages-health-check (1.2.0)
addressable (~> 2.3)
net-dns (~> 0.8)
octokit (~> 4.0)
public_suffix (~> 1.4)
typhoeus (~> 0.7)
html-pipeline (2.4.2)
activesupport (>= 2)
nokogiri (>= 1.4)
i18n (0.7.0)
jekyll (3.2.1)
colorator (~> 1.0)
jekyll-sass-converter (~> 1.0)
jekyll-watch (~> 1.1)
kramdown (~> 1.3)
liquid (~> 3.0)
mercenary (~> 0.3.3)
pathutil (~> 0.9)
rouge (~> 1.7)
safe_yaml (~> 1.0)
jekyll-coffeescript (1.0.1)
coffee-script (~> 2.2)
jekyll-feed (0.5.1)
jekyll-gist (1.4.0)
octokit (~> 4.2)
jekyll-github-metadata (2.1.1)
jekyll (~> 3.1)
octokit (~> 4.0)
jekyll-mentions (1.2.0)
activesupport (~> 4.0)
html-pipeline (~> 2.3)
jekyll (~> 3.0)
jekyll-paginate (1.1.0)
jekyll-redirect-from (0.11.0)
jekyll (>= 2.0)
jekyll-sass-converter (1.3.0)
sass (~> 3.2)
jekyll-seo-tag (2.0.0)
jekyll (~> 3.1)
jekyll-sitemap (0.10.0)
jekyll-swiss (0.4.0)
jekyll-watch (1.5.0)
listen (~> 3.0, < 3.1)
jemoji (0.7.0)
activesupport (~> 4.0)
gemoji (~> 2.0)
html-pipeline (~> 2.2)
jekyll (>= 3.0)
json (1.8.3)
kramdown (1.11.1)
liquid (3.0.6)
listen (3.0.6)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9.7)
mercenary (0.3.6)
mini_portile2 (2.1.0)
minima (1.2.0)
minitest (5.9.1)
multipart-post (2.0.0)
net-dns (0.8.0)
nokogiri (1.6.8.1)
mini_portile2 (~> 2.1.0)
octokit (4.3.0)
sawyer (~> 0.7.0, >= 0.5.3)
pathutil (0.14.0)
forwardable-extended (~> 2.6)
public_suffix (1.5.3)
rb-fsevent (0.9.7)
rb-inotify (0.9.7)
ffi (>= 0.5.0)
rouge (1.11.1)
safe_yaml (1.0.4)
sass (3.4.22)
sawyer (0.7.0)
addressable (>= 2.3.5, < 2.5)
faraday (~> 0.8, < 0.10)
terminal-table (1.7.3)
unicode-display_width (~> 1.1.1)
thread_safe (0.3.5)
typhoeus (0.8.0)
ethon (>= 0.8.0)
tzinfo (1.2.2)
thread_safe (~> 0.1)
unicode-display_width (1.1.1)
PLATFORMS
ruby
DEPENDENCIES
github-pages
BUNDLED WITH
1.13.2

7
docs/README.md Normal file
View File

@ -0,0 +1,7 @@
Documentation for sitespeed.io
================
To run it locally: <code>bundle install && bundle exec jekyll serve --baseurl ''</code>.
Checkout https://localhost:4000/

15
docs/_config.yml Normal file
View File

@ -0,0 +1,15 @@
permalink: /:title/
baseurl: /sitespeed.io
markdown: kramdown
compress_html:
clippings: all
endings: all
kramdown:
enable_coderay: false
coderay:
coderay_wrap: div
coderay_line_numbers: inline
coderay_line_number_start: 1
coderay_tab_width: 4
coderay_bold_every: 10
coderay_css: style

View File

View File

@ -0,0 +1,14 @@
html {
background-color:#5c90c4;
}
.data {
text-align: center
}
.cent {
margin: 20px auto;
max-width: 100%;
display:block;
height: auto;
}

View File

@ -0,0 +1,4 @@
{% include css/normalize.css %}
{% include css/grid.css %}
{% include css/navigation.css %}
{% include css/sitespeed.css %}

280
docs/_includes/css/grid.css Normal file
View File

@ -0,0 +1,280 @@
/*
Simple Grid
Project Page - http://thisisdallas.github.com/Simple-Grid/
*/
*, *:after, *:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
margin: 0px;
}
[class*='col-'] {
float: left;
padding-right: 20px;
padding-left: 20px;
}
.grid {
width: 100%;
max-width: 1140px;
min-width: 755px;
margin: 0 auto;
overflow: hidden;
}
.grid:after {
content: "";
display: table;
clear: both;
}
.grid-pad {
padding-top: 20px;
padding-left: 20px;
padding-right: 0px;
}
.push-right {
float: right;
}
.col-1-1 {
width: 100%;
}
.col-2-3, .col-8-12 {
width: 66.66%;
}
.col-1-2, .col-6-12 {
width: 50%;
}
.col-1-3, .col-4-12 {
width: 33.33%;
}
.col-1-4, .col-3-12 {
width: 25%;
}
.col-1-5 {
width: 20%;
}
.col-1-6, .col-2-12 {
width: 16.667%;
}
.col-1-7 {
width: 14.28%;
}
.col-1-8 {
width: 12.5%;
}
.col-1-9 {
width: 11.1%;
}
.col-1-10 {
width: 10%;
}
.col-1-11 {
width: 9.09%;
}
.col-1-12 {
width: 8.33%
}
.col-11-12 {
width: 91.66%
}
.col-10-12 {
width: 83.333%;
}
.col-9-12 {
width: 75%;
}
.col-5-12 {
width: 41.66%;
}
.col-7-12 {
width: 58.33%
}
.push-2-3, .push-8-12 {
margin-left: 66.66%;
}
.push-1-2, .push-6-12 {
margin-left: 50%;
}
.push-1-3, .push-4-12 {
margin-left: 33.33%;
}
.push-1-4, .push-3-12 {
margin-left: 25%;
}
.push-1-5 {
margin-left: 20%;
}
.push-1-6, .push-2-12 {
margin-left: 16.667%;
}
.push-1-7 {
margin-left: 14.28%;
}
.push-1-8 {
margin-left: 12.5%;
}
.push-1-9 {
margin-left: 11.1%;
}
.push-1-10 {
margin-left: 10%;
}
.push-1-11 {
margin-left: 9.09%;
}
.push-1-12 {
margin-left: 8.33%
}
@media handheld, only screen and (max-width: 767px) {
.grid {
width: 100%;
min-width: 0;
margin-left: 0px;
margin-right: 0px;
padding-left: 20px;
padding-right: 10px;
}
[class*='col-'] {
width: auto;
float: none;
margin-left: 0px;
margin-right: 0px;
margin-top: 10px;
margin-bottom: 10px;
padding-left: 0px;
padding-right: 10px;
}
[class*='mobile-col-'] {
float: left;
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
margin-bottom: 10px;
padding-left: 0px;
padding-right: 10px;
padding-bottom: 0px;
}
.mobile-col-1-1 {
width: 100%;
}
.mobile-col-2-3, .mobile-col-8-12 {
width: 66.66%;
}
.mobile-col-1-2, .mobile-col-6-12 {
width: 50%;
}
.mobile-col-1-3, .mobile-col-4-12 {
width: 33.33%;
}
.mobile-col-1-4, .mobile-col-3-12 {
width: 25%;
}
.mobile-col-1-5 {
width: 20%;
}
.mobile-col-1-6, .mobile-col-2-12 {
width: 16.667%;
}
.mobile-col-1-7 {
width: 14.28%;
}
.mobile-col-1-8 {
width: 12.5%;
}
.mobile-col-1-9 {
width: 11.1%;
}
.mobile-col-1-10 {
width: 10%;
}
.mobile-col-1-11 {
width: 9.09%;
}
.mobile-col-1-12 {
width: 8.33%
}
.mobile-col-11-12 {
width: 91.66%
}
.mobile-col-10-12 {
width: 83.333%;
}
.mobile-col-9-12 {
width: 75%;
}
.mobile-col-5-12 {
width: 41.66%;
}
.mobile-col-7-12 {
width: 58.33%
}
.hide-on-mobile {
display: none !important;
width: 0;
height: 0;
}
}

View File

@ -0,0 +1,134 @@
body {
margin: 0;
padding: 0;
background: #fff;
font-family: Tahoma, Verdana,sans-serif;
font-size: 19px;
line-height: 1.618em;
word-wrap: break-word;
}
.nav {
background: #0095d2;
}
.nav ul {
list-style: none;
text-align: center;
padding: 0;
margin: 0;
background-color: #0095d2;
}
.nav li {
font-size: 1em;
line-height: 40px;
height: 40px;
border-bottom: 1px solid #0073b0;
}
.nav a {
text-decoration: none;
color: #fff;
display: block;
}
.nav a:hover {
background-color: #0073b0;
}
.nav a.active {
background-color: #0073b0;
color: #fff;
cursor: default;
}
.logo {
text-align: center;
background-color: #0095d2;
}
.navbar-brand {
padding: 0px 0px;
font-size: 18px;
max-width: 250px;
}
.nav li ul {
position: absolute;
display: none;
width: inherit;
}
@media screen and (min-width: 820px) {
body
{ padding-top: 50px; }
.nav {
height: 50px;
width: 100%;
z-index: 1000;
position: fixed;
top: 0;
}
.navbar-brand {
padding: 0px 0px;
font-size: 18px;
float: left;
max-width: 250px;
}
.nav a {
padding-left: 20px;
padding-right: 20px;
}
.nav {
z-index: 10;
top: 0;
background-color: #0095d2;
}
.nav li {
border-bottom: none;
height: 50px;
line-height: 50px;
font-size: 1em;
float: left;
display: inline-block;
margin-right: 0px;
}
.nav a {
text-decoration: none;
color: #fff;
display: block;
}
.nav ul {
list-style: none;
text-align: center;
padding: 0;
margin: 0;
background-color: #0095d2;
}
/* Sub Menus */
.nav li ul {
position: absolute;
display: none;
width: inherit;
}
.nav li:hover ul {
display: block;
}
.nav li ul li {
display: block;
float: none;
}
}

289
docs/_includes/css/normalize.css vendored Normal file
View File

@ -0,0 +1,289 @@
/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
html {
font-family: sans-serif;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
display: block;
}
audio,
canvas,
progress,
video {
display: inline-block; /* 1 */
vertical-align: baseline; /* 2 */
}
audio:not([controls]) {
display: none;
height: 0;
}
[hidden],
template {
display: none;
}
a {
background-color: transparent;
}
a:active,
a:hover {
outline: 0;
}
abbr[title] {
border-bottom: 1px dotted;
}
b,
strong {
font-weight: bold;
}
dfn {
font-style: italic;
}
h1 {
font-size: 2em;
margin: 0.67em 0;
}
mark {
background: #ff0;
color: #000;
}
small {
font-size: 80%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
img {
border: 0;
}
svg:not(:root) {
overflow: hidden;
}
figure {
margin: 1em 40px;
}
hr {
-moz-box-sizing: content-box;
box-sizing: content-box;
height: 0;
}
pre {
overflow: auto;
}
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
button,
input,
optgroup,
select,
textarea {
color: inherit; /* 1 */
font: inherit; /* 2 */
margin: 0; /* 3 */
}
button {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
}
button[disabled],
html input[disabled] {
cursor: default;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
input {
line-height: normal;
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
input[type="search"] {
-webkit-appearance: textfield; /* 1 */
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /* 2 */
box-sizing: content-box;
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
legend {
border: 0; /* 1 */
padding: 0; /* 2 */
}
textarea {
overflow: auto;
}
optgroup {
font-weight: bold;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
td,
th {
padding: 0;
}

View File

@ -0,0 +1,180 @@
.blue {
background-color: #e1f6fd;
padding-bottom: 20px;
}
.copy {
padding-top: 20px;
}
.flogo {
padding-top: 10px;
}
footer h3 {
margin-bottom:10px;
}
.pull-left {
float: left!important;
}
.pull-right {
float: right!important;
}
.img-big {
margin-right: 20px;
}
.img-footer {
margin-top: 15px;
}
.middle {
vertical-align: middle;
width: 32px;
}
.fastly {
vertical-align: middle;
height: 32px;
}
hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top: 1px solid #eee;
box-sizing: content-box;
height: 0;
}
footer p {
text-align: center;
margin: 0;
}
a {
color: #428bca;
text-decoration: none;
}
.language-bash {
color: #fff;
background-color: #555;
font-size: 80%;
}
pre code {
display: block;
padding: 9.5px;
margin: 0 0 10px;
font-size: 13px;
line-height: 1.428571429;
word-break: break-all;
word-wrap: break-word;
color: #333;
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 4px;
font-family: Monaco,Menlo,Consolas,"Courier New",monospace;
white-space: pre-wrap;
}
.note-info {
background-color: #f0f7fd;
border-color: #d0e3f0;
}
.note {
margin: 20px 0;
padding: 15px 30px 15px 15px;
border-left: 10px solid #eee;
}
.note-warning {
background-color: #fcf2f2;
border-color: #dfb5b4;
}
.img-thumbnail img {
padding: 4px;
line-height: 1.428571429;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 4px;
-webkit-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
display: inline-block;
max-width: 100%;
height: auto;
}
.small {
font-size: 0.8em;
line-height: 1.2em;
}
footer ul {
list-style: none;
padding: 0;
margin: 0;
}
footer li {
padding-bottom: 4px;
}
footer a {
color: #0095d2;
}
a btn {
margin-top: 10px;
}
.photo {
border-radius: 10px;
margin-right: 20px;
margin-bottom: 10px;
}
.language-help {
overflow: auto;
word-wrap: normal;
white-space: pre;
}
@media screen and (max-width: 820px) {
.small {
text-align: center;
font-size: 19px;
}
h1 {
line-height: 1em;
}
ul {
padding-left: 10px;
margin-left: 10px;
}
}
.video-container {
position: relative;
padding-bottom: 56.25%;
padding-top: 30px; height: 0; overflow: hidden;
margin-right: 5%;
margin-left: 5%;
}
.video-container iframe,
.video-container object,
.video-container embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,60 @@
<hr>
<footer>
<div class="grid small">
<div class="col-1-5 hide-on-mobile">
<p>
<img src="{{site.baseurl}}/img/black-logo-120.png" width="60" height="64" class="img-footer">
</p>
<p>sitespeed.io</p>
</div>
<div class="col-1-5">
<h3>Universe</h3>
<ul>
<li><a href="https://github.com/sitespeedio/sitespeed.io">Source Code</a></li>
<li><a href="https://hub.docker.com/u/sitespeedio/">Docker</a></li>
<li><a href="https://github.com/tobli/browsertime">Browsertime</a></li>
<li><a href="https://github.com/sitespeedio/coach">The coach</a></li>
<li><a href="https://github.com/sitespeedio/pagexray">PageXray</a></li>
</div>
<div class="col-1-5">
<h3>Connect</h3>
<ul>
<li><a href="https://twitter.com/SiteSpeedio">Twitter</a></li>
<li><a href="https://www.facebook.com/sitespeed.io">Facebook</a></li>
<li><a href="https://github.com/sitespeedio">Github</a></li>
</div>
<div class="col-1-5">
<h3>sitespeed.io</h3>
<ul>
<li><a href="{{site.baseurl}}/aboutus/">About Us</a></li>
<li><a href="https://github.com/sitespeedio/sitespeed.io/blob/master/HELP.md">Help Us</a></li>
<li><a href="https://dashboard.sitespeed.io/">The dashboard</a></li>
<li><a href="https://www.stickermule.com/marketplace/2574-sitespeed-dot-io">Stickers</a></li>
<li><a href="{{site.baseurl}}/logo/">Logos</a></li>
</ul>
</div>
<div class="col-1-5">
<h3>&hearts; Open Source &hearts;</h3>
<ul>
<li><a href="http://www.seleniumhq.org/">Selenium</a></li>
<li><a href="https://github.com/WPO-Foundation/tsproxy">TSProxy</a></li>
<li><a href="https://github.com/micmro/PerfCascade">PerfCascade</a></li>
<li><a href="http://getskeleton.com/">Skeleton</a></li>
<li><a href="https://github.com/cgiffard/node-simplecrawler">Simplecrawler</a></li>
</ul>
</div>
<div class="col-1-1">
<p class="copy">
&copy; Sitespeed.io
{{ site.time | date: '%Y' }}, last updated {{ site.time | date: "%H:%M %d %B %Y" }}
</p>
<p class="flogo">The CDN is sponsored by <a href="https://www.fastly.com/"><img src="{{site.baseurl}}/img/fastly2.png" class="fastly"></a></p>
</div>
</div>
<p></p>
</footer>

View File

@ -0,0 +1,32 @@
<div class="darkblue nav">
<div class="grid">
<div class="col-1-1">
<div class="logo">
<a href="https://www.sitespeed.io"><img src="{{site.baseurl}}/img/sitespeed-logo-2c.png" class="navbar-brand" alt="Sitespeed.io - How speedy is your site?" width="162" height="50"/></a>
</div>
<ul>
<li>
<a href="{{site.baseurl}}" {% if page.nav == 'start' %}class="active" {% endif %}>Start</a>
</li>
<li>
<a href="{{site.baseurl}}/documentation/" {% if page.nav == 'tools' %}class="active" {% endif %}>Documentation</a>
<ul>
<li><a href="{{site.baseurl}}/documentation/sitespeed.io/">sitespeed.io</a></li>
<li><a href="{{site.baseurl}}/documentation/coach/">Coach</a></li>
<li><a href="{{site.baseurl}}/documentation/browsertime/">Browertime</a></li>
<li><a href="{{site.baseurl}}/documentation/pagexray/">PageXray</a></li>
</ul>
</li>
<li>
<a href="{{site.baseurl}}/example/" {% if page.nav == 'examples' %}class="active" {% endif %}>Examples</a>
</li>
<li>
<a href="{{site.baseurl}}/blog/" {% if page.nav == 'blog' %}class="active" {% endif %}>Blog</a>
</li>
<li>
<a href="{{site.baseurl}}/faq/" {% if page.nav == 'faq' %}class="active" {% endif %}>FAQ</a>
</li>
</ul>
</div>
</div>
</div>

View File

@ -0,0 +1,10 @@
{% for post in site.posts limit:1 %}
## {{ post.title }}
* * *
{{ post.intro }}
[Read the blog post to find out more.]({{ post.url }})
{% endfor %}

View File

@ -0,0 +1,6 @@
## Be a performance hero!
* * *
<img src="img/pippi.png" class="pull-left img-big" alt="Sitespeed.io logo" width="180" height="151">
With sitespeed.io it's easy to be a performance hero! Check out our [example dashboard](https://dashboard.sitespeed.io), it's the best example that shows you what you can do.

View File

@ -0,0 +1,3 @@
## Docker to the rescue!
* * *
Use our [Docker containers](https://hub.docker.com/u/sitespeedio/) to get an environment with Firefox, Chrome, XVFB and sitespeed.io up in a couple of minutes.

View File

@ -0,0 +1,8 @@
## Why we love sitespeed.io
* * *
* Uses real browsers (Firefox and Chrome)
* Understand and speaks HTTP/2
* Plugin support (write your own plugins that handles the data)
* Runs on Linux
* Works great with Graphite and Grafana

View File

View File

View File

@ -0,0 +1,9 @@
## Thank you!
* * *
Sitespeed.io is built upon a couple Open Source tools, massive love to those projects:
* [Selenium](http://www.seleniumhq.org/)
* [TSProxy](https://github.com/WPO-Foundation/tsproxy)
* [PerfCascade](https://github.com/micmro/PerfCascade)
* [Skeleton](http://getskeleton.com)
* [Simple crawler](https://github.com/cgiffard/node-simplecrawler)

View File

@ -0,0 +1,3 @@
## Contribute
* * *
You can help us making sitespeed.io better! Check the [help section](https://github.com/sitespeedio/sitespeed.io/blob/master/HELP.md) of how you can help us. [These people](https://github.com/sitespeedio/sitespeed.io/blob/master/CONTRIBUTORS.md) has already helped us with pull requests or ideas (massive love!).

View File

@ -0,0 +1,4 @@
/* Thanks Nic Jansma https://github.com/nicjansma/usertiming.js */
/*! usertiming v0.1.6 */
!function(a){"use strict";"undefined"==typeof a&&(a={}),"undefined"==typeof a.performance&&(a.performance={}),a._perfRefForUserTimingPolyfill=a.performance,a.performance.userTimingJsNow=!1,a.performance.userTimingJsNowPrefixed=!1,a.performance.userTimingJsUserTiming=!1,a.performance.userTimingJsUserTimingPrefixed=!1,a.performance.userTimingJsPerformanceTimeline=!1,a.performance.userTimingJsPerformanceTimelinePrefixed=!1;var b,c,d=[],e=[],f=null;if("function"!=typeof a.performance.now){for(a.performance.userTimingJsNow=!0,e=["webkitNow","msNow","mozNow"],b=0;b<e.length;b++)if("function"==typeof a.performance[e[b]]){a.performance.now=a.performance[e[b]],a.performance.userTimingJsNowPrefixed=!0;break}var g=+new Date;a.performance.timing&&a.performance.timing.navigationStart&&(g=a.performance.timing.navigationStart),"function"!=typeof a.performance.now&&(a.performance.now=Date.now?function(){return Date.now()-g}:function(){return+new Date-g})}var h=function(){},i=function(){},j=[],k=!1,l=!1;if("function"!=typeof a.performance.getEntries||"function"!=typeof a.performance.mark){for("function"==typeof a.performance.getEntries&&"function"!=typeof a.performance.mark&&(l=!0),a.performance.userTimingJsPerformanceTimeline=!0,d=["webkit","moz"],e=["getEntries","getEntriesByName","getEntriesByType"],b=0;b<e.length;b++)for(c=0;c<d.length;c++)f=d[c]+e[b].substr(0,1).toUpperCase()+e[b].substr(1),"function"==typeof a.performance[f]&&(a.performance[e[b]]=a.performance[f],a.performance.userTimingJsPerformanceTimelinePrefixed=!0);h=function(a){j.push(a),"measure"===a.entryType&&(k=!0)};var m=function(){k&&(j.sort(function(a,b){return a.startTime-b.startTime}),k=!1)};if(i=function(a,c){for(b=0;b<j.length;)j[b].entryType===a&&("undefined"==typeof c||j[b].name===c)?j.splice(b,1):b++},"function"!=typeof a.performance.getEntries||l){var n=a.performance.getEntries;a.performance.getEntries=function(){m();var b=j.slice(0);return l&&n&&(Array.prototype.push.apply(b,n.call(a.performance)),b.sort(function(a,b){return a.startTime-b.startTime})),b}}if("function"!=typeof a.performance.getEntriesByType||l){var o=a.performance.getEntriesByType;a.performance.getEntriesByType=function(c){if("undefined"==typeof c||"mark"!==c&&"measure"!==c)return l&&o?o.call(a.performance,c):[];"measure"===c&&m();var d=[];for(b=0;b<j.length;b++)j[b].entryType===c&&d.push(j[b]);return d}}if("function"!=typeof a.performance.getEntriesByName||l){var p=a.performance.getEntriesByName;a.performance.getEntriesByName=function(c,d){if(d&&"mark"!==d&&"measure"!==d)return l&&p?p.call(a.performance,c,d):[];"undefined"!=typeof d&&"measure"===d&&m();var e=[];for(b=0;b<j.length;b++)("undefined"==typeof d||j[b].entryType===d)&&j[b].name===c&&e.push(j[b]);return l&&p&&(Array.prototype.push.apply(e,p.call(a.performance,c,d)),e.sort(function(a,b){return a.startTime-b.startTime})),e}}}if("function"!=typeof a.performance.mark){for(a.performance.userTimingJsUserTiming=!0,d=["webkit","moz","ms"],e=["mark","measure","clearMarks","clearMeasures"],b=0;b<e.length;b++)for(c=0;c<d.length;c++)f=d[c]+e[b].substr(0,1).toUpperCase()+e[b].substr(1),"function"==typeof a.performance[f]&&(a.performance[e[b]]=a.performance[f],a.performance.userTimingJsUserTimingPrefixed=!0);var q={};"function"!=typeof a.performance.mark&&(a.performance.mark=function(b){var c=a.performance.now();if("undefined"==typeof b)throw new SyntaxError("Mark name must be specified");if(a.performance.timing&&b in a.performance.timing)throw new SyntaxError("Mark name is not allowed");q[b]||(q[b]=[]),q[b].push(c),h({entryType:"mark",name:b,startTime:c,duration:0})}),"function"!=typeof a.performance.clearMarks&&(a.performance.clearMarks=function(a){a?q[a]=[]:q={},i("mark",a)}),"function"!=typeof a.performance.measure&&(a.performance.measure=function(b,c,d){var e=a.performance.now();if("undefined"==typeof b)throw new SyntaxError("Measure must be specified");if(!c)return void h({entryType:"measure",name:b,startTime:0,duration:e});var f=0;if(a.performance.timing&&c in a.performance.timing){if("navigationStart"!==c&&0===a.performance.timing[c])throw new Error(c+" has a timing of 0");f=a.performance.timing[c]-a.performance.timing.navigationStart}else{if(!(c in q))throw new Error(c+" mark not found");f=q[c][q[c].length-1]}var g=e;if(d)if(g=0,a.performance.timing&&d in a.performance.timing){if("navigationStart"!==d&&0===a.performance.timing[d])throw new Error(d+" has a timing of 0");g=a.performance.timing[d]-a.performance.timing.navigationStart}else{if(!(d in q))throw new Error(d+" mark not found");g=q[d][q[d].length-1]}var i=g-f;h({entryType:"measure",name:b,startTime:f,duration:i})}),"function"!=typeof a.performance.clearMeasures&&(a.performance.clearMeasures=function(a){i("measure",a)})}"undefined"!=typeof define&&define.amd?define([],function(){return a.performance}):"undefined"!=typeof module&&"undefined"!=typeof module.exports&&(module.exports=a.performance)}("undefined"!=typeof window?window:void 0);

View File

@ -0,0 +1,11 @@
---
#
# Jekyll layout that compresses HTML
# v1.1.0
# https://github.com/penibelst/jekyll-compress-html
# © 2014 Anatol Broder (http://penibelst.de/)
# MIT License
#
---
{% if site.compress_html.ignore.envs contains jekyll.environment %}{{ content }}{% else %}{% capture _content %}{{ content }}{% endcapture %}{% if site.compress_html.endings == "all" %}{% assign _endings = "html head body li dt dd p rt rp optgroup option colgroup caption thead tbody tfoot tr td th" | split: " " %}{% else %}{% assign _endings = site.compress_html.endings %}{% endif %}{% for _element in _endings %}{% capture _end %}</{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _end %}{% endfor %}{% if site.compress_html.comments.size == 2 %}{% assign _comment_befores = _content | split: site.compress_html.comments.first %}{% for _comment_before in _comment_befores %}{% assign _comment_content = _comment_before | split: site.compress_html.comments.last | first %}{% if _comment_content %}{% capture _comment %}{{ site.compress_html.comments.first }}{{ _comment_content }}{{ site.compress_html.comments.last }}{% endcapture %}{% assign _content = _content | remove: _comment %}{% endif %}{% endfor %}{% endif %}{% assign _pre_befores = _content | split: "<pre" %}{% assign _content = "" %}{% for _pre_before in _pre_befores %}{% assign _pres = _pre_before | split: "</pre>" %}{% case _pres.size %}{% when 2 %}{% capture _content %}{{ _content }}<pre{{ _pres.first }}</pre>{{ _pres.last | split: " " | join: " " }}{% endcapture %}{% when 1 %}{% capture _content %}{{ _content }}{{ _pres.last | split: " " | join: " " }}{% endcapture %}{% endcase %}{% endfor %}{% if site.compress_html.clippings == "all" %}{% assign _clippings = "html head title base link meta style body article section nav aside h1 h2 h3 h4 h5 h6 hgroup header footer address p hr blockquote ol ul li dl dt dd figure figcaption main div table caption colgroup col tbody thead tfoot tr td th" | split: " " %}{% else %}{% assign _clippings = site.compress_html.clippings %}{% endif %}{% for _element in _clippings %}{% assign _edges = " <e;<e; </e>;</e>;</e> ;</e>" | replace: "e", _element | split: ";" %}{% assign _content = _content | replace: _edges[0], _edges[1] | replace: _edges[2], _edges[3] | replace: _edges[4], _edges[5] %}{% endfor %}{{ _content }}{% endif %}

View File

@ -0,0 +1,63 @@
---
layout: compress
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ page.title }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="{{ page.description }}">
<meta name="keywords" content="{{ page.keywords }}">
<meta name="author" content="{{ page.author }}">
<link rel="canonical" href="{{site.baseurl}}{{ page.url | replace:'index.html','' }}"/>
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@sitespeedio">
<meta name="twitter:creator" content="@soulislove">
<meta name="twitter:url" content="{{site.baseurl}}{{ page.url | replace:'index.html','' }}">
<meta name="twitter:title" content="{{ page.title | truncate:70 }}">
{% if page.twitterdescription %}
<meta name="twitter:description" content="{{ page.twitterdescription | truncate:200 }}">
{% else %}
<meta name="twitter:description" content="{{ page.description | truncate:200 }}">
{% endif %}
{% if page.image %}
<meta name="twitter:image" content="{{ page.image }}">
{% endif %}
<meta property="og:image" content="{{site.baseurl}}/img/sitespeed.io-400x400.png">
<meta property="og:title" content="{{ page.title }}">
<meta property="og:url" content="{{site.baseurl}}{{ page.url | replace:'index.html','' }}">
<meta property="og:site_name" content="Sitespeed.io - How speedy is your website">
<meta property="og:description" content="{{ page.description | truncate:200 }}">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="{{site.baseurl}}/img/ico/sitespeed.io-144.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="{{site.baseurl}}/img/ico/sitespeed.io-114.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="{{site.baseurl}}/img/ico/sitespeed.io-72.png">
<link rel="apple-touch-icon-precomposed" href="{{site.baseurl}}/img/ico/sitespeed.io-57.png">
<link rel="shortcut icon" href="{{site.baseurl}}/img/ico/sitespeed.io.ico">
<style>{% include css/default.css %}</style>
<script type="text/javascript">{% include userTimings.js %}</script>
{% include analythics.js %}
</head>
<body>
{% include header.html %}
<div class="grid">
<div class="col-1-1">
{{ content }}
</div>
</div>
<div class="blue">
<div class="grid">
<div class="col-1-1">
{% include footer.html %}
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,14 @@
---
layout: 404
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ page.title }}</title>
<style>{% include css/404.css %}</style>
</head>
<body>
{{ content }}
</body>
</html>

View File

@ -0,0 +1,107 @@
---
layout: compress
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ page.title }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="{{ page.description }}">
<meta name="keywords" content="{{ page.keywords }}">
<meta name="author" content="{{ page.author }}">
<link rel="canonical" href="https://www.sitespeed.io{{ page.url | replace:'index.html','' }}"/>
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@sitespeedio">
<meta name="twitter:creator" content="@soulislove">
<meta name="twitter:url" content="https://www.sitespeed.io{{ page.url | replace:'index.html','' }}">
<meta name="twitter:title" content="{{ page.title | truncate:70 }}">
{% if page.twitterdescription %}
<meta name="twitter:description" content="{{ page.twitterdescription | truncate:200 }}">
{% else %}
<meta name="twitter:description" content="{{ page.description | truncate:200 }}">
{% endif %}
{% if page.image %}
<meta name="twitter:image" content="{{ page.image }}">
{% endif %}
<meta property="og:image" content="{{site.baseurl}}/img/sitespeed.io-400x400.png">
<meta property="og:title" content="{{ page.title }}">
<meta property="og:url" content="https://www.sitespeed.io{{ page.url | replace:'index.html','' }}">
<meta property="og:site_name" content="Sitespeed.io - How speedy is your website">
<meta property="og:description" content="{{ page.description | truncate:200 }}">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="{{site.baseurl}}/img/ico/sitespeed.io-144.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="{{site.baseurl}}/img/ico/sitespeed.io-114.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="{{site.baseurl}}/img/ico/sitespeed.io-72.png">
<link rel="apple-touch-icon-precomposed" href="{{site.baseurl}}/img/ico/sitespeed.io-57.png">
<link rel="shortcut icon" href="{{site.baseurl}}/img/ico/sitespeed.io.ico">
<style>{% include css/default.css %}</style>
<script type="text/javascript">{% include userTimings.js %}</script>
{% include analythics.js %}
</head>
<body>
{% include header.html %}
<div class="blue">
<div class="grid">
<div class="col-1-1">
{{ content }}
</div>
</div>
</div>
<div class="grid">
<div class="col-1-2">
{% capture box1 %}{% include index/box1.md %}{% endcapture %}
{{ box1 | markdownify }}
</div>
<div class="col-1-2">
{% capture box2 %}{% include index/box2.md %}{% endcapture %}
{{ box2 | markdownify }}
</div>
</div>
<div class="grid">
<div class="col-1-2">
{% capture box3 %}{% include index/box3.md %}{% endcapture %}
{{ box3 | markdownify }}
</div>
<div class="col-1-2">
{% capture box4 %}{% include index/box4.md %}{% endcapture %}
{{ box4 | markdownify }}
</div>
</div>
<div class="grid">
<div class="col-1-2">
{% capture box5 %}{% include index/box5.md %}{% endcapture %}
{{ box5 | markdownify }}
</div>
<div class="col-1-2">
{% capture box6 %}{% include index/box6.md %}{% endcapture %}
{{ box6 | markdownify }}
</div>
</div>
<div class="grid">
<div class="col-1-2">
{% capture box7 %}{% include index/box7.md %}{% endcapture %}
{{ box7 | markdownify }}
</div>
<div class="col-1-2">
{% capture box8 %}{% include index/box8.md %}{% endcapture %}
{{ box8 | markdownify }}
</div>
</div>
<div class="blue">
<div class="grid">
<div class="col-1-1">
{% include footer.html %}
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,15 @@
---
layout: default
title: Welcome sitespeed.io 4.0 beta
description: Finally sitespeed.io 4.0 is here!
author: Peter Hedenskog
authorimage: /img/aboutus/peter.jpg
intro: We have released the first beta version of 4.0 of sitespeed.io. Finally!
keywords: sitespeed.io, sitespeed, site, speed, webperf, performance, web, wpo
nav: blog
---
# Sitespeed.io 4.0 beta
Yes finally we have released the first beta of 4.0. We plan to do at least one beta before final.
We have a have some great changes in 4.0 but let pause those for the 4.0 final post and let me go through what missing this release and what's coming in 4.0 final.

30
docs/aboutus/index.md Normal file
View File

@ -0,0 +1,30 @@
---
layout: default
title: About Us
description: The team behind sitespeed.io
author: Peter Hedenskog
keywords: sitespeed.io, about, peter hedenskog, tobias lidskog, jonathan Lee
nav: aboutus
---
# About Us
We are a three member team that works on sitespeed.io in our free time. New contributors and team members are very welcomed!
## Jonathan Lee
<a href="https://twitter.com/beenanner"><img src="{{site.baseurl}}/img/aboutus/jonathan.jpg" class="photo pull-left" width="200" height="200"></a> I discovered sitespeed.io version 3 in 2015 while exploring the latest trending tools in web performance. I was intrigued by this tool and decided to learn more. Wanting to contribute back to the open source community that has giving me so much over the last decade, I reached out to Peter and Tobias to assist with the development of version 4.0.
As a performance engineer at [CBSi](http://www.cbsinteractive.com/) I am able to offer real-world feedback to the team to make improvements that will benefit others. I love talking about web performance so feel free connect or reach out to me on [LinkedIn](https://www.linkedin.com/in/jonathanlee20) or [Twitter](https://twitter.com/beenanner).
## Tobias Lidskog
<a href="https://twitter.com/tobiaslidskog"><img src="{{site.baseurl}}/img/aboutus/tobias.jpg" class="photo pull-left" width="200" height="200"></a> Having been supporter of sitespeed.io from the sidelines for some time, I joined Peter as we started working on version 3.0. I've been working professionally with the web for about 15 years, and open source tools have been an indispensable help all along. Now it's nice to be able to give something back.
In my work at [iZettle](https://www.izettle.com/) I spend most of my time enabling the dev teams to shine. Working on sitespeed.io is a great complement, letting me get my hands dirty with range of tools and techniques; from [controlling browsers with WebDriver](http://www.browsertime.net) to [learning how to use Docker](https://github.com/sitespeedio/sitespeed.io-docker).
## Peter Hedenskog
<a href="https://twitter.com/soulislove"><img src="{{site.baseurl}}/img/aboutus/peter.jpg" class="photo pull-left" width="200" height="200"></a> I created sitespeed.io late 2012. It's been a lot of work and incredibly [fun](http://www.peterhedenskog.com/blog/2015/02/building-a-new-sitespeed.io/)! I'm a web performance geek, love the web and think Open Source is the way forward. I work in the performance team at [Wikimedia](https://www.wikimedia.org/).
In early 2015 I was awarded for building sitespeed.io by [The Swedish Internet Infrastructure Foundation](https://www.iis.se/english/about-se/) making it possible for me to work full time on the project for three months.
I'm one of the organizers of the [Stockholm Web Performance meetup group](http://www.meetup.com/Stockholm-Web-Performance-Group/). We are 600+ members and are always looking for new speakers. If you are in Stockholm and have something to share, ping me on <a href="https://twitter.com/soulislove">Twitter</a> and see if we can make it happen.

24
docs/blog/index.md Normal file
View File

@ -0,0 +1,24 @@
---
layout: default
title: The sitespeed.io blog
description: The team behind sitespeed.io
author: Peter Hedenskog
keywords: sitespeed.io, peter hedenskog, tobias lidskog
nav: blog
---
# Blog
{% for post in site.posts %}
<img src="{{site.baseurl}}{{ post.authorimage }}" class="photo pull-left" width="100" height="100">
## [{{ post.title }}]({{site.baseurl}}{{ post.url }})
**{{ post.date | date: '%Y' }}-{{ post.date | date: '%m' }}-{{ post.date | date: '%d' }}** -
{{ post.intro }}
[>> Read more]({{site.baseurl}}{{ post.url }})
* * *
{% endfor %}

View File

@ -0,0 +1,17 @@
---
layout: default
title: Browsertine Documentation
description:
keywords: browsertime, documentation, web performance
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription:
---
[Documentation]({{site.baseurl}}/documentation/browsertime/) /
# Browsertime - Documentation
{:.no_toc}
* Lets place the TOC here
{:toc}

View File

@ -0,0 +1,56 @@
---
layout: default
title: Browsertime
description:
keywords: tools, documentation, web performance
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription:
---
# Browsertime
<img src="{{site.baseurl}}/img/logos/browsertime.png" class="pull-right img-big" alt="Browsertime logo" width="200" height="175">
Access the Web Performance Timeline, from your browser, in your terminal!
Browsertime allows you to:
* Query timing data directly from the browser, to access [Navigation Timing](http://kaaes.github.io/timing/info.html), [User Timing](http://www.html5rocks.com/en/tutorials/webperformance/usertiming/),
[Resource Timing](http://www.w3.org/TR/resource-timing/), first paint and [RUM Speed Index](https://github.com/WPO-Foundation/RUM-SpeedIndex).
* Generate [HAR](http://www.softwareishard.com/blog/har-12-spec/) files
* Run custom Javascript scripts in the browser and get statistics for each run.
## A simple example
~~~
$ bin/browsertime.js https://www.sitespeed.io
~~~
Load https://www.sitespeed.io in Chrome three times. Results are stored in a json file (browsertime.json) with the timing data, and a har file (browsertime.har) in browsertime-results/www.sitespeed.io/$date/
## I want more examples
Checkout the [examples](https://github.com/sitespeedio/browsertime/tree/master/docs/examples).
## Browsers
Browsertime supports Firefox and Chrome on desktop. On Android we support Chrome. Yep that's it for now.
But we want to support Opera (on Android) https://github.com/sitespeedio/browsertime/issues/150 and when Safari 10 is availible, we will add it too. And when(?!) it iOS Safari supports WebDriver we will add that too.
## How does it work
Browsertime uses Selenium NodeJS to drive the browser. It starts the browser, load a URL, executes configurable Javacsripts to collect metrics, collect a HAR file.
To get the HAR from Firefox we use the [HAR Export Trigger](https://github.com/firebug/har-export-trigger) and Chrome we parse the timeline log and generates the HAR file.
Oh and you can run your own Selenium script before (<code>--preScript</code>) and after (<code>--postScript</code>) a URL is accessed so you can login/logout or do whatever you want.
## The rewrite to 1.0
The master is to a large degree a re-write of the internal implementation, the cli interface, and the node API. It's
based on learnings from the previous releases of Browsertime, and their use in Sitespeed.io. It's still lacking some features
from the 0.x releases, and the API is not final. However it should be a better foundation for future development, using
more modern Javascript features and a much more extensive test suite.
With 1.0 we dropped BrowsermobProxy so you don't need Java :smile: to run anymore and each run will be 1000% faster. Also we now support HTTP/2 and pre and post selenium scripts, if you want to do things before the URL is tested.
If you would would like to get started there are a few examples that can be found in the [docs folder](https://github.com/sitespeedio/browsertime/tree/master/docs/examples). If you run into any issues getting started using Browsertime visit our [issues page](https://github.com/sitespeedio/browsertime/issues) for some common issues/solutions. If you still cannot resolve the problem and feel the issue is within browsertime feel free to open an issue.

View File

@ -0,0 +1,204 @@
---
layout: default
title: Coach
description:
keywords: coach, documentation, web performance
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription:
---
[Documentation]({{site.baseurl}}/documentation/coach/) / Developers guide
# The Coach - Developers guide
{:.no_toc}
* Lets place the TOC here
{:toc}
## Prerequisites
You need install [Node.js](https://nodejs.org/en/), [npm](https://nodejs.org/en/), [Firefox](https://www.mozilla.org/en-US/firefox/new/) and [Chrome](https://www.google.com/chrome/browser/desktop/).
When you got them installed you can clone the project (or rather first fork it and clone your fork).
```
$ git clone git@github.com:sitespeedio/coach.git
```
Inside your coach folder install the dependencies and run the tests to check that everything works:
```
$ cd coach
$ npm install
$ npm test
```
If the test works you are ready start!
## Advice
The coach helps you with web performance and gives you advice about things you can do better. The advice needs to follow the following structure:
```javascript
return {
id: 'uniqueid', // a uniqie id
title: 'The title of the advice',
description: 'More information of the advice',
advice: 'Information of what the user should do to fix the problem',
score: 100, // a number between 0-100, 100 means the page don't need any advice
weight: 5, // a number between 0-10, how important is this advice in this category? 10 means super important
offending: [], // an array of assets that made the score less than perfect
tags: ['performance','html']
};
```
Does it look familiar? Yep it is almost the same structure as an YSlow rule :)
### DOM vs HAR advice
The coach analyze a page in two steps: First it executes Javascript in the browser to do checks that are a perfect fit for Javascript: examine the rendering path, check if images are scaled in the browser and more.
Then the coach take the HAR file generated from the page and analyze that too. The HAR is good if you want the number of responses, response size and check cache headers.
In the last step the coach merges the advice into one advice list and creates an overall score.
Isn't that cool? We got one more thing that we [intend to implement](https://github.com/sitespeedio/coach/issues/13)): the combination of the two: A HAR advice that takes input from a DOM. This is cool because the coach will then have the power to know it all.
#### DOM advice
Each DOM advice needs to be a [IIFE](https://en.wikipedia.org/wiki/Immediately-invoked_function_expression) and return an object that holds the data.
A simple example is the cssPrint advice that looks for a print stylesheet.
```javascript
(function(util) {
'use strict';
var offending = [];
var links = document.getElementsByTagName('link');
for (var i = 0, len = links.length; i < len; i += 1) {
if (links[i].media === 'print') {
offending.push(util.getAbsoluteURL(links[i].href));
}
}
var score = offending.length * 10;
return {
id: 'cssPrint',
title: 'Do not load print stylesheets, use @media type print instead',
description: 'Loading a specific stylesheet for printing slows down the page, even though it is not used',
advice: offending.length > 0 ? 'The page has ' + offending.length + ' print stylesheets. You should include that stylesheet using @media type print instead.':'',
score: Math.max(0, 100 - score),
weight: 1,
offending: offending,
tags: ['performance', 'css']
};
})(util);
```
#### HAR advice
We use [PageXray](https://github.com/sitespeedio/pagexray) to convert the HAR file into a Page object that are easier to work with.
Each HAR advice needs to implement a processPage function. The function will be called once for each page.
Lets look at a simple advice that checks if the total page size is too large.
```javascript
'use strict';
let util = require('../util');
module.exports = {
id: 'pageSize',
title: 'Total page size shouldn\'t be too big',
description: 'Avoid having pages that have transfer size over the wire of more than 2 MB (desktop) and 1 MB (mobile) because that is really big and will hurt performance. ',
weight: 3,
tags: ['performance', 'mobile'],
processPage: function(page, domAdvice, options) {
// in options we have the input parameters
// so we can do specific advice for devices like
let sizeLimit = options.mobile ? 1000000 : 2000000;
if (page.transferSize > sizeLimit) {
return {
score: 0,
offending: [],
advice: 'The page total transfer size is ' + util.formatBytes(page.transferSize) + ', which is more than the coach limit of ' + util.formatBytes(sizeLimit) + '. That is really big and you should check what you can do to make it smaller.'
};
}
// and the domAdvice is the data we got from running the DOM advice
// we can get things like what assets are loaded inside of HEAD
// knowing which Javascripts that are loaded synchronous
// if (domAdvice.coachAdvice.results.info.head.jssync.length > 0)
return {
score: 100,
offending: [],
advice: ''
};
}
};
```
What's extra cool is that a HAR advice can both act on input (specific advice for device or browser) and on the result from the DOM advice running in the browser (=you can let the HAR advice know which assets are loaded inside of head etc).
#### The best of two worlds
As an extra feature, the HAR advice override the DOM advice if the advice has the same id. This means you can easily combine data from the two and still output one advice.
There's no advice that use that functionality today but be sure it will soon be.
It also means we can use information from the resource timing API v2 (where we can get response size) making the DOM advice even more powerful, but when you combine the HAR & DOM advice we can get all the values from the HAR (or some if we want that).
## Testing HTTP/2 vs HTTP/1
Both DOM and HAR advice have help methods that makes it easy to give different advice depending on the protocol.
### DOM
```javascript
if (util.isHTTP2()) {
// special handling for H2 connections
}
```
### HAR
```javascript
if (util.isHTTP2(page)) {
// special handling for H2 connections
}
```
## Test in your browser
You can and should test your advice in your browser. It's easy. Just copy/paste your advice into the browser console. If you use the [utility methods](https://github.com/sitespeedio/coach/blob/master/lib/dom/util.js) you need to copy/paste that too inside your console before you test your advice.
## Add a test case
When you create a new advice you also need to create unit tests. We run the tests in both Firefox & Chrome.
We create a new unique HTML page for each rule (or two if you want to test different behavior). If you only have one page, name it the same as the advice + '.html' and it will be picked up.
A simple test run for the print CSS advice looks like this:
```javascript
it('We should find out if we load an print CSS', function() {
return runner.run('cssPrint.js')
.then((result) => {
assert.strictEqual(result.offending.length, 1);
});
});
```
Right now all these tests run in https://github.com/sitespeedio/coach/blob/master/test/dom/performance/indexTest.js
Each test case runs against a specific HTML page located in [test/http-server](test/http-server) Create a suitable HTML page with the structure you want to test. Create the test case in [test/dom](test/dom) or [test/har](test/har) and run it with <code>npm test</code>
## Test your changes against a web page
The coach uses Browsertime as runner for browsers. When you done a change, make sure to build a new version of the combined Javascript and then test against a url.
```bash
npm run combine
bin/index.js https://www.sitespeed.io firefox
```
# Add a new category
When you browse the code you will see that the coach knows more things than performance.
We have accessibility best practice, performance, and info today. Do the coach need to know something else? Let us know and we can create that category (it's as easy as create a new folder) and we can start add new advice there.

View File

@ -0,0 +1,189 @@
---
layout: default
title: Coach
description:
keywords: coach, documentation, web performance
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription:
---
[Documentation]({{site.baseurl}}/documentation/coach/) / How to
# The Coach - How to use the coach
{:.no_toc}
* Lets place the TOC here
{:toc}
You can use the coach in a couple of different ways.
### Standalone
You need Node.js 4.3.0 or later to run. And you need Firefox and/or Chrome installed.
If you want to use Firefox (Firefox is default):
```bash
webcoach https://www.sitespeed.io
```
Try it with Chrome:
```bash
npm install webcoach -g
webcoach https://www.sitespeed.io --browser chrome
```
If you also want to show the offending assets/details and the description of the advice:
```bash
webcoach https://www.sitespeed.io --details --description
```
By default, the coach only tells you about advice where you don't get the score 100. You can change that. If you want to see all advice, you can do that too:
```bash
webcoach https://www.sitespeed.io --limit 101
```
If you want to test as a mobile device, that's possible too, by faking the user-agent.
```bash
webcoach https://www.sitespeed.io --mobile -b chrome
```
> ... but hey, I want to see the full JSON?
Yes, you can do that!
```bash
webcoach https://www.sitespeed.io -f json
```
This will get you the full JSON, the same as if you integrate the coach into your tool.
### sitespeed.io 4.0
The coach is a part of the forthcoming [sitespeed.io 4.0](https://www.sitespeed.io). It will be released this summer, hallelujah!
### Bookmarklet
We also produce a bookmarklet. The bookmarklet only uses advice that you can run inside the browser (it doesn't have HAR file to analyze even though maybe possible in the future with the Resource Timing API).
The bookmarklet is really rough right now and logs the info to the browser console. Help us make a cool front-end :)
You can generate the bookmarklet by running
```bash
grunt bookmarklet
```
and then you will find it in the dist folder.
### Include in your own tool
The coach uses Browsertime to start the browser, execute the Javascript and fetch the HAR file. You can use that functionality too inside your tool or you can use the raw scripts if you have your own browser implementation.
#### Use built in browser support
In the simplest version you use the default configuration (default DOM and HAR advice and using Firefox):
```javascript
const api = require('webcoach');
const result = api.run('https://www.sitespeed.io');
```
The full API method:
```javascript
// get the API
const api = require('webcoach');
const result = api.run(url, domScript, harScript, options);
```
#### Use the scripts
Say that your tool run on Windows, you start the browsers yourself and you generate your own HAR file. Create your own wrapper to get the coach to help you.
First you need the Javascript advice, you can get the raw script either by generating it yourself or through the API.
Generate the script
```bash
grunt combine
```
and it will be in the dist folder.
Or you just get it from the API:
```javascript
// get the API
const api = require('webcoach');
// get the DOM scripts, it's a promise
const domScriptPromise = api.getDomAdvice();
```
Take the <em>domScript</em> and run it in your browser and take care of the result.
To test the HAR you need to generate the HAR yourself and then run it against the advice.
```javascript
const api = require('webcoach');
// You read your HAR file from disk or however you get hold of it
const harJson = //
// if your har contains multiple pages (multiple runs etc) you can use the API
// to get the page that you want
const firstPageHar = api.pickAPage(harJson, 0);
// the result is a promise
const myHarAdviceResultPromise = api.runHarAdvice(firstPageHar, api.getHarAdvice());
```
When you got the result from both the DOM and the HAR you need to merge the result to get the full coach result:
```javascript
// Say that you got the result from the browser in domAdviceResult
// and the HAR result in harAdviceResult
const coachResult = api.merge(domAdviceResult, harAdviceResult);
```
Now you have the full result (as JSON) as a coachResult.
## What do the coach do
The coach will give you advice on how to do your page better. You will also get a score between 0-100. If you get 100 the page is great, if you get 0 you can do much better!
## How does it all work?
The coach tests your site in two steps:
* Executes Javascript in your browser and check for performance, accessibility, best practice and collect general info about your page.
* Analyze the [HAR file](http://www.softwareishard.com/blog/har-12-spec/) for your page together with relevant info from the DOM process.
You can run the different steps standalone but for the best result run them together.
![What the coach do](https://github.com/sitespeedio/coach/blob/master/img/coach-explained.png)
## Bonus
The coach knows more than just performance. She also knows about accessibility and web best practice.
### Accessibility
Make sure your site is accessible and useable for every one. You can read more about making the web accessible [here](https://www.marcozehe.de/2015/12/14/the-web-accessibility-basics/).
### Best practice
You want your page to follow best practices, right? Making sure your page is set up for search engines, have good URL structure and so on.
### General information
The world is complex. Some things are great to know but hard for the coach to give advice about.
The coach will then just tell you how the page is built and you can draw your own conclusions if something should be changed.
### Timings
The coach has a clock and knows how to use it! You will get timing metrics and know if you are doing better or worse than the last run.
# Developers guide
Checkout the [developers guide](../developers/) to get a better feeling how the coach works.
# Browser support
The coach is automatically tested in latest Chrome and Firefox. To get best results you need Chrome or Firefox 48 (or later) to be able to know if the server is using HTTP/2.
We hope that the coach work in other browsers but we cannot guarantee it right now.

View File

@ -0,0 +1,19 @@
---
layout: default
title: Coach
description:
keywords: tools, documentation, web performance
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription:
---
# The coach - Clear Eyes. Full Hearts. Cant Lose!
<img src="{{site.baseurl}}/img/logos/coach.png" class="pull-right img-big" alt="I'm the coach" width="188" height="219">
The coach helps you find performance problems on your web page. Think of the coach as a modern version of [YSlow](http://yslow.org/). The coach will give advice of how your page can be faster. You can run the coach standalone, include it in your own tool or get the data when you run sitespeed.io.
* [Introduction](introduction/)
* [How to use the coach](how-to/)
* [Developers](developers/)

View File

@ -0,0 +1,40 @@
---
layout: default
title: Coach
description:
keywords: coach, documentation, web performance
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription:
---
[Documentation]({{site.baseurl}}/documentation/coach/) / Introduction
# The Coach - Introduction
{:.no_toc}
* Lets place the TOC here
{:toc}
## Do my page need coaching?
You know, it's hard to get everything right! The world is complex: HTTP/1 vs HTTP/2. Some of the previous performance best practices are now worst practices. The coach will detect that the page is accessed using HTTP/2, and adjust its advice accordingly.
## Why we love the coach
Ten reasons why we love the coach:
- The coach gives you advice on how to make your page faster. The coach aims to NEVER give you bad advice. Follow the advice and you will WIN!
- HTTP/1 or HTTP/2? That's no problem, the coach adjust the advice accordingly.
- The coach uses real browsers to see your page exactly like your users do.
- Every advice has one or more unit-tests to make sure it's easy to change advice in the future.
- The coach knows about more than just performance: Accessibility and web best practice are other things that the coach can help you with.
- You can integrate the coach with your own web performance tool. It's easy: your tool only need to be able to run JavaScript in the browser and produce a HAR file. Or you can use the built-in functionality of the coach to run the browser.
- The coach is open-source. The advice is public, you can check it and change it yourself. Help us make the coach even better!
- The coach can combine knowledge from the DOM with HAR to give you super powerful advice.
- The CLI output is pretty nice. You can configure how much you want to see. Use it as fast way to check the performance of your page.
- The coach is a part of sitespeed.io 4.0 and it will be awesome!
## Work in progress!
We know you want the coach to help you but right now YOU need to help the coach! The coach is new and need more advice. Send a PR with a new advice, so the coach gets more knowledge! Check out the [issues](https://github.com/sitespeedio/coach/issues), try the project and give us feedback! In a couple of months we will release 1.0.

View File

@ -0,0 +1,18 @@
---
layout: default
title: Tools
description: Here's the documentation of how to use sitespeed.io.
keywords: tools, documentation, web performance
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Documentation for the sitespeed.io.
---
# Documentation
At the moment we have four different tools:
* [sitespeed.io]({{site.baseurl}}/documentation/sitespeed.io/)
* [Coach]({{site.baseurl}}/documentation/coach/)
* [Browsertime]({{site.baseurl}}/documentation/browsertime/)
* [PageXray]({{site.baseurl}}/documentation/pagexray/)

View File

@ -0,0 +1,141 @@
---
layout: default
title: PageXray
description:
keywords: tools, documentation, web performance
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription:
---
# PageXray
<img src="{{site.baseurl}}/img/logos/pagexray.png" class="pull-right img-big" alt="PageXray logo" width="365" height="200">
We love HAR file but it's hard to actually see what the page includes only looking at the file. The PageXray converts a HAR file to a JSON format that is easier to read. We use the format internally in the coach and sitespeed.io.
## What do we collect?
* The size and the number of requests per content type
* The size and requests per domain
* The number of requests per response code
* The base domain and the httpVersion used for the base asset (the main HTML document)
* All assets (responses) with the following data: type, url, size, expires (a normalized expires converting max-age/expires to just expires in seconds), status (response code), timeSinceLastModified (using the last modified field in the repsonse header and normalizing to seconds), httpVersion and all request and response headers.
## Install
```bash
npm install pagexray -g
```
## Run
```bash
pagexray /path/to/my.har
```
Or if you want to prettify the HAR
```bash
pagexray --pretty /path/to/my.har
```
And if you want to get info per request/response:
```bash
pagexray -includeAssets /path/to/my.har
```
If you want to use it in node, use it like this:
```node
let pagexray = require('pagexray');
let har = // your HAR
let pages = pagexray.convert(har);
```
## Output
All sizes are in bytes. Expires and timeSinceLastModified are in seconds.
```json
[
{
"url": "https://run.sitespeed.io/",
"finalUrl": "https://run.sitespeed.io/",
"baseDomain": "run.sitespeed.io",
"documentRedirects": -1,
"redirectChain": [],
"transferSize": 102069,
"contentSize": 102069,
"headerSize": 6480,
"requests": 11,
"httpType": "h2",
"httpVersion": "HTTP/2.0",
"contentTypes": {
"html": {
"transferSize": 12311,
"contentSize": 12311,
"headerSize": 582,
"requests": 1
},
"javascript": {
"transferSize": 26285,
"contentSize": 26285,
"headerSize": 347,
"requests": 1
},
"image": {
"transferSize": 11855,
"contentSize": 11855,
"headerSize": 984,
"requests": 2
},
"svg": {
"transferSize": 45100,
"contentSize": 45100,
"headerSize": 3923,
"requests": 6
},
"favicon": {
"transferSize": 6518,
"contentSize": 6518,
"headerSize": 644,
"requests": 1
}
},
"assets": [],
"responseCodes": {
"200": 11
},
"domains": {
"run.sitespeed.io": {
"requests": 9,
"transferSize": 75749,
"contentSize": 75749,
"headerSize": 5788
},
"www.google-analytics.com": {
"requests": 2,
"transferSize": 26320,
"contentSize": 26320,
"headerSize": 692
}
},
"expireStats": {
"min": "0",
"p10": "0",
"median": "31536000",
"p90": "31536000",
"p99": "31536000",
"max": "31536000"
},
"lastModifiedStats": {
"min": "15293097",
"p10": "18613493",
"median": "18613493",
"p90": "566681353",
"p99": "566681353",
"max": "566681353"
}
}
]
```

View File

@ -0,0 +1,75 @@
---
layout: default
title: Browsers - Documentation - sitespeed.io
description: How to get browser timings using sitespeed.io for Firefox and Chrome.
keywords: browsers, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Browser timings for sitespeed.io.
---
[Documentation]({{site.baseurl}}/documentation/sitespeed.io/) / Browsers
# Browsers
{:.no_toc}
* Lets place the TOC here
{:toc}
You can fetch timings and execute your own Javascript. The following browsers are supported: Firefox, Chrome and Chrome on Android.
## Firefox
You will need Firefox 48+. We use the new [Geckodriver](https://github.com/mozilla/geckodriver) and it works only version 48 or later.
## Chrome
Chrome should work out of the box.
## Change connectivity
You can throttle the connection when you are fetching metrics using the browser. Choose between:
* 3g - 1600/768 300 RTT
* 3gfast - 1600/768 150 RTT
* 3gslow - 780/330 200 RTT
* 2g - 35/328 1300 RTT
* cable - 5000/1000 280 RTT
* native - your current connection
We use [TSProxy](https://github.com/WPO-Foundation/tsproxy) by default so you need Python 2.7 to be able tho throttle the connection.
~~~bash
$ sitespeed.io https://www.sitespeed.io -c cable
~~~
We plan to implement support for other connectivity engines in the future. You can try out our tc implementation by setting <code>--connectivity.engine tc</code>
## Choose when to end your test
By default the browser will collect data until [window.performance.timing.loadEventEnd happens + aprox 2 seconds more](https://github.com/sitespeedio/browsertime/blob/d68261e554470f7b9df28797502f5edac3ace2e3/lib/core/seleniumRunner.js#L15). That is perfectly fine for most sites, but if you do Ajax loading and you mark them with user timings, you probably want to include them in your test. Do that by changing the script that will end the test (waitScript). When the scripts returns true the browser will close or if the timeout time (default 60 seconds) will be reached.
In this we wait 10 seconds until loadEventEnd happens but you can also choose to trigger it at a specific event.
~~~bash
$ sitespeed.io https://www.sitespeed.io --browsertime.pageCompleteCheck 'return (function() {try { return (Date.now() - window.performance.timing.loadEventEnd) > 10000;} catch(e) {} return true;})()'
~~~
## Custom metrics
You can collect your own metrics in the browser by supplying Javascript file(s). Each file need to return a metric/value and it will be picked up and returned in the JSON. If you return a number, statistics will automatically be generated for the value (like median/percentiles etc).
Say we have a folder called scripts and in there we have one file called scripts.js that checks how many javascript that is loaded. The script looks like this:
~~~bash
return document.getElementsByTagName("script").length;
~~~
Then to pick up the script, run like this:
~~~bash
sitespeed.io https://www.sitespeed.io --browsertime.script scripts.js -b firefox
~~~
## More browser goodness
Everything you can do in Browsertime, you can also do in sitespeed.io. Add browsertime to the CLI parameter and it will be passed on to Browsertime.
You can check what Browsertime can do [here](https://github.com/sitespeedio/browsertime/blob/master/lib/support/cli.js).
Say for example that you wanna pass on extra Chrome arguments to Chrome. In standalone Browsertime you do that with <i>--chrome.args</i>. If you wanna do that in sitespeed.io you add browsertime to the param: <i>--browsertime.chrome.args</i>. Yes we know, it is sweat :)

View File

@ -0,0 +1,180 @@
---
layout: default
title: Browsers - Documentation - sitespeed.io
description: How to configure sitespeed.io
keywords: configuration, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Configuration for sitespeed.io.
---
[Documentation]({{site.baseurl}}/documentation/sitespeed.io/) / Configuration
# Configuration
{:.no_toc}
* Lets place the TOC here
{:toc}
# Configuration
Sitespeed.io is highly configurable, let's check it out!
## The options
You have the following options running sitespeed.io (we will add more as we are coming to the stable 4.0 release):
~~~help
bin/sitespeed.js [options] <url>/<file>
Browser
--browsertime.browser, -b, --browser Choose which Browser to use when you test. [choices: "chrome", "firefox"] [default: "chrome"]
--browsertime.iterations, -n How many times you want to test each page [default: 3]
--browsertime.delay Delay between runs, in milliseconds [number] [default: 0]
--browsertime.connectivity.profile, -c, --connectivity The connectivity profile. Default connectivity engine is tsproxy
[choices: "3g", "3gfast", "3gslow", "2g", "cable", "native", "custom"] [default: "native"]
--browsertime.connectivity.config This option requires --connectivity.profile be set to "custom". Takes a JSON object with the keys downstreamKbps,
upstreamKbps and latency. "{\"downstreamKbps\":6000, \"upstreamKbps\": 6000, \"latency\": 200}"
--browsertime.connectivity.tsproxy.port The port used for ts proxy [default: 1080]
--browsertime.connectivity.engine The engine for connectivity. Tsproxy needs Python 2.7. TC needs tc, modprobe and ip installed to work. Running tc
inside Docker needs modprobe to run outside the container. [choices: "tc", "tsproxy"] [default: "tsproxy"]
--browsertime.pageCompleteCheck Javascript snippet is repeatedly queried to see if page has completed loading (indicated by the script returning true)
--browsertime.script, --script Add custom Javascript to run on page (that returns a number). Note that --script can be passed multiple times if you
want to collect multiple metrics. The metrics will automatically be pushed to the summary/detailed summary and each
individual page + sent to Graphite/InfluxDB.
--browsertime.selenium.url Configure the path to the Selenium server when fetching timings using browsers. If not configured the supplied
NodeJS/Selenium version is used.
--browsertime.viewPort The view port, the page viewport size WidthxHeight like 400x300 [default: "1366x708"]
--browsertime.userAgent The full User Agent string, defaults to the user agent used by the browsertime.browser option.
--browsertime.preScript, --preScript Task(s) to run before you test your URL (use it for login etc). Note that --preScript can be passed multiple times.
--browsertime.postScript, --postScript Path to JS file for any postTasks that need to be executed.
Crawler
--crawler.depth, -d How deep to crawl (1=only one page, 2=include links from first page, etc.)
--crawler.maxPages, -m The max number of pages to test. Default is no limit.
Graphite
--graphite.host The Graphite host used to store captured metrics.
--graphite.port The Graphite port used to store captured metrics. [default: 2003]
--graphite.namespace The namespace key added to all captured metrics. [default: "sitespeed_io.default"]
--graphite.includeQueryParams Whether to include query paramaters from the URL in the Graphite keys or not [boolean] [default: false]
Plugins
--plugins.list List all configured plugins in the log. [boolean] [default: false]
--plugins.disable Disable a plugin. Use it to disable generating html or screenshots. [array]
--plugins.load Extra plugins as an installed npm module that you want to run [array]
Metrics
--metrics.list List all possible metrics in the data folder (metrics.txt). [boolean] [default: false]
--metrics.filterList List all configured filters for metrics in the data folder (configuredMetrics.txt) [boolean] [default: false]
--metrics.filter Add/change/remove filters for metrics. If you want to send all metrics, use: *+ . If you want to remove all current metrics and send only the coach
score: *- coach.summary.score.* [array]
WebPageTest
--webpagetest.host The domain of your WebPageTest instance. [default: "https://www.webpagetest.org"]
--webpagetest.key The API key for you WebPageTest instance.
--webpagetest.location The location for the test [default: "Dulles:Chrome"]
--webpagetest.connectivity The connectivity for the test. [default: "Cable"]
--webpagetest.runs The number of runs per URL. [default: 3]
--webpagetest.custom Execute arbitrary Javascript at the end of a test to collect custom metrics.
--webpagetest.script Path to a script file
gpsi
--gpsi.key The key to use Google Page Speed Insight
Slack
--slack.hookUrl WebHook url for the Slack team (check https://<your team>.slack.com/apps/manage/custom-integrations).
--slack.userName User name to use when posting status to Slack. [default: "Sitespeed.io"]
HTML
--html.showWaterfallSummary Set to true to show waterfalls on summary HTML report [boolean] [default: false]
Options:
--version, -V Show version number [boolean]
--debug Debug mode logs all internal messages to the console. [boolean] [default: false]
--verbose, -v Verbose mode prints progress messages to the console. Enter up to three times (-vvv) to increase the level of detail. [count]
--mobile Access pages as mobile a fake mobile device. Set UA and width/height. For Chrome it will use device Apple iPhone 6. [boolean] [default: false]
--outputFolder The folder name where the result will be stored. By default the name is generated using current_date/domain/filename [default: "sitespeed-result"]
--firstParty A regex running against each request and categorize it as first vs third party URL. (ex: ".*sitespeed.*")
--utc Use Coordinated Universal Time for timestamps [boolean] [default: false]
--config Path to JSON config file
--help, -h Show help [boolean]
Read the docs at https://www.sitespeed.io/documentation/
urlOrFile
~~~
## The basics
If you installed with the global option (-g), run the command *sitespeed.io* else run the script *bin/sitespeed.js*. In the examples we will use the installed version.
You can analyze a site either by crawling or feed sitespeed.io with the URL:s you want to analyze.
### Analyze by URLs
You can choose
~~~bash
$ sitespeed.io https://www.sitespeed.io
~~~
If you wanna test multiple URLs just feed them:
~~~bash
$ sitespeed.io https://www.sitespeed.io https://www.sitespeed.io/documentation/
~~~
You can also use a plain text file with one URL on each line. Create a file called urls.txt:
~~~
http://www.yoursite.com/path/
http://www.yoursite.com/my/really/important/page/
http://www.yoursite.com/where/we/are/
~~~
And feed it:
~~~bash
$ sitespeed.io urls.txt
~~~
### Analyze by crawling
You can choose how deep to crawl (1=only one page, 2=include links from first page, etc.):
~~~bash
$ sitespeed.io https://www.sitespeed.io -d 2
~~~
### How many runs per URL?
Collecting timing metrics it's good to test the URL more than one time. You can configure how many runs doing like this (five runs):
~~~bash
$ sitespeed.io https://www.sitespeed.io -n 5
~~~
### Choose browser
Choose which browser to use:
~~~bash
$ sitespeed.io https://www.sitespeed.io -b firefox
~~~
~~~bash
$ sitespeed.io https://www.sitespeed.io -b chrome
~~~
### Connectivity
You can throttle the connection when you are fetching metrics using the browser. Choose between:
* 3g - 1600/768 300 RTT
* 3gfast - 1600/768 150 RTT
* 3gslow - 780/330 200 RTT
* 2g - 35/328 1300 RTT
* cable - 5000/1000 280 RTT
* native - your current connection
We use [TSProxy](https://github.com/WPO-Foundation/tsproxy) by default so you need Python 2.7 to be able to throttle the connection.
~~~bash
$ sitespeed.io https://www.sitespeed.io -c cable
~~~

View File

@ -0,0 +1,19 @@
---
layout: default
title: Continuous integration - Documentation - sitespeed.io
description: Use sitespeed.io in your Continuous Integration setup with Jenkins, Grunt or Team City.
keywords: Continuous Integration, jenkins, grunt, team city, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Use sitespeed.io in your Continuous Integration setup.
---
[Documentation]({{site.baseurl}}/documentation/sitespeed.io/) / Continuous Integration
# Continuous Integration
{:.no_toc}
* Lets place the TOC here
{:toc}
Coming soon!

View File

@ -0,0 +1,19 @@
---
layout: default
title: Developers - Documentation - sitespeed.io
description: How to add your own post tasks, create rules and other cool stuff.
keywords: developers, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: How to add your own post tasks, create rules and other cool stuff.
---
[Documentation]({{site.baseurl}}/documentation/sitespeed.io/) / Developers
# Developers
{:.no_toc}
* Lets place the TOC here
{:toc}
Coming soon!

View File

@ -0,0 +1,68 @@
---
layout: default
title: Docker - Documentation - sitespeed.io
description: Use Docker to run sitespeed.io.
keywords: docker, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Use Docker to run sitespeed.io.
---
[Documentation]({{site.baseurl}}/sitespeed.io/documentation/) / Docker
# Docker
{:.no_toc}
* Lets place the TOC here
{:toc}
## Containers
With 4.0 we focus on one Docker container that you should use to run sitespeed.io.
* [Chrome, Firefox & Xvfb](https://hub.docker.com/r/sitespeedio/sitespeed.io/)
## Running in Docker
The simplest way to run is like this fetching the box with Chrome and Firefox:
~~~ bash
sudo docker run --privileged --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io https://www.sitespeed.io -b chrome
~~~
If you want to feed sitespeed with a list of URL:s in a file (here named *myurls.txt*), add the file to your current directory and do like this:
~~~ bash
sudo docker run --privileged --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io myurls.txt -b chrome
~~~
In the real world you should always specify the exact version (tag) of the Docker container to make sure you use the same version all the time (else you will download the latest tag, meaning you can have old and new versions running on the server and you don't know it). Specify the tag after the container name(X.Y.Z) in this example. The tag/version number will be the same number as the sitespeed.io release:
~~~ bash
sudo docker run --privileged --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:X.Y.Z https://www.sitespeed.io -b chrome
~~~
## Setup the volume
If you want to feed sitespeed.io with a file with URL:s or if you want the HTML result, you should setup a volume. Sitespeed.io will do all the work inside the container in a directory located */sitespeed.io*. To setup your current working directory add the *-v "$(pwd)":/sitespeed.io* to your parameter list. Using "$(pwd)" will default to the root user directory. In order to specify the location, simply define an absolute path: *-v /Users/user/path:/sitespeed.io*
Note: running on Mac OS X and Windows Docker only has rights to write data in your */Users* or *C:\Users* directory. Read more [here](https://docs.docker.com/userguide/dockervolumes/#mount-a-host-directory-as-a-data-volume).
{: .note .note-warning}
## Update version (download newer sitespeed.io version)
Updating to a newer version is easy, change X.Y.Z to the version you want to use:
~~~ bash
docker pull sitespeedio/sitespeed.io:X.Y.Z
~~~
Or alternatively pull the latest version:
~~~ bash
docker pull sitespeedio/sitespeed.io
~~~
And then change your start script (or where you start your container) to use the new version number.
If you don't use version number (you should!) then just pull the container and you will run the latest version.

View File

@ -0,0 +1,19 @@
---
layout: default
title: Installation - Documentation - sitespeed.io
description: How to to install sitespeed.io. Use npm or Docker.
keywords: installation, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: How to to install sitespeed.io. Use npm or Docker.
---
[Documentation]({{site.baseurl}}/documentation/sitespeed.io/) / How it all works
# How it all works
{:.no_toc}
* Lets place the TOC here
{:toc}
Coming soon!

View File

@ -0,0 +1,30 @@
---
layout: default
title: sitespeed.io
description:
keywords: tools, documentation, web performance
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: Documentation for the sitespeed.io.
---
# Documentation 4.x
<img src="{{site.baseurl}}/img/logos/sitespeed.io.png" class="pull-right img-big" alt="Browsertime logo" width="200" height="214">
* [Introduction](introduction/)
* [Installation](installation/) - install using npm, Vagrant or run our Docker containers.
* [Configuration](configuration/) - there's alot of things you can do with sitespeed.io, lets checkout how!
* [Browsers](browsers/) - collect timings using real browsers. We support Firefox, Chrome, Internet Explorer and Safari.
* [Use Cases](use-cases/) - find out best practices for testing a site, compare with other sites.
* [Performance Dashboard](performance-dasboard/) - keep track of your metrics and performance.
* [Performance Budget](performance-budget/) - make sure you are within your performance budget.
* [Plugins](plugins/) - list/disable/enable or create your own plugin.
* [Pre/post scripting](prepostscript/) - run Selenium scripts before/after you test a URL.
* [Metrics](metrics/) - configure which metrics you want to use.
* [Continuous Integration](continuous-integration/) - generate JUnit XML/TAP and use Jenkins, Team City, Grunt or the Gulp plugin.
* [Docker](docker/) - how to use our Docker containers.
* [Mobile phones](mobile-phones/) - test using your mobile phone (Android only).
* [WebPageTest](webpagetest/) - drive WebPageTest and fetch metrics and graph them.
* [Developers](developers/) - more info on how to create your own post tasks or use your own rules.

View File

@ -0,0 +1,47 @@
---
layout: default
title: Installation - Documentation - sitespeed.io
description: How to to install sitespeed.io. Use npm or Docker.
keywords: installation, documentation, web performance, sitespeed.io
author: Peter Hedenskog
nav: documentation
image: https://www.sitespeed.io/img/sitespeed-2.0-twitter.png
twitterdescription: How to to install sitespeed.io. Use npm or Docker.
---
[Documentation]({{site.baseurl}}/documentation/sitespeed.io/) / Installation
# Installation
{:.no_toc}
* Lets place the TOC here
{:toc}
# Download and installation
## Install on Mac, Linux & Windows
Prerequisites: Install [NodeJS](https://nodejs.org/en/download/) ([Linux](https://github.com/creationix/nvm)) and make sure you have [npm](https://github.com/npm/npm) installed.
~~~ bash
$ npm install sitespeed.io@4.0.0-beta.1 -g
~~~
Run
~~~ bash
sitespeed.io --help
~~~
on Windows you should use the Docker image.
## Docker
We have [Docker images](https://hub.docker.com/u/sitespeedio/) with sitespeed.io, Chrome, Firefox and Xvfb. They are super easy to use (Xvfb is started automatically when you start the container). Here's how to use the container with both Firefox & Chrome (install [Docker](https://docs.docker.com/engine/installation/) first.
~~~ bash
$ docker pull sitespeedio/sitespeed.io:4.0-beta
$ docker run --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:4.0-beta https://www.sitespeed.io -b firefox
~~~
That will output the data from the run in the current directory. You can read more about running the containers [here]({{site.baseurl}}/documentation/docker/).

Some files were not shown because too many files have changed in this diff Show More