This guide describes how to get up and running with Edgio for traditional, multi-page applications. Edgio can enable traditional websites (e.g. jQuery, PHP, VanillaJS, etc.) to take advantage of the performance benefits of advanced caching and predictive prefetching. If your website is built on a modern framework such as React, Angular, or Vue, we recommend considering our framework-specific guides.
Note that the speed benefit for traditional sites from Edgio is dependent on the site’s JavaScript usage during the page load. If a page has JavaScript heavy processing during load it may reduce the benefit from Edgio. Contact your account manager or our sales department at 1 (866) 200 - 5463 to request site analysis prior to installation. Our typical turnaround time is 1 to 2 business days.
How Edgio for Traditional Sites Works
As shown below, Edgio becomes the main CDN for your site:
Requests for your site will now pass through Edgio’s globally distributed network of computers and then to your server. Your site’s main domain, such as
www.site.com
now points to Edgio, and your original server now responds to a new domain such as origin.site.com
that Edgio will use for fetching your page data. Note that origin.site.com
in this example is hidden from users; users continue to access your site transparently from your original domain www.site.com
.Edgio will do two things that accelerate your pages:
- Globally distributed caching: Pages and content that are in Edgio cache will be returned to the user faster than being fetched from your server.
- Predictive prefetching: Edgio predictively prefetch and serve data to the device before the user even requests it. By effectively streaming page data to the device a few seconds ahead of the shopper, the page load becomes instantaneous because there is no network to wait for. Normally the increased traffic from this kind of data streaming would overload your server, but Edgio’s caching layer acts as a “shield” to protect your origin for this load.
Implementation Process
The high level implementation process for Edgio is:
- Make sure your pages are cacheable
- Set up a project
- Configure caching and prefetching
- Test locally and on Edgio
- Go live by changing the DNS
We highly recommend performing this process on a staging server before attempting to try it on your production website.
Make Sure Your Pages are Cacheable
Edgio will only prefetch and accelerate pages that are cacheable, i.e. do not have user specific content. The good news is that most pages can be made cacheable with only a few adjustments. Let’s walk through an example.
Consider the ecommerce page shown above. Most of the content on this page such as the main hero image, the menu items, the company logo, and more are not user specific. However, the badge indicating the number of items in the cart is specific to that user browsing the page. The cart count can’t be stored in the cache otherwise, every user would get a page with the same cart count. However to make this page cacheable we can simply remove the user specific parts and “late load” them with JavaScript. In this case, we could change the page so that the cart count is empty in the page HTML and let JavaScript on the page fetch the cart count and update the page HTML after it loads. This strategy of late load is fairly universal and you may want to delegate all the user specific content to a single late load request that is made by JavaScript on your page.
Here are some of common types of page content that may need this approach:
- Badges indicating the number of items in cart or bag
- Text or buttons dependent on the username or login status (e.g. “Login”, or “Welcome Bob”)
- Segmented or personalized content such as recommended products based on the user’s profile or browsing behavior (note that recommended products based on page data are cacheable because the same recommended product would be shown to all users).
- User specific parameters for analytics (e.g. if analytics tracks users by their userid or how frequently they visit the site).
See common things you need to look for on an eCommmerce site:
Non-cacheable content | How to Change | Location |
---|---|---|
Cart item count | Late load via API | Global |
Welcome message | Late load | Global |
Localized currency | Split cache based on cookie | Global |
Inline analytics | Refactor | Global |
Personalized banners | Late load | Homepage |
Promo pricing | Late load | PLP |
Complex pricing (e.g. employee discounts, affiliate discounts, pricing based on item combinations or dollar amount in the cart) | Late load | PLP, PDP |
Inventory | Lower cache TTL | PLP |
Product recommendations | Late load | PDP |
Inventory | Targeted cache clearing | PDP |
Connector
This framework has a connector developed for Edgio. See Connectors for more information.
Prerequisites
Setup requires:
- An Edgio account. Sign up for free.
- An Edgio property. Learn how to create a property.
- Node.js. View supported versions and installation steps.
- Edgio CLI.
Install the Edgio CLI
If you have not already done so, install the Edgio CLI.
Bash
1npm i -g @edgio/cli@^6.0.0
Setup a Project
Create a project through the following command:
Bash
1npx @edgio/cli@^6.0.0 init \2 --edgioVersion ^6.0.0 \3 --name <DOMAIN> \4 --environment default \5 --origin <DOMAIN> \6 --deploy
Replace
<DOMAIN>
with your website’s domain when running the above command.If possible, try to run the above command from your website’s root directory.
Project Structure
Before we get started, you should familiarize yourself with some of the key files in the Edgio project:
service-worker.ts
: Is run on the browser. The service worker is able to prefetch content (main product image, scripts, fonts, links, etc. as defined here) from within the potential next page’s document. We call this method “deepfetching”. This file is where deepfetching rules are defined: the selector, how many elements, which attribute to fetch, resource type, and an optional callback function for more complex fetches (as shown in the example). Here’s more detailed info about deepfetching.shoppingFlowRouteHandler.ts
: Is run on Edgio. It’s where the caching rules get implemented, as well as where the modifications to be made to the requests and/or responses to support caching of dynamic content are defined.cache.ts
: This is where the caching rules are defined for both Edgio (edge) and the browser.routes.ts
: This is where the routes to be cached and prefetched are defined, as well as what to pass through without modification and what to serve up as static content.browser.ts
: This is the entry point for themain.js
javascript bundle which is added to the window.
Configure Caching and Prefetching
Next we need to configure the caching in our newly created project. To do so, add a route for each URL you want to cache to the
routes.ts
file. For example, consider a site where the homepage (/
), category pages (/category/xxxx
), and product pages (/product/yyyy
) are to be cached. Then your routes.ts
file would look like:TypeScript
1// routes.ts2import {Router} from '@edgio/core/router';3import shoppingFlowRouteHandler from './shoppingFlowRouteHandler';45export default new Router()6 .get('/', shoppingFlowRouteHandler)7 .get('/collections/*path', shoppingFlowRouteHandler)8 .get('/products/*path', shoppingFlowRouteHandler);
TypeScript
1// shoppingFlowRouteHandler.ts2import {CACHE_PAGES} from './cache';3import {RouteHandler} from '@edgio/core/router/Router';45const handler: RouteHandler = async ({cache, removeResponseHeader, proxy}) => {6 cache(CACHE_PAGES);7 removeUpstreamResponseHeader('set-cookie'); // The presence of a set-cookie header would prevent the response from being cached, so ensure set-cookie headers are removed.8 proxy('origin');9};1011export default handler;
TypeScript
1// cache.ts2const ONE_HOUR = 60 * 60;3const ONE_DAY = 24 * ONE_HOUR;4const ONE_YEAR = 365 * ONE_DAY;56/**7 * The default cache setting for pages in the shopping flow8 */9export const CACHE_PAGES = {10 edge: {11 maxAgeSeconds: ONE_HOUR,12 },13 browser: {14 maxAgeSeconds: 0,15 serviceWorkerSeconds: ONE_HOUR,16 },17};
In addition to configuring your caching in
routes.ts
as shown above, you may need to employ advanced prefetching techniques to achieve the best possible performanceUnderstanding Caching and Prefetching
By injecting
main.js
into your app’s front-end code, your app will automatically prefetch all visible HTML links with URLs that match a route configured with edge.maxAgeSeconds
and browser.serviceWorkerSeconds
(in essence, when you configure a route to be cached, you are also declaring it to be a candidate for prefetching as well). Links that are visible when the page first loads are fetched immediately. Additional links will be fetched when the user scrolls down the page and more links become visible.Prefetching can generate substantial additional network traffic. Edgio automatically shields your origin from this additional traffic by only serving prefetch requests from the edge cache. If a prefetch request cannot be served from the cache, Edgio will return an HTTP 412 status and the request will not be proxied to the origin. When this happens, the only effect for the user is that they will not see the speed benefit of prefetching. Therefore, the effectiveness of prefetching ramps up over time as users visit pages throughout your site. When the edge cache is cleared, either through the Edgio Developer console or automatically following a deployment, the speed benefit of prefetching is decreased until the cache fills up based on organic traffic.
Test Your Code Locally and on Edgio
Now that you’ve configured your caching in
routes.ts
, you should test it in your local development environment and on Edgio.Running Locally
To test the caching behavior locally, run your project with the local cache option as shown below:
Bash
1edgio dev --cache
Running on Edgio
Now that you’re satisfied with your site in local development, it’s time to deploy it to Edgio Cloud. Once your code is deployed to Edgio Cloud, you can formally evaluate site performance and QA functionality.
Deploy the build to Edgio by running the
edgio deploy
command:Bash
1edg deploy --team=<TEAM>
Consult the Deployment guide for more information on the options for deploying your site.
Go Live by Changing the DNS
After you’ve configured and tested your site on Edgio, it’s time to take it live. At a high level, the process is:
- Specify the domain name of the site under the Configuration tab for the environment in the Edgio Developer console.
- Configure your SSL certificate under the Configuration tab for the environment in the Edgio Developer console.
- Create a CNAME record with your DNS provider with the value shown under the Domains section for the environment in the Edgio Developer console.
The third step (configuring your DNS) will be the crucial step that effectively transitions your domain to Edgio and should be done last.
Before going live, you should use the Edgio Onboarding Discovery Worksheet to help you think through common use cases and concerns and ensure a smooth launch.
Advanced Prefetching Techniques
An introduction to prefetching is available in the Prefetching guide. In addition, here are some techniques to take full advantage of the power of prefetching.
Deep Fetching
Deep fetching is an important technique for Edgio projects. By default, only HTML content is prefetched. In order to achieve truly instant page transitions, all of the assets needed to render the content that appears above the fold needs to be deep fetched. Refer to the Deep Fetching section of the Prefetching guide for more details on how to configure deep fetching in your project.
Prefetching POSTs
Most assets that need to be prefetched are HTTP
GET
requests. It is also possible to prefetch POST
requests with some additional configuration.When your app prefetches assets, the actual prefetch request is always a
GET
, so you need to make sure that your router is configured to respond to GET
requests for any POST
URL. In order to ensure that the response is cached as a POST
by the service worker, you need to specify convertToGet: true
in the cache config for the prefetch route handler, and to also use the transformMethod
function to properly transform the GET
request into a POST
on the server:JavaScript
1import {transformMethod} from '@edgio/core/transform';23const postCacheConfig = {4 edge: {5 maxAgeSeconds: 60 * 60 * 24,6 staleWhileRevalidateSeconds: 60 * 60,7 },8 browser: {9 serviceWorkerSeconds: 60 * 60 * 24,10 convertToGet: true,11 },12};1314export default new Router()15 // When the request is a GET, convert it to post using serverless compute and cache the result16 .get('/some-post-path', ({cache, proxy}) => {17 cache(postCacheConfig);18 proxy('origin', {19 transformRequest: transformMethod('post'),20 });21 })22 // When the request is a POST, forward it to origin from the edge without using serverless compute23 .post('/some-post-path', ({cache, proxy}) => {24 cache(postCacheConfig);25 proxy('origin');26 });
Prefetching based on Element Visibility
By default,
<a>
tags are watched by the Prefetcher so that the value of their href
attributes are prefetched once the links become visible in the viewport. However, sometimes you might need to trigger a prefetch based on the visibility of other types of elements.When installing the service worker, you can specify a
watch
list. Elements that match watch
selectors can trigger a callback function when they become visible in the viewport:JavaScript
1import {install, prefetch} from '@edgio/prefetch/window';23document.addEventListener('DOMContentLoaded', function () {4 install({5 // If you don't have links specified with a `<a>` tags with `href` attributes, you can also6 // specify watchers to prefetch when other elements are added to the page:7 watch: [8 {9 selector: 'div.product-tile',10 callback: (el) => {11 const productId = el.getAttribute('data-product-id');12 const catId = document13 .getElementById('cat-listing')14 .getAttribute('data-category-id');15 prefetch(`/api/${catId}/${productId}`, 'fetch');16 },17 },18 ],19 });20});
Maintenance
For the most part maintenance for traditional sites running on Edgio is minimal. However, the typical scenarios that require changes are:
- If you add personalized or user-specific content to the page you will need to make sure it is late loaded as described in the Make sure your pages are cacheable section.
- If you introduce a new segmentation of content (e.g. support a new language or currency), you may need to update your custom cache key.
- If you change the layout of the page (especially above the fold), it may alter the assets you need to prefetch or deepfetch to achieve the best performance.