Git Product home page Git Product logo

defer.php's Introduction

defer.php

🚀 A PHP library that aims to help you concentrate on web performance optimization.

GitHub GitHub Release Date CodeFactor Grade Post an issue GitHub issues


🥇 Powered by defer.js - A super small, super efficient library that helps you lazy load almost everything like images, video, audio, iframes as well as stylesheets, and JavaScript.


Features

  • Simplify library options
  • Embed defer.js library
  • Normalize DOM elements
  • Fix missing meta tags
  • Fix missing media attributes
  • Preconnect to required origins
  • Preload key requests
  • Prefetch key requests
  • Browser-level image lazy-loading for the web
  • Lazy-load offscreen and hidden iframes
  • Lazy-load offscreen and hidden videos
  • Lazy-load offscreen and hidden images
  • Lazy-load CSS background images
  • Reduce the impact of JavaScript
  • Defer non-critical CSS requests
  • Defer third-party assets
  • Add fallback <noscript> tags for lazy-loaded objects
  • Add custom HTML while browser is rendering the page (splashscreen)
  • Attribute to ignore optimizing the element
  • Attribute to ignore lazyloading the element
  • Optimize AMP document
  • Minify HTML output

Installation

Install with composer

composer require shinsenter/defer.php

Load the library into your program

// Include the library
require_once __DIR__ . '/vendor/autoload.php';

// TODO: your code is from here

Requirements

This library requires PHP 5.6 or above so you need this version or the latest version of PHP installed on your system.

It recommends that the server is running PHP version 7.3+ or above for better performance and supports.

Library options from v2.x are not backward compatible with previous release's options. Please read library manual for more details.

Usages

Basic usage

// Include the library
require_once __DIR__ . '/vendor/autoload.php';

// Create a Defer object
$defer = new \AppSeeds\Defer();

// Read HTML source from file
$html_source = file_get_contents('mypage.html');

// Then get the optimized output
$result = $defer->fromHtml($html_source)->toHtml($html);
var_dump($result);

// You can use the same instance to keep loading another HTML and optimize it
$result2 = $defer->fromHtml(file_get_contents('otherpage.html'))->toHtml();
var_dump($result2);

Options

// Include the library
require_once __DIR__ . '/vendor/autoload.php';

