Live Support

Introduction

What is Warp?

Warp is a high-performance caching module for Magento. It has been shown to improve page response by 10-15 times over other caching solutions. It is the newest version of Lightspeed

What does this mean? Users are able to interact with your website up to 90% faster than they could before. Your cached pages will be loading in as little as 100 milliseconds. This is compared to an uncached performance of up to 4.5 seconds on a page load. Servers are able to serve up to 100x more requests with the same resources, thus lowering total server cost.

How it Works

Warp operates on a caching methodology of caching entire pages and then “punching holes” to retrieve dynamic content. This is different than most caching methods which compute the entire page, retrieving pieces of content from the cache as it loads.

The first user to visit a page will cause it to be cached. Every visitor that follows will be viewing the cached version of the page until the page is expired from the cache. If you use the Warp Caching utility, it will automatically cache the page for you, then the page will already be cached when the first user arrives.

Installation

Before you Install

As with all our modules (and all modules in general), installing this module directly and solely in a live environment is strongly discouraged. It is recommended that it be installed in a development environment, configured, tested, and then deployed to your live environment through your deployment method of choice (i.e. - git, subversion, etc...). If this is not possible, then the next best thing would be to make a FULL backup before installation.

Caution: Conflicts

We've experienced issues with Warp installed along side other 3rd-party caching components. Install other caching components at your own risk. While we cannot test and support compatibility between other products much of the time, we receive reports of varying experience with using similarly purposed modules along side one another. Use caution in attempting to install modules of similar nature at the same time.

Compilation

As with all our modules (and all modules in general), installing this module while compilation is turned on is not recommended. Please turn off compilation before installing.

Make sure not to use Compilation with this module as it does not work with Compilation at this time.

Pre-requisites

Code/Conflicts

  • NO EDITS OR MODIFICATIONS TO MAGENTO CORE (Typically, this includes all code inside the app/code/core folder)
  • No conflicting modules (or conflicting custom code) installed (Typically, if installed component/module affects same functionality as Warp--caching, you should be wary of conflicts)

Magento Version

  • Community Edition 1.0 - 1.9.0.1

Installing the Basic Application

Download Warp and unzip the zipped file.

Navigate to the root of your application. You should see folders like (app, downloader, skin, etc...). Copy all of the files to the root of your magento installation.

To make the changes to your .htaccess file that are required for Warp, simply do the following:

APACHE Configuring your .htaccess file

DirectoryIndex index.php
DirectoryIndex warp.php
RewriteRule .* index.php [L]
RewriteRule .* warp.php [L]
.htaccess

Other references to index.php

Depending on your apache configuration, if you have any other references to index.php in the .htaccess file, you may have to make sure to change those to warp.php. Most won't have any more than those listed above. However, it might be something to come back to if you complete installation and are experiencing issues getting Warp up and running.

Installation Method

If you have sub-directories in the application that rely on an index.php file to serve content, you will need to adjust the .htaccess file in those directories accordingly. Details on how to do that are outside the scope of this documentation. However, chances are that if you setup other files to do this, you already know how to fix it.

Registration

Before your Warp caching module will work, it must be registered to your installation. From your Open Commerce account dashboard, click the 'My Orders' tab and then click on the order with your Warp information in it and view your order confirmation.

Copy the License and Installation Key (as seen below) into the appropriate Magento admin fields found in TinyBrick > Warp > Warp Configuration (as seen below).

If you get access denied or other issue, you might have to refresh this admin view (refer to Troubleshooting/FAQs for more info).

Configuration - Quick

Quick configuration is the best way to see the power of Warp in the least amount of time. If you want to quickly target the 70-90% of your visitors that are not shopping or logging in, you can have Warp configured in as little as 30 minutes.

Here’s how:

  1. The warp.xml file has been added for you so you shouldn't need to do much, if you have other cms/xml pages you want to have cached automatically that are not found in the warp.xml, follow the next step.
  2. Add this code snippet:

    XML Code Snippet

    <reference name="root">
      <action method="cachePage">
          <expires></expires>
          <disqualifiers>cart,loggedin,compare</disqualifiers>
      </action>
    </reference>
  3. To the layout files (app/design/frontend/[package]/[theme]/layout) listed below:

XML tip

For anyone not familiar with Magneto and it's use of XML, it's worth noting that the code snippet from above should be added after each of the opening tags of each layout nodes from the table below.

XML Tip Example

<cms_page translate="label">
    <reference name="root">
        <action method="cachePage">
            <expires></expires>
            <disqualifiers>cart,loggedin,compare</disqualifiers>
        </action>
    </reference>
    ...
