Why speed matters
Speed affects the user.
- Users first perceive delays over 100 ms;
- Beyond 1,000 ms, they tend to lose focus on the task they are performing;
- Beyond 10,000 ms, they tend to abandon the task altogether.
Speed affects your SEO.
- Google uses speed as a ranking factor.
Speed affects the business.
- About 10 years ago, a study was done that showed that every 100 ms of latency cost Amazon 1% in sales.
Rendering strategies that improve speed
No pre-rendering
Your HTML and javascript is downloaded; you essentially have a blank page before your browser animates anything.
With pre-rendering
Your HTML is fully formed before hitting the browser and then the javascript is activated.
Two pre-rendering strategies are:
- Static site generation (SSG): This refers to rendering at build time, i.e. everything is fully formed. Use SSG whenever possible, including marketing pages, blogs, and e-commerce product listings.
- Server-side rendering (SSR): HTML is generated at request time. We have a server, and when somebody asks for the page, the HTML is generated and sent down to them. Use SSR if you cannot pre-render ahead of a user’s request for things like account pages, or where the user requires frequently updated data.
The problem with using Angular to pre-render
Unfortunately, there is no Next.js equivalent for Angular. To build an SSG/SSR web application with Angular from scratch requires careful consideration of how to implement pre-rendering and server-side rendering and how to instruct the framework to choose between the two when necessary. Additionally, since the rendering occurs on the server, there are complexities involved in writing API routes to handle the data retrieval process.
As a result, the developer experience is so awful that many Angular developers have turned to Next.js for applications that require SSR or SSG.
Analog
Analog is a full-stack meta-framework for building applications and websites with Angular. It supports both SSR and SSG rendering. It also uses file-based routing and supports API (server) routes. Analog does a lot of the grunt work for you, making your work as a developer much easier.
Analog provides a scaffold. By running an npm or yarn command, it sets up a standard Angular application with the necessary server components already configured. You basically get what you would get within Angular CLI but it’s ready to do a lot of the heavy lifting that would be difficult to do with Angular Universal.
One of the notable features of Analog is the way you define paths or URLs for navigable pages. Analog takes control of the routing for you, which is crucial.The file path becomes the corresponding URL. This structure also allows for nested routes – simply create a folder.
Similar to Next.js, Analog is able to do dynamic routing. Dynamic routes are defined by using the filename as the route path enclosed in square brackets. The parameter for the route is extracted from the route path. This can be used to fetch the corresponding data from a database or CMS and render it dynamically on the page. This approach allows you to create dynamic systems that work seamlessly from both server-side and static site perspectives.
Additionally, there's a `server` folder where you can create APIs to fetch data. API routes are simple TypeScript files defined in the src/server/routes folder. When you deploy your application, both your APIs and pages will be deployed together.
Once you have a page, it looks like a standard Angular component. This is a familiar page structure that you may have created numerous times before. Simply by placing it under the `src/app/pages` directory, it is now server-side rendered by default. There is no additional configuration required. This is the smooth developer experience we've been highlighting. In a way, it resembles building HTML or PHP sites, but with the advantage of leveraging Angular.
Once you have Analog set up, the rest of your application will largely remain the same.
An API route is similar to writing a serverless function. For instance, Lambda is a simple TypeScript file that you export. By placing this TypeScript file in the `server/routes` directory, you not only enable server-side rendering but also provide API routes that your server-side rendered pages can access to retrieve data to render.
Finally, if everything is SSR by default, how do you get SSG?
The answer lies in the vite.config.js file. Inside this file, you can define the routes that you want to be pre-rendered as static pages. Instead of being server-side generated, these routes will be statically generated during the build process. You can specify routes like the about page, the root of the blog, or even individual blog posts to be statically generated. Any pages not listed in this configuration will be server-side rendered.
How to dynamically specify components to render?
So how do we dynamically specify which components to render?
Content isn’t always added at the build of an application. A typical scenario is when content creators need to add or update content. So, to be able to pre-render this, we would need a second manual step to update the app, load the data, and render it.
Historically, if we wanted content dynamically updating, this would have been done through the client making the request to the server. However, this is not as performant as pre-rendered sites.
Analog does a lot of the heavy lifting here. It can get the data from the CMS, and use that to define what will be pre-rendered on pages, but it doesn’t align with dynamically specifying which components to render.
Enter Contentful.
Essentially, we want components that are mapped to CMS pieces.
At [13:00] in the webinar, Robyn demonstrates the flow of how data would enter the application and how that can be used to create these dynamically rendered components. The key lies in the RenderTemplateComponent.
Basically, we’re getting data from our CMS, compiling that data into the shape that we want, and passing that with the injectLoad[] function into our build component file. We take those build components and map each node to a component and place it in the right spot. This gives us a fully dynamic page.
To learn more about how to render dynamic components in Angular, see our blog post.
Build a dynamic site with Contentful
At [15:00], Robyn demonstrates how straightforward it is to build a page in Contentful.
With the help of Analog automating a very complicated process in Angular, plus the flexibility of a CMS like Contentful, a content creator is able to come in and dynamically render content right away without having to rely on a developer.