// Declare the options
$options = [
  // Insert debug information inside the output HTML after optimization.
  // Debug information will contain outer HTMLs of tags before being optimized.
  // Default: false (turn off the debug information)
  'debug_mode' => false,

  // Although defer.js is the soul of this library,
  //   in some regions, you may want to serve defer.js library locally
  //   due to The General Data Protection Regulation (EU).
  // See: https://en.wikipedia.org/wiki/General_Data_Protection_Regulation
  // If you need to manually insert the defer.js library yourself,
  //   please enable this option to true.
  // Default: false (always automatically insert defer.js library)
  'manually_add_deferjs' => false,

  // URL to defer.js javascript file.
  // Default: https://cdn.jsdelivr.net/npm/@shinsenter/[email protected]/dist/defer_plus.min.js
  'deferjs_src'  => \AppSeeds\DeferConstant::SRC_DEFERJS_CDN,

  // URL to javascript contains fixes.
  // for some older browsers that do not support IntersectionObserver feature.
  // Default: https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver
  'polyfill_src' => \AppSeeds\DeferConstant::SRC_POLYFILL_CDN,

  // Inline the defer.js library to minimize download time in the browser.
  // Default: true (always automatically inline defer.js library)
  'inline_deferjs' => true,

  // ---------------------------------------------------------------------------

  // This option moves all stylesheets to bottom of the head tag,
  //   and moves script tags to bottom of the body tag
  // See: https://web.dev/render-blocking-resources/
  // Default: true (always automatically fix render blocking)
  'fix_render_blocking' => true,

  // Turn on optimization for stylesheets
  // This option applies to style and link[rel="stylesheet"] tags.
  // Best practices: https://web.dev/extract-critical-css/
  // Default: true (automatically optimize stylesheets)
  'optimize_css'        => true,

  // Optimize script tags (both inline and external scripts).
  // Note: The library only minify for inline script tags.
  // See: https://web.dev/unminified-javascript/
  // Default: true (automatically optimize script tags)
  'optimize_scripts'    => true,

  // Optimize img, picture, video, audio and source tags.
  // See: https://web.dev/browser-level-image-lazy-loading/
  // See: https://web.dev/lazy-loading-images/
  // Default: true (automatically optimize)
  'optimize_images'     => true,

  // Optimize iframe, frame, embed tags.
  // See: https://web.dev/lazy-loading-video/
  // Default: true (automatically optimize)
  'optimize_iframes'    => true,

  // Optimize tags that containing CSS for loading images from external sources.
  // For example, style properties contain background-image:url() etc.
  // See: https://web.dev/optimize-css-background-images-with-media-queries/
  // Default: true (automatically optimize)
  'optimize_background' => true,

  // Create noscript tags so lazy-loaded elements can still display
  //   even when the browser doesn't have javascript enabled.
  // This option applies to all tags that have been lazy-loaded.
  // See: https://web.dev/without-javascript/
  // Default: true (automatically create fallback noscript tags)
  'optimize_fallback'   => true,

  // Optimize anchor tags, fix unsafe links to cross-origin destinations
  // See: https://web.dev/external-anchors-use-rel-noopener/
  // Default: true (automatically optimize)
  'optimize_anchors' => true,

  // Add missing meta tags such as meta[name="viewport"], meta[charset] etc.
  // See: https://web.dev/viewport/
  // Default: true (automatically optimize)
  'add_missing_meta_tags' => true,

  // Preconnect to required URL origins.
  // See: https://web.dev/uses-rel-preconnect/
  // Default: true (automatically optimize)
  'enable_dns_prefetch'   => true,

  // Preload key requests such as stylesheets or external scripts.
  // See: https://web.dev/uses-rel-preload/
  // Default: false (do not apply by default)
  'enable_preloading'     => false,

  // Lazy-load all elements like images, videos when possible.
  // See: https://web.dev/lazy-loading/
  // Default: true (automatically optimize)
  'enable_lazyloading'    => true,

  // Minify HTML output.
  // See: https://web.dev/reduce-network-payloads-using-text-compression/
  // Default: false (do not minify HTML by default)
  'minify_output_html'    => false,

  // ---------------------------------------------------------------------------

  // Detect and optimize third-party URLs if possible (experiment).
  // This option also allows entering an array containing the URL origins to be defered.
  // See: https://web.dev/preload-optional-fonts/
  // Default: true (automatically optimize)
  'defer_third_party' => true,

  // Apply fade-in animation to tags after being lazy-loaded.
  // Default: false (do not apply by default)
  'use_css_fadein_effects' => false,

  // Use random background colors for images to be lazy-loaded.
  // Set the value to 'grey' if you want to use greyish background colors.
  // Default: false (do not apply by default)
  'use_color_placeholder'  => false,

  // ---------------------------------------------------------------------------

  // Default placeholder for lazy-loaded img tags.
  // If this value is not set or empty,
  //   an SVG image will be used to avoid CLS related problems.
  // See: https://web.dev/cls/
  // Default: blank string
  'img_placeholder'    => '',

  // Default placeholder for lazy-loaded iframe tags.
  // Default: 'about:blank'
  'iframe_placeholder' => 'about:blank',

  // ---------------------------------------------------------------------------

  // Show custom HTML content (splashscreen)
  //   while browser is rendering the page (experiment).
  // Default: blank string (no splashscreen)
  'custom_splash_screen' => '',

  // ---------------------------------------------------------------------------

  // Do not lazy-load for URLs containing
  //   one of the array's texts (exact match keywords).
  // Default: blank array
  'ignore_lazyload_paths'  => [],

  // Do not lazy-load for tags containing
  //   one of the array's texts (exact match keywords).
  // Default: blank array
  'ignore_lazyload_texts'  => [],

  // Do not lazy-load for tags containing one of these CSS class names.
  // Default: blank array
  'ignore_lazyload_css_class'  => [],

  // Do not lazy-load for tags matching one of these CSS selectors.
  // See: https://www.w3schools.com/cssref/css_selectors.asp
  // Default: blank array
  'ignore_lazyload_css_selectors'  => [
    // 'header img',
    // 'img#logo',
  ],
];