</cms_page>
Page Layout File Layout Node
CMS Pages cms.xml <cms_page>
Layered Catalog Pages catalog.xml <catalog_category_layered>
Product View Pages catalog.xml <catalog_product_view>
Layered (no-children) Catalog Pages (optional) catalog.xml <catalog_category_layered_nochildren>

Why is that last page optional?

You colored INSIDE the lines when you were in school didn't you? Well, so did Warp. Warp caches every layout you specify and not a single one more. That last one is optional because not everyone has a category structure that uses that particular layout. It's also worth noting that while our suggested layouts/pages in the table above cover non-comittal traffic on the front-end of your store, Warp can cache whatever layout you tell it to. For more information on caching more layouts/pages, refer to the full configuration.

Gotcha? Dynamic Content

If you have any content that will need to be unique for each user (recently viewed products, for example), then you will need to provide a full configuration with hole punches.

Memcached

When using memcached, make sure you use a seperate memcached instance for your Cache and Sessions. If you use the same instance, you will have problems with clearing sessions whenever you clear cache because it uses the flush_all command. Users will see the cart drop and everyone will be logged out.

Redis

When using Redis, make sure you use a seperate Redis instance for your Cache and Sessions. If you use the same instance, you will have problems with clearing sessions whenever you clear cache because it uses the flush_all command. Users will see the cart drop and everyone will be logged out.

General Usage

Now, let's give you a tour of how to control Warp from the admin. The main control area of the admin resides in the System -> Cache Management page. It should look something like this:

The important components of this page include the following cache components:

  • Whole Pages - Warp

Enable each of these components. Each of these are areas controlled by TinyBrick Performance products. If you've never used the cache control page, try here. Also, I might be able to offer a parallel to help.

While the checkboxes (like a sink faucet) may turn off and on the flow of water, the sink holds cached pages, blocks, etc...(water) that was generated while caching was enabled (faucet was on). While unchecking a box (and then saving) may turn off the faucet, to empty the sink (prevent the website from loading cached pages, blocks, etc...) you'll need to refresh the cache (empty the sink). This is typically done by using the drop-down at the top left. Setting it to refresh, and then saving the page.

On a default magento/Warp installation, the ideal running state is to have all the caching component checked. However, if you have other caching component installed, they may not be checked.

Testing

Now that you've implemented Warp caching, you probably want to see some results. You should be able to see an immediate speed increase just by browsing your site. If you need the exact figures, we recommend using a tool like the Firebug plug-in for Firefox to assist. This article should have some more suggestions on how to get those numbers.

