Time to break down 🕺 -- Edge. What do we mean when we say it's faster and closer to the user?
Let's put it simply: Every user who visits a website receives a response from a computer somewhere on the Internet. When that happens, a machine is used to:
- Process the request,
- Check what the client expects and
- Send the most accurate response
But that process can be slow. Especially if the server is located in a different city. Or a different country. Or in a different continent.
And we can all agree that slow is annoying. We don't want slow.
To make it faster, it would be great to have something in between. Something closer to the end-user. Fast, reliable and distributed. What if we create a network of servers around the globe? A CDN.
When you type an address and hit enter, the CDN instantly sends the content to the user. Since it doesn't have to travel far, it’s very close to the user -- a new neighbor. Usually in the same city or country.
And how is that content sent to the user? Let's find out.
What are the differences between static and dynamic websites?
I’m going to discuss three different approaches to send content to the user. Yes, there are also some other, more complicated scenarios, but I just want to give you a quick overview.
The first one is a classic server.
[@portabletext/react] Unknown block type "break", specify a component for it in the `components.types` prop
Scenario 1: Dynamic single server distribution
This is when you have a server in a single location. Users can be from all over the world. And... the good part is that the response can be customized for every user.
[@portabletext/react] Unknown block type "singleServer", specify a component for it in the `components.types` prop
Let's peek into the interaction 👀:
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "break", specify a component for it in the `components.types` prop
Scenario 2: Static CDN
This time, the content is served from distributed servers that are located in strategic locations all over the world. The biggest networks have hundreds of data centers. That means, if a user is from the United States, they will connect to the closest data center available following the user's request data. -- by the way, you connected to New York Cloudflare's data center.
[@portabletext/react] Unknown block type "cdnServer", specify a component for it in the `components.types` prop
The issue is, the content for every user is the same. You can’t modify it based on the response on the CDN. You can do some redirections or bypass the request to the origin server, but that’s slow. The response won’t be from cache.
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "break", specify a component for it in the `components.types` prop
Scenario 3: Edge
What if we can merge those two approaches? A server, but on the distributed CDN. Here's where the Edge shines through.
[@portabletext/react] Unknown block type "edgeServer", specify a component for it in the `components.types` prop
Similar to CDN, it’s located in strategic locations around the globe. But it can execute the code too. This means that you can do a lot of interesting things like:
- personalize the response,
- modify the content,
- authorize the user.
All of it without sacrificing performance.
Here's how it works:
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "message", specify a component for it in the `components.types` prop
No pain -- no wait -- right next to the user.
[@portabletext/react] Unknown block type "break", specify a component for it in the `components.types` prop
Workers, handlers or just functions?
Each top cloud provider has a different approach and name. But the main idea is similar: To run code at the edge with close to zero latency.
Cloudflare launched Workers in 2017, changing the game in the edge atmosphere. Edge became available and affordable for everyone, so you no longer have to be a big enterprise with a custom infrastructure.
Continuing the trend, Netlify announced a similar concept called Edge Handlers in 2020. It’s still in the early access stage. As Netlify Partners, we do have access. We tested Handlers and we can tell you: they look very promising!
In October 2021, Vercel announced that Edge Functions are coming to their cloud platform. Vercel built them on top of existing Cloudflare Workers infrastructure. Along with functions, they introduced Middlewares for Next.js which is an easy way of using Edge together with Next.
They took what’s best in the edge world and implemented it in both Next.js and Vercel. That combo makes it very easy to unleash the full potential of edge for developers.
Edge Use Cases
Even though it is powerful, Edge is not as versatile as classic servers (Node.js or others). Some of Edge's use cases include:
- A/B testing: You can split traffic across different variants or pages. Or modify the content directly at the edge. To learn more, read our case study: Optimizing DrSmile's Website to Allow for Lightning Fast Experiments at the Edge. There, we explained how we used Optimizely, Cloudflare Workers and Gatsby to make an extremely fast A/B testing experience.
- Personalization: Serve a custom content for every user based on multiple variables.
- Improving security: Send custom headers, block traffic from specific regions, make an auth-gate, rate-limit an API, show a captcha for suspicious requests.
- Authentication: You can authorize the user directly at the edge. Unauthorized requests can be redirected to the login page. No more loading spinners on client-side.
- Data storage: Some providers like Cloudflare offer a simple, low latency key-value (KV) data store. You can build an API that responds as quickly as a static file served from CDN.
Personalization at the edge
Edge is the infrastructure that allows to set up a personalized experience for every user. Because of these possibilities, there are new emerging tools that help to manage all of it. Some examples are the following:
- Uniform, a San Francisco-based startup that connects headless CMS like Contentful or Sanity with commerce engines and CDN. It’s a great tool to create variants, compose content and manage testing experiments.
- ninetailed, a Berlin-based startup. They focus on creating an API-first approach but with great UX for content editors and marketers. So far there is an integration with Contentful and react-based frameworks like Gatsby or Next.js.
How we use edge functions on the Bejamas website?
We’ve been using Cloudflare Workers for a couple of years. Here are some interesting things we developed with it:
- Theme switcher. We have light and dark theme, and we can switch between them. We store the selected theme in the cookie and serve the content from the edge based on this. We removed the flash of default theme before client-side JS is loaded. It means theme switching works even without JS enabled. You can try this by adding a param to the URL:
?theme=dark
or ?theme=light
. - Critical CSS. If you visit our website for the first time, you will have an inlined, critical CSS in the head. Later, when the client is ready we fetch the rest of the CSS and cache it. Then, we save the CSS ID in the cookie. If you visit our website for the second time, we won't send you the inlined critical CSS again. You already have the full CSS in the cache. We can use it.
- Proxy third-party JS. We use a couple of scripts like Google Analytics or Twitter Analytics. All of those have their own domain. To save a few unnecessary round-trips, we proxy them. An example link to Google Analytics is: https://bejamas.io/www.google-analytics.com/analytics.js?cf_hash=443c6ec0d05fb4b8f258a5b405e2f1e88c57bd3f
- Geo-location based cookie banner. Some countries require an accept for cookies. Some don't. We show the top bar based on user's location.
- This blog post. We inserted origin country of your request and the data center you connected to. It's New York.
[@portabletext/react] Unknown block type "break", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "break", specify a component for it in the `components.types` prop
We have the tools. And we have the knowledge. We can make the static dynamic. With no sacrificing performance.
Need help with your website or an app? Let’s get in touch!
CLICK HERE to schedule a 1-on-1 talk and learn more about what we can do for you and your business.