// Create a Defer object
$defer  = new \AppSeeds\Defer($options);
$result = $defer->fromHtml(file_get_contents('mypage.html'))->toHtml();
var_dump($result);

// Change library options
$defer->options()->debug = true;
$defer->options()->minify_output_html = true;

// Keep loading another HTML and optimize it with new options
$result2 = $defer->fromHtml(file_get_contents('otherpage.html'))->toHtml();
var_dump($result2);

Optimize final output HTML of a website

You also can capture the final output generated by PHP and optimize it before giving it back to browser.

// Include the library
require_once __DIR__ . '/vendor/autoload.php';

// Create a callback function
function ob_deferphp($html) {
  // Create a Defer object
  $defer = new \AppSeeds\Defer([
    /* declare options here */
  ]);

  return $defer->fromHtml($html)->toHtml();
}

// Call ob_start() function to create an output buffer
//   and pass above callback function name as its argument.
// This function should be called before any other process to print the content.
ob_start('ob_deferphp');

// .......... (place your PHP code here)

// And call this to flush optimized output HTML
//   right before you send the final HTML to browser.
ob_end_flush();

Ignore optimization for some elements

Add an data-ignore attribute to element that you don't want it to be optimized by the library. This attribute can be used for all HTML elements.

<!-- Example for add data-ignore for a script tag -->
<script data-ignore>var MY_IMPORTANT_VARIABLE = 'important value';</script>

<!-- Example for add data-ignore for an img tag -->
<img data-ignore src="my_photo.jpeg" alt="Awesome photo" />

Add an data-nolazy attribute to element that you don't want it to be lazy-loaded by the library. Other optimizations for that element will still be applied except lazy-load. This attribute can be used for all <img>, <picture>, <video>, <audio>, <iframe> and also <link rel="stylesheet"> elements.

<!-- Example for add data-nolazy for an img tag -->
<img data-nolazy src="my_photo.jpeg" alt="Awesome photo" />

Stylesheets and JavaScript

This library supports a more efficient lazy-load method for stylesheets and JavaScript tags that contain the defer attribute.

<!-- Example for defer an stylesheet -->
<link defer rel="stylesheet" href="some/heavy/fonts.css">

<!-- Examples for defer some heavy script tags -->
<script defer src="some/heavy/libraries.js"></script>
<script defer>someHeavyTask();</script>

Even when the library is turned off, above tags that contain defer attribute are backwards compatible and work well in most modern browsers. You can use it with peace of mind.

AMP page

Only few options of this library are applicable to AMP pages (minifying HTML content for example).

My works

Defer.js

https://code.shin.company/defer.js/

🥇 A super small, super efficient library that helps you lazy load almost everything like images, video, audio, iframes as well as stylesheets, and JavaScript.

Wordpress plugin

https://code.shin.company/defer-wordpress/

⚡️ A native, blazing fast lazy loader. ✅ Legacy browsers support (IE9+). 💯 SEO friendly. 🧩 Lazy-load everything.

Laravel package

https://code.shin.company/defer-laravel/

🚀 A Laravel package that focuses on minimizing payload size of HTML document and optimizing processing on the browser when rendering the web page.

Support my activities

Donate via Paypal Become a sponsor Become a stargazer Report an issue


From Vietnam 🇻🇳 with love.

defer.php's People

Contributors

dependabot-preview[bot] avatar mnakalay avatar shinsenter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

defer.php's Issues

Uncaught Error: Call to a member function get()

On My Framework what i use

Fatal error: Uncaught Error: Call to a member function get() on null in C:\xampp\htdocs\wcs\lib\system\api\defer.php\src\Defer.php:211 Stack trace: #0 C:\xampp\htdocs\wcs\lib\system\api\defer.php\src\Defer.php(78): shinsenter\Defer->nodefer() #1 C:\xampp\htdocs\wcs\lib\system\event\listener\OutputModListener.class.php(57): shinsenter\Defer->fromHtml('\r\n\r\n\r\n<!DOCTYPE...') #2 C:\xampp\htdocs\wcs\lib\system\event\EventHandler.class.php(221): wcf\system\event\listener\OutputModListener->execute('wcf\util\Header...', 'wcf\util\Header...', 'parseOutput', Array) #3 C:\xampp\htdocs\wcs\lib\util\HeaderUtil.class.php(140): wcf\system\event\EventHandler->fireAction('wcf\util\Header...', 'parseOutput') #4 [internal function]: wcf\util\HeaderUtil::parseOutput('\r\n\r\n\r\n<!DOCTYPE...', 9) #5 C:\xampp\htdocs\wcs\lib\system\WCF.class.php(191): ob_end_flush() #6 [internal function]: wcf\system\WCF::destruct() #7 {main} thrown in C:\xampp\htdocs\wcs\lib\system\api\defer.php\src\Defer.php on line 211

