-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 33fdd14
Showing
41 changed files
with
9,125 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules | ||
.DS_Store | ||
npm-debug.log | ||
yarn-error.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Better Resource Hints | ||
Easy preloading, prefetching, HTTP/2 server pushing for your CSS and JavaScript. | ||
|
||
## Description | ||
Better Resource Hints will make your WordPress site faster using modern, performance-enhancing resource hints supported by most of today's browsers and servers. | ||
|
||
As it stands, WordPress isn't that bad about leveraging a base level of resource hints. A basic API has been [shipped since version 4.6.](https://make.wordpress.org/core/2016/07/06/resource-hints-in-4-6/). However, this functionality only scratches the service, providing only `dns-prefetch` tags out of the box. Better Resource Hints helps you leverage some of the most effective, cutting-edge techniques available to most browsers today, and more importantly, it allows you to implement these tactics in an unintimidating yet flexible way. Specifically, this plugin focuses on the following types of hints for your styles and JavaScript assets: | ||
|
||
**Preloading** - This occurs when the browser is told it can start downloading an asset in the background early during page load, instead of waiting until the asset is explicitly called to start the process. This hint is most beneficial for assets loaded later on in the page, but are nonetheless essential to the page's functionality. More often than not, this is a JavaScript file. Enabling this results in an overall faster load time, and quicker time to interactive. | ||
|
||
**Prefetching** - Prefetching assets is similar to preloading, but the assets are downloaded in low priority for the purpose of caching them for later use. For example, if a user hits your home page and is likely to go to a page that uses a heavy JavaScript file, it's wise to prefetch that asset on the home page, so it's cached and ready to go on the next. Again, the result is a quicker subsequent page load, quicker time to interactive, and an improved overall user experience. This is different from DNS prefetching, which will only resolve the DNS of a resource's host, and not actually download the resource itself. | ||
|
||
**Server Push** - If enabled, server push will tell your server to start delivering an asset before the browser even asks for it. This results in a much faster delivery of key assets, and be toggled on for both preloaded and prefetched assets. **Note: This feature requires a server that supports server push, and is the most experimental strategy this plugin provides.** | ||
|
||
As with any sort of performance-enhancing technique, just be aware that they should be used judiciously, and that the results you see will depend on the amount of resource your site loads, as well as how your server is configured. For additional reading, see some of the resources below: | ||
|
||
[Preload, Prefetch, & Priorities in Chrome](https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf) | ||
[Preloading Key Requests](https://developers.google.com/web/tools/lighthouse/audits/preload) | ||
[Preload: What's It Good For?](https://www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/) | ||
|
||
#### About Preloading CSS | ||
|
||
Because of their high placement on a page, if the option is enabled, your CSS files will be asyncronously preloaded, and _then_ turned into a stylesheet once they've completely loaded. The advantage to doing this is that while the files are downloading, they won't block the rest of the page from rendering, resulting an overall faster page load. | ||
|
||
However, this also means that there may be a flash of unstyled content on the page for a brief moment as the files download. To prevent this, it's recommended to only preload CSS files that are not critical to the initial view of the page. This will allow you to gain some performance points without sacrificing use experience as the page loads. | ||
|
||
## Installation | ||
1. Download the plugin and upload to your plugins directory, or install the plugin through the WordPress plugins page. | ||
2. Activate the plugin through the 'Plugins' page. | ||
3. Use the Settings -> Better Resource Hints screen to choose whether and which assets to preload, prefetch, and server push. | ||
|
||
## Using the Plugin | ||
|
||
Upon activation, Better Resource Hints will optimize your resource hints in a consevrative, low-risk way by only preloading JavaScript assets enqueued in the footer. Beyond this, you are able to adjust settings to tweak optimization as seen fit. As a means of testing your optimizations, use a tool like [Google Lighthouse](https://developers.google.com/web/tools/lighthouse/) to measure the impact of these changes on your site's performance. | ||
|
||
As mentioned, the techniques used here are largely supported by modern browsers, but your results may vary depending on the amount of assets being loaded on your site, as well as your server configuration. | ||
|
||
### Changelog | ||
|
||
#### 1.0.0 | ||
* Initial release. | ||
|
||
## Feedback | ||
You like it? [Email](mailto:alex@macarthur.me) or [tweet](http://www.twitter.com/amacarthur) me. You hate it? [Email](mailto:alex@macarthur.me) or [tweet](http://www.twitter.com/amacarthur) me. | ||
|
||
Regardless of how you feel, your review would be greatly appreciated! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?php | ||
/** | ||
* Plugin Name: Better Resource Hints | ||
* Description: Easy preloading, prefetching, and HTTP/2 server pushing for your CSS and JavaScript. | ||
* Version: 1.0.0 | ||
* Author: Alex MacArthur | ||
* Author URI: http://macarthur.me | ||
* License: GPLv2 or later | ||
* License URI: http://www.gnu.org/licenses/gpl-2.0.html | ||
*/ | ||
|
||
namespace BetterResourceHints; | ||
|
||
require_once 'src/Settings.php'; | ||
require_once 'src/Filters.php'; | ||
require_once 'src/Preloader.php'; | ||
require_once 'src/Prefetcher.php'; | ||
require_once 'src/Utilities.php'; | ||
|
||
if ( !defined( 'WPINC' ) ) { | ||
die; | ||
} | ||
|
||
class App { | ||
|
||
private static $instance; | ||
|
||
protected static $options_prefix = 'better_resource_hints'; | ||
protected static $admin_settings_page_slug = 'better_resource_hints'; | ||
protected static $copy = array( | ||
'public' => 'Better Resource Hints' | ||
); | ||
|
||
public static function init() { | ||
if(!isset(self::$instance) && !(self::$instance instanceof App)) { | ||
self::$instance = new App; | ||
} | ||
} | ||
|
||
public function __construct() { | ||
new Filters; | ||
new Settings; | ||
new Preloader; | ||
new Prefetcher; | ||
|
||
add_action( 'admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts' )); | ||
} | ||
|
||
/** | ||
* Enqueue necessary admin scripts & styles. | ||
* | ||
* @return void | ||
*/ | ||
public function enqueue_styles_and_scripts() { | ||
wp_enqueue_style( 'better-resource-hints', plugin_dir_url( __FILE__ ) . 'src/assets/css/style.css', array(), null); | ||
wp_enqueue_script( 'better-resource-hints', plugin_dir_url( __FILE__ ) . 'src/assets/js/scripts.min.js', array(), false, true); | ||
} | ||
|
||
} | ||
|
||
App::init(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"name": "better-resource-hints", | ||
"description": "No-nonsense preloading, prefetching, and HTTP/2 server pushing for your CSS and JavaScript assets.", | ||
"type": "wordpress-plugin", | ||
"minimum-stability": "stable", | ||
"license": "GPL-2.0", | ||
"authors": [ | ||
{ | ||
"name": "Alex MacArthur", | ||
"email": "alex@macarthur.me", | ||
"homepage": "https://macarthur.me", | ||
"role": "Developer" | ||
} | ||
], | ||
"support" : { | ||
"issues": "https://github.com/alexmacarthur/better-resource-hints/issues", | ||
"source": "https://github.com/alexmacarthur/better-resource-hints" | ||
}, | ||
"require": { | ||
"composer/installers": "^1.0.7" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<?php // Silence is golden. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"/src/assets/js/scripts.min.js": "/src/assets/js/scripts.min.js", | ||
"/src/assets/css/style.css": "/src/assets/css/style.css", | ||
"/src/assets/js/preload.min.js": "/src/assets/js/preload.min.js" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"name": "wp-better-resource-hints", | ||
"author": "Alex MacArthur <alex@macarthur.me>", | ||
"email": "alex@macarthur.me", | ||
"url": "https://macarthur.me", | ||
"description": "Easy preloading, prefetching, and HTTP/2 server pushing for your CSS and JavaScript assets.", | ||
"version": "1.0.0", | ||
"license": "GPL-2.0", | ||
"main": "better-resource-hints.php", | ||
"repository": "https://github.com/alexmacarthur/wp-better-resource-hints", | ||
"bugs": { | ||
"url": "https://github.com/alexmacarthur/wp-better-resource-hints/issues" | ||
}, | ||
"keywords": [ | ||
"server push", | ||
"preload", | ||
"css", | ||
"javascript", | ||
"optimization", | ||
"wordpress" | ||
], | ||
"devDependencies": { | ||
"babili-webpack-plugin": "^0.1.2", | ||
"laravel-mix": "^2.1.11" | ||
}, | ||
"scripts": { | ||
"dev": "NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", | ||
"watch": "NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", | ||
"build": "NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
=== Better Resource Hints === | ||
|
||
Contributors: alexmacarthur | ||
Donate link: paypal.me/alexmacarthur | ||
Tags: performance, resource hints, prefetch, preload, server push, HTTP/2 | ||
Requires at least: 4.0 | ||
Tested up to: 4.9.5 | ||
Stable tag: 1.0.0 | ||
License: GPLv2 or later | ||
License URI: http://www.gnu.org/licenses/gpl-2.0.html | ||
|
||
== Description == | ||
|
||
Better Resource Hints will make your WordPress site faster using modern, performance-enhancing resource hints supported by most of today's browsers and servers. | ||
|
||
As it stands, WordPress isn't that bad about leveraging a base level of resource hints. A basic API has been [shipped since version 4.6.](https://make.wordpress.org/core/2016/07/06/resource-hints-in-4-6/). However, this functionality only scratches the service, providing only `dns-prefetch` tags out of the box. Better Resource Hints helps you leverage some of the most effective, cutting-edge techniques available to most browsers today, and more importantly, it allows you to implement these tactics in an unintimidating yet flexible way. Specifically, this plugin focuses on the following types of hints for your styles and JavaScript assets: | ||
|
||
**Preloading** - This occurs when the browser is told it can start downloading an asset in the background early during page load, instead of waiting until the asset is explicitly called to start the process. This hint is most beneficial for assets loaded later on in the page, but are nonetheless essential to the page's functionality. More often than not, this is a JavaScript file. Enabling this results in an overall faster load time, and quicker time to interactive. | ||
|
||
**Prefetching** - Prefetching assets is similar to preloading, but the assets are downloaded in low priority for the purpose of caching them for later use. For example, if a user hits your home page and is likely to go to a page that uses a heavy JavaScript file, it's wise to prefetch that asset on the home page, so it's cached and ready to go on the next. Again, the result is a quicker subsequent page load, quicker time to interactive, and an improved overall user experience. This is different from DNS prefetching, which will only resolve the DNS of a resource's host, and not actually download the resource itself. | ||
|
||
**Server Push** - If enabled, server push will tell your server to start delivering an asset before the browser even asks for it. This results in a much faster delivery of key assets, and be toggled on for both preloaded and prefetched assets. **Note: This feature requires a server that supports server push, and is the most experimental strategy this plugin provides.** | ||
|
||
As with any sort of performance-enhancing technique, just be aware that they should be used judiciously, and that the results you see will depend on the amount of resource your site loads, as well as how your server is configured. For additional reading, see some of the resources below: | ||
|
||
[Preload, Prefetch, & Priorities in Chrome](https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf) | ||
[Preloading Key Requests](https://developers.google.com/web/tools/lighthouse/audits/preload) | ||
[Preload: What's It Good For?](https://www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/) | ||
|
||
= About Preloading CSS = | ||
Because of their high placement on a page, if the option is enabled, your CSS files will be asyncronously preloaded, and _then_ turned into a stylesheet once they've completely loaded. The advantage to doing this is that while the files are downloading, they won't block the rest of the page from rendering, resulting an overall faster page load. | ||
|
||
However, this also means that there may be a flash of unstyled content on the page for a brief moment as the files download. To prevent this, it's recommended to only preload CSS files that are not critical to the initial view of the page. This will allow you to gain some performance points without sacrificing use experience as the page loads. | ||
|
||
== Installation == | ||
|
||
1. Download the plugin and upload to your plugins directory, or install the plugin through the WordPress plugins page. | ||
2. Activate the plugin through the 'Plugins' page. | ||
3. Use the Settings -> Better Resource Hints screen to choose whether and which assets to preload, prefetch, and server push. | ||
|
||
== Using the Plugin == | ||
|
||
Upon activation, Better Resource Hints will optimize your resource hints in a consevrative, low-risk way by only preloading JavaScript assets enqueued in the footer. Beyond this, you are able to adjust settings to tweak optimization as seen fit. As a means of testing your optimizations, use a tool like [Google Lighthouse](https://developers.google.com/web/tools/lighthouse/) to measure the impact of these changes on your site's performance. | ||
|
||
As mentioned, the techniques used here are largely supported by modern browsers, but your results may vary depending on the amount of assets being loaded on your site, as well as your server configuration. | ||
|
||
== Frequently Asked Questions == | ||
|
||
= What about browsers that don't support these resource hints? = | ||
If someone's using an older browser that doesn't support these hints, nothing will break. The generated tags will just be skipped over and the page will load as normal. The one slight exception to this is preloading CSS. Because the original `link` tags are completely converted to `rel="preload"`, there would be nothing on which to fall back. To remedy this, a small polyfill is included by this plugin, so you can be at ease. | ||
|
||
= How can I test my site's performance to verify improvements? = | ||
To start, I'd recommend [Google Lighthouse](https://developers.google.com/web/tools/lighthouse/). It's built into Google Chrome and there's also a command line utility available. Beyond that, you could try out something like [WebPagetest](https://www.webpagetest.org/) or a more enterprise solution like [SpeedCurve](https://speedcurve.com/). | ||
|
||
= How can I specifically verify that preloading is working? = | ||
First, ensure that your source code contains `<link rel="preload" ... >` tags. Then, in Chrome, inspect the page and open up the Network tab. Refresh the page, and filter for your JS files to make things a little easier. Preloaded assets will have a "Priority" of "High." | ||
|
||
= How can I verify that prefetching is working? = | ||
Remember, this is different from `dns-prefetch`, and will download assets in the background as to cache them for future use. To verify a resource is being prefetched, first ensure that your source code contains `<link rel="prefetch" ... >` tags. Then, in Chrome, inspect the page and open up the Network tab. Refresh the page, and filter for your JS files to make things a little easier. Prefetched assets will have a "Priority" of "Low." | ||
|
||
= How can I verify HTTP/2 server push is working? = | ||
First, ensure your server is configured to support server push. Then, you can use Chrome's net internals to inspect each HTTP/2 session and which assets are being pushed. Navigate to `chrome://net-internals/#http2` in Chrome to view this information. | ||
|
||
== Screenshots == | ||
|
||
== Changelog == | ||
|
||
= 1.0.0 = | ||
* Initial release. | ||
|
||
== Feedback == | ||
|
||
You like it? [Email](mailto:alex@macarthur.me) or [tweet](http://www.twitter.com/amacarthur) me. You hate it? [Email](mailto:alex@macarthur.me) or [tweet](http://www.twitter.com/amacarthur) me. | ||
|
||
Regardless of how you feel, your review would be greatly appreciated! | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
namespace BetterResourceHints; | ||
|
||
class Filters extends App { | ||
|
||
public function __construct() { | ||
add_filter('style_loader_tag', array($this, 'add_id_to_style_tags'), 10, 4); | ||
add_filter('script_loader_tag', array($this, 'add_id_to_script_tags'), 10, 3); | ||
} | ||
|
||
public function add_id_to_style_tags($html, $handle, $href, $media) { | ||
return str_replace('<link ', '<link data-handle="' . $handle . '" ', $html); | ||
} | ||
|
||
public function add_id_to_script_tags($tag, $handle, $src) { | ||
return str_replace('<script ', '<script data-handle="' . $handle . '" ', $tag); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<?php | ||
|
||
namespace BetterResourceHints; | ||
|
||
class Prefetcher extends App { | ||
|
||
public function __construct() { | ||
add_action('wp_head', array($this, 'prefetch_javascript'), 1); | ||
add_action('wp_head', array($this, 'prefetch_styles'), 1); | ||
} | ||
|
||
public function prefetch_javascript() { | ||
$this->generate_prefetch_markup('scripts'); | ||
} | ||
|
||
public function prefetch_styles() { | ||
$this->generate_prefetch_markup('styles'); | ||
} | ||
|
||
/** | ||
* Only allow users to prefetch by specific handle, | ||
* because we don't want to prefetch all admin scripts | ||
* if that option is selected. | ||
* | ||
* @param string $type | ||
* @return void | ||
*/ | ||
private function generate_prefetch_markup($type = 'scripts') { | ||
|
||
global ${'wp_' . $type}; | ||
$singularType = substr_replace($type, "", -1); | ||
$handlesToPrefetch = []; | ||
|
||
$noSpaces = Utilities::strip_spaces(Utilities::get_option('prefetch_'. $type. '_handles')); | ||
$specificHandlesToPrefetch = explode(',', $noSpaces ?: ''); | ||
|
||
//-- @todo In the future, check if user would like to preload $specificHandlesToPrefetch's dependencies as well. | ||
// foreach($specificHandlesToPrefetch as $handle) { | ||
// $specificHandlesToPrefetch = array_merge($specificHandlesToPrefetch, Utilities::collect_all_deps($handle)); | ||
// } | ||
|
||
//-- Loop through and print preload tags. | ||
foreach($specificHandlesToPrefetch as $handle) { | ||
$resource = isset(${'wp_' . $type}->registered[$handle]) | ||
? ${'wp_' . $type}->registered[$handle] | ||
: false; | ||
|
||
if($resource === false) continue; | ||
if(empty($resource->src)) continue; | ||
|
||
$methodToCheckIfAssetIsEnqueued = 'wp_' . $singularType . '_is'; | ||
if($methodToCheckIfAssetIsEnqueued($handle)) continue; | ||
|
||
$source = $resource->src . ($resource->ver ? "?ver={$resource->ver}" : ""); | ||
|
||
if(Utilities::get_option("prefetch_assets_enable_server_push")) { | ||
Utilities::construct_server_push_headers('prefetch', $source); | ||
} | ||
echo apply_filters('better_resource_hints_prefetch_tag', "<link rel='prefetch' href='{$source}'/>\n", $handle, $type); | ||
} | ||
} | ||
} |
Oops, something went wrong.