If you don't see a performance increase, you may have missed something. To make sure, Warp has built-in debug tools that tells you everything it's doing on a particular page. To use it, you'll just need to add the following to the end of your URL:

  • debug_back=1 (e.g. - http://www.mysite.com/?debug_back=1)
  • debug_front=1 (e.g. - http://www.mysite.com/?debug_front=1)

?debug_back=1

After adding "/?debug_back=1" to the end of any url you should no longer see your site, but instead plain text telling you if Warp is trying to save the page to cache.

If you see something other than this, you may need to clear your cache. If you get "invalid registration", you may need to review your license credentials in the Magento admin panel. If you get "this page is not set to be cached according to the layout", the xml code snippet may not be applied correctly to the appropriate layout file.

?debug_front=1

After adding "/?debug_front=1" to the end of any url you should no longer see your site, but instead plain text telling you if Warp is serving a cached page.

If you see a message similar to this, Warp is working correctly. However, if you get another message, refer the particular area it states as an issue and double check that you've done everything correctly. Unless you're a magento pro, mistakes can happen (and even then). This tool should help you understand what's going wrong.

It may not give super long error messages, but they should be descriptive enough to get you going in the right direction.

That’s it! You have just decreased page response times to around 100–200 milliseconds for most of your users. That said, you should still read on so you can provide a fully optimized experience for all users including logged in users and users with an active cart.

Configuration - Full - AJAX hole Punching

So you want AJAX Hole Punching? Warp gives it to you with ready to use javascript and hole punching in the Index Controller. We make it easy. We grab all the information by default and save it into localStorage.

What is localStorage

localStorage is also known as HTML5 Web Storage. It stores data in your local browser. This has many advantages as it can speed up your site so you are not contstantly grabing the data from the server. We use localStorage with AJAX to overlay your data with the new data.

Warning: Programmers Only

"Full customization" is code "not intended for non-programmers." If you're not a programmer, or not interested in becoming one, this configuration option may not be for you. And if you are, let me tell you from experience that it may be an easier task for programmers familiar with the inner workings of Magento. Not saying that you won't figure it out, but our experience has been that Warp full configuration can take an experienced magento programmer a few hours to accomplish. It would be better for you to make the right decision about which configuration to use NOW, instead of hours and headaches later. On the other hand, don't let me scare you. If you have some time to burn and want give it a try, feel free. Just don't say I didn't warn you if you can't figure it out.

Enabling AJAX Hole Punching

The first thing you will need to do is enable Hole Punching on all of your pages. We already include the js files you will need (js/warp) in order to do the Hole Punching, but you will need to tell your page what function to run. We typically place this in your template/page/html/header.phtml file.

Javascript Adding Javascript to a template file

< script>document.onload = runPunch();< /script>

We provide sample code inside the js/warp/warp.js file. Below, we explain what each piece does.

JS runEnabled() function (main function)

runEnabled();

runEnabled() will run every enabled hole punch from the backend

JS runLogOut() function (Top Links Hole Punch function)

var tlc = JSON.parse(localStorage.getItem('topLinksCss'));

This grabs the topLinksCss from the localStorage. if(localStorage.getItem('loggedin') == 1){
runLogOut(tlc.loginlink, tlc.logoutlink, tlc.logoutcss);
This function is run if loggedin = 1 (1 for yes, 0 for no). }

function runLogOut(loginlink, logoutlink, logoutcss){
jQuery(logoutcss).text('Log Out');
jQuery('a[href$="'+loginlink+'"]').attr('href',logoutlink);
the jquery above will find the login link and chang it to the logout link. }

This is the javascript portion. You can do this for each hole punch you want. The jQuery places the data where it needs to be so you need to be familiar with javascript and jQuery.

PHP HoleController.php

public function topLinks(){
// get total items in cart
$cart = Mage::helper('checkout/cart')->getQuote()->getData();
$cartTotal = (int)$cart['items_qty'];

// check if logged in
if(Mage::helper('customer')->isLoggedIn() == 1){

$loggedin = 1;

$firstName = Mage::getSingleton('customer/session')->getCustomer()->getFirstname();
$lastName = Mage::getSingleton('customer/session')->getCustomer()->getLastname();

if(!$firstName || !$lastName){
$welcome = Mage::getStoreConfig('design/header/welcome');
}else{
$welcome = 'Welcome, ' . $firstName . ' ' . $lastName . '!';
}
}else{
$welcome = Mage::getStoreConfig('design/header/welcome');
}

// This will grab all of the css info from backend
$configTopLinks = Mage::getStoreConfig('punch/toplinks');

return $newObject = array(
"cartTotal" => $cartTotal,
"welcome" => $welcome,
"loggedin" => $loggedin,
"topLinksCss" => $configTopLinks,
);
}

If you understand all of this, then you should be fine creat an AJAX hole punch. Good luck!

Configuration - Full (Optional)

So you want more do you? Well, Warp is ready to give. To take advantage of this power, it has to be customized to your site. You have dynamic content here or there. Well, that's great, but the next 5 people put that dynamic content in a completely different place. For that reason, full configuration is meant only for full customization. Here we go!

Warning: Programmers Only

"Full customization" is code "not intended for non-programmers." If you're not a programmer, or not interested in becoming one, this configuration option may not be for you. And if you are, let me tell you from experience that it may be an easier task for programmers familiar with the inner workings of Magento. Not saying that you won't figure it out, but our experience has been that Warp full configuration can take an experienced magento programmer a few hours to accomplish. It would be better for you to make the right decision about which configuration to use NOW, instead of hours and headaches later. On the other hand, don't let me scare you. If you have some time to burn and want give it a try, feel free. Just don't say I didn't warn you if you can't figure it out.

Pages

The first thing you need to do to configure Warp is determine which pages you would like to be cached. Literally any page can be cached. Setting a page to be cached is a matter of calling the cachePage() method of the root block, which is added during installation (an instance of TinyBrick_Warp_Block_Page_Html). cachePage() accepts three optional arguments:

  1. The first is an integer argument that represents the time in seconds before the cached page should expire. If no expire time is set, the cached page will never expire unless memcache is restarted or needs to make room for newer data.
  2. The second argument is a comma-separated list of disqualifiers. These disqualifiers will disqualify users that match the listed criteria from receiving cached pages.
  3. The third argument is a path that will retrieve the content to fill the holes punched in the cached page. This allows disqualified users to still get a cached page, but with fresh dynamic content only where necessary.

cachePage() may be called either from a layout or from a block. It is recommended that it be called from a layout.

As Magento loads the various blocks and layouts that make up a page, every block gets an opportunity to indicate that the page being loaded should be cached. If any block on the page calls cachePage() on the root block, that entire page will be cached. For that reason, you should call cachePage() as high up in the layout / block hierarchy as possible to avoid any accidental caching.

Pages Adding Caching to a Layout

<reference name="root">
    <action method="cachePage">
        <!-- Expire time (seconds) -->
        <expires></expires>
        <!-- Turns off LS under these conditions -->
        <disqualifiers>cart,loggedin,compare</disqualifiers>
        <!-- Path to dynamic content for page -->
        <holecontent>module/controller/action</holecontent>
    </action>
</reference>

The <expires> tag can be left empty (<expires></expires>) to indicate that the page should only be expired when one of its tags is flushed from the cache. In this example, this page will be served entirely from the cache if the visitor does not have items in their shopping cart and if they are not logged in. In the event that a user has items in their shopping cart or is logged in, they will still get served a cached page, but certain pieces of the page will be replaced with fresh content. In this event, the request into Magento to get the fresh content can be minimal, allowing the response to be very fast and very light on the application.

Good to know...

<expires>, <holecontent> and <disqualifiers> are optional arguments.

Hole Punching

Hole punching is used by Warp to retrieve pieces of dynamic content on a cached page. For example, most sites have a top bar that may have the visitor’s name if they are logged in and the number of items in their shopping cart. A lot of sites will also have a “Recently Viewed” section that is different for every visitor.

Hole punches are triggered from template files (.phtml) by implementing the following snippets, in the form of HTML comment blocks:

HTML Punching A Hole

<!-- NOCACHE key="unique_key" -->
    <div>
        Your display code replaced after a page cache hit.
    </div>
<!-- ENDNOCACHE -->

As declared previously, the third argument to the cachePage() function declares a route where the content for the NOCACHE holes can be requested. This route is expected to have content for all of the holes for that page. The route is just like any other route within Magento. The route: module/controller/action would expect a Magento module, a Controller, and an Action method that you specify. You'll have to create this path. If you need help with this, then you'll need to study up on how to create a module according to magento standards or add an action to an already existing controller.

Here's an example of one such controller:

PHP An Example Controller Action (For Filling a Punch)

class Namespace_Module_TestController extends Mage_Core_Controller_Front_Action {
    public function HoleContentAction() {
        $content = array( 'hole1' => 'html content'
            ,'hole2' => 'more html content'
            ,'hole3' => $this->getLayout()->createBlock('core/template')->setTemplate('template.phtml')->toHtml()
            );
        echo Zend_Json::encode($content);
    }
}

As shown in the previous example, there are a couple of conventions:

  1. The response to be echoed must be an array encoded in JSON.
  2. The array is a key value registry, where the key will match the key declared in the NOCACHE punch, and the value is the html content that will fill NOCACHE punch with content.

Your primary task here, is to make this request as light as possible. The lighter and smaller you can make this request, the better your application will scale as the heaviest pieces of the page will be cached already.

Is All This Hole-Punching Business Confusing?

You're not alone. Warp (and especially Hole-Punching) is complicated. However, it overcomes a major performance issue in Magneto. That doesn't come without some work and as such, full configuration like this can require some experience to leverage well. quick configuration works well for many happy Warp customers out there.

Disqualifiers

Disqualifiers represent visitor states that disqualify a user from getting an entire cached page or prevents Warp from creating a cached page in the event that no page cache exists yet.

There are only four disqualifiers at the time of this writing: *, cart, loggedin, and compare.

  • "*" - Signifies that every visitor is disqualified for a completely cached page. This could be useful on pages with recently viewed products, that needs to be unique for each visitor.
  • "cart" - Represents a state where a visitor has at least one item in their shopping cart.
  • "loggedin" - Represents a state where the visitor has logged in.
  • "compare" - Represents a state where the visitor has add a product to the compare. (Added in Lightspeed Version 2.10)

Tagging

Tagging within Warp is extremely simple. Warp will aggregate all of the tags for every block used within that page, and associate them with the cached page. An expired tag on any block on that page will also clear the cached page. A tutorial on how to implement block level cache tagging is out of the scope of this documentation, but more information can be found here.

That's the tour. Enjoy Warp page performance!

Known Limitations

  • Magento Connect - Because warp.php replaces the index.php file, you may just see a list of files when you try to access Magento Connect from the admin panel. A temporary work around is to simply, click the index.php file in the list. A permanent solution could be to write a conditional statement in the .htaccess file to always use index.php when in the admin or when accessing Magento Connect.
  • Compilation - Warp is not currently compatible with Magento's compilation. In order to install Warp, please disable Compilation.