i musst change teh Follow Line https://github.com/shinsenter/defer.php/blob/master/src/Defer.php#L211 to
$has_nodefer = 0;

Wrong HTML entity encoding in attribute

The website is: dentzar.com.
Please click on the Search button and you’ll see strange looking box.

Original HTML:

data-avia-search-tooltip="&lt;form role=&quot;search&quot; action=&quot;https://dentzar.com/&quot; id=&quot;searchform&quot; method=&quot;get&quot; class=&quot;&quot;&gt;
&lt;div&gt;
&lt;input type=&quot;submit&quot; value=&quot;&quot; id=&quot;searchsubmit&quot; class=&quot;button avia-font-entypo-fontello&quot; /&gt;
&lt;input type=&quot;text&quot; id=&quot;s&quot; name=&quot;s&quot; value=&quot;&quot; placeholder='Search' /&gt;
&lt;/div&gt;
&lt;/form&gt;"

Defer.js optimized HTML:

data-avia-search-tooltip="&lt;form role=&amp;quot;search&amp;quot; action=&amp;quot;https://dentzar.com/&amp;quot; id=&amp;quot;searchform&amp;quot; method=&amp;quot;get&amp;quot; class=&amp;quot;&amp;quot;&gt;
&lt;div&gt;
&lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;quot; id=&amp;quot;searchsubmit&amp;quot; class=&amp;quot;button avia-font-entypo-fontello&amp;quot; /&gt;
&lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;s&amp;quot; name=&amp;quot;s&amp;quot; value=&amp;quot;&amp;quot; placeholder='Search' /&gt;
&lt;/div&gt;
&lt;/form&gt;"

Reason: wrong HTML entity encoding.
Schedule: Fix in the next release
Temporary fix: None

NORMALIZE_XPATH bug?

this code

<p>Na was machst du den hier, Möchtest du den Boss, Chef, Gott usw. des Forum mal genauer betrachten oder haste einfach Interesse an meiner Person und Persönlichkeit?<br><br>Naja dann wünsche ich dir Viel Spaß und hoffe deine Träume erfüllt mein Profile <img src="https://www.cafe-anime.de/_OLD/wcf/images/smilies/wink.png" alt=";)"></p>

after minifyOutputHTML
<p>Na was machst du den hier, Möchtest du den Boss, Chef, Gott usw. des Forum mal genauer betrachten oder haste einfach Interesse an meiner Person und Persönlichkeit?<br><br> Naja dann wünsche ich dir Viel Spaß und hoffe deine Träume erfüllt mein Profile<img alt=";)" class="defer-lazied defer-loaded" data-src="https://www.cafe-anime.de/_OLD/wcf/images/smilies/wink.png" src="https://www.cafe-anime.de/_OLD/wcf/images/smilies/wink.png" data-lazied="IMG"><noscript><img src="https://www.cafe-anime.de/_OLD/wcf/images/smilies/wink.png" alt=";)" class="jsResizeImage"></noscript></p>

after "Profile<" is a space missing

or

<p><strong>Avatar (<a href="https://www.cafe-anime.de/index.php?thread/17375-10-jahre-cafe-anime-cafe-anime-feiert-geburtstag/&amp;postID=514919#post514919">Vorlage</a>) by <a href="https://www.cafe-anime.de/index.php?user/5183-blacksad/">Blacksad</a>, Danke</strong></p>

after
<p><strong>Avatar (<a href="https://www.cafe-anime.de/index.php?thread/17375-10-jahre-cafe-anime-cafe-anime-feiert-geburtstag/&amp;postID=514919#post514919">Vorlage</a> ) by<a href="https://www.cafe-anime.de/index.php?user/5183-blacksad/">Blacksad</a>, Danke</strong></p>

by "by<a" missing space

Add Deffer inline

DeepL Translation:
Can you insert an option for deffer_min.js. The one that inserts the script inline of HTMl and not external?

Kannst du eine Option für deffer_min.js einfügen. Die den den Script inline des HTMl einfügt und nicht externe?

Parser's issue with scripts containing closing tags

Hello,
Whenever the page contains a script which contains a closing HTML tag, the parser gets it wrong and adds a closing </script> tag right in the middle

For instance this

$('<div class="bg-color-overlay"></div>').prependTo('body');

becomes this

$('<div class="bg-color-overlay"></script></div>').prependTo('body');

And breaks everything.

How do use width smarty template ?

Hi !

My project using smarty template engine it's synax bellow

require_once(SMARTY_DIR . 'Smarty.class.php');

$smarty = new Smarty();

$smarty->setTemplateDir('/web/www.example.com/guestbook/templates/');
$smarty->setCompileDir('/web/www.example.com/guestbook/templates_c/');
$smarty->setConfigDir('/web/www.example.com/guestbook/configs/');
$smarty->setCacheDir('/web/www.example.com/guestbook/cache/');

$smarty->assign('name','Ned');

//** un-comment the following line to show the debug console
//$smarty->debugging = true;

$smarty->display('index.tpl');

it's display through display function but shinsenter not like that it's output direct

feature request fully local

i wish me a fully local version of JS because General Data Protection Regulation GDPR (DSGVO)
i cant use external source and the Polyfill.js is includes as External source by me

Plugin does not work properly with caching (non-optimized version gets saved)

I think I posted this in the wrong github repo--I was sent to the defer.js one. Anyway, for some reason your optimized output does not get saved in the Cache Enabler cache. The author of Autoptimize says AO uses output buffering in order not to depend on any caching plugin.

Is it possible you could use this technique so yours gets cached, too? I prefer your plugin.

Testing with Dev Master (v2.5)

Hi.

I am using this version Dev Master (v2.5) and got it all working.

I am using it in relation to Wordpress.

So if you have some updates you want to push, or mention, or test, feel free to let me know :) and I'll give it a run.

[Bug] Doesn't work on php5.6, codeigniter 3

Hi I have tested your project on my Codeigniter source code.

Wow it changed the html code structure amazingly. But there was a problem. I think it is caused by your defer.js component. It makes all image and js resources unloadable.

Best regards and good luck!

found a Broken Script

I have found a Script thats Broken all (No Console Error)

Before
001
Code-> https://paste.ee/p/ePXqY

After
002
Code-> https://paste.ee/p/aThOO

Setting

  	// Library injection
  	$defer->append_defer_js     = true;
  	$defer->default_defer_time  = 10;

  	// Page optimizations
  	$defer->enable_preloading   = false;
  	$defer->enable_dns_prefetch = false;
  	$defer->fix_render_blocking = false;
  	$defer->minify_output_html  = false;

  	// Tag optimizations
  	$defer->enable_defer_css        = false;
  	$defer->enable_defer_scripts    = false;
  	$defer->enable_defer_images     = false;
  	$defer->enable_defer_iframes    = false;
  	$defer->enable_defer_background = false;
  	$defer->enable_defer_fallback   = false;

  	// Web-font optimizations
  	$defer->defer_web_fonts = false;

  	// Image and iframe placeholders
  	$defer->empty_gif               = '';
  	$defer->empty_src               = '';
  	$defer->use_color_placeholder   = false;
  	$defer->use_css_fadein_effects  = false;

  	// Blacklist
  	$defer->do_not_optimize = [
  		'document\.write\s*\(',
  		'(jquery([-_][\d\.]+)?(\.min)?\.js|jquery-core)',
  		'partner',
  		'styleLogo'
  	];

Got Warning Deprecated

Deprecated: Return type of AppSeeds\Elements\DocumentNode::normalize() should either be compatible with DOMNode::normalize(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in \vendor\shinsenter\defer.php\src\Elements\DocumentNode.php on line 272

Deprecated: DOMDocument::createElement(): Passing null to parameter #2 ($value) of type string is deprecated in \vendor\shinsenter\defer.php\src\Elements\DocumentNode.php on line 197

how to fix it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.