{"id":761,"date":"2023-08-04T12:23:00","date_gmt":"2023-08-04T12:23:00","guid":{"rendered":"https:\/\/staging.infragistics.com\/blogs\/?p=761"},"modified":"2025-02-18T14:18:59","modified_gmt":"2025-02-18T14:18:59","slug":"improve-performance-of-angular-apps","status":"publish","type":"post","link":"https:\/\/www.infragistics.com\/blogs\/improve-performance-of-angular-apps","title":{"rendered":"How To Improve the Performance of Angular Apps?"},"content":{"rendered":"\n<p>Angular has become a very popular and widely adopted framework for developing modern web applications. This technology is both very powerful and feature-rich. Everything that you need as a web developer comes out-of-the-box and Angular allows for easily configuring, maintaining, and expanding any application built on top of the framework.&nbsp;&nbsp;<\/p>\n\n\n\n<p>And by now, you\u2019ve probably already put together one or more Angular applications, but are they optimal?&nbsp;&nbsp;<\/p>\n\n\n\n<p>In Part 2 of my Software Performance series, then, I will talk about Angular optimization, demonstrating how to improve the performance of an Angular application using an Angular example app that I built. I will use Chrome Dev Tools to derive an initial lighthouse score to determine where the application initially stands.&nbsp;Let\u2019s take a look at what can be improved and how.&nbsp;<\/p>\n\n\n\n<p>Other blogs from this series:<\/p>\n\n\n\n<p><a href=\"https:\/\/medium.com\/ignite-ui\/software-performance-web-61158c8583d\" rel=\"noopener\">Software Performance [Web]<\/a> Part I<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"how-to-improve-angular-apps-performance\">How to Improve The Performance of Angular Applications<\/h2>\n\n\n\n<p>For this article, I will use a sample Angular application that I\u2019ve put together. At the time of writing this article, the application uses the following features and libraries:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list postList\">\n<li>Angular 16<\/li>\n\n\n\n<li>Ignite UI for Angular 16<\/li>\n\n\n\n<li>RxJS 7<\/li>\n\n\n\n<li>PWA (Angular service worker)<\/li>\n\n\n\n<li>Server-side rendering (express server)<\/li>\n\n\n\n<li>Angular localization<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading graf graf--h4\" id=\"angular-build\">Angular Build<\/h3>\n\n\n\n<p class=\"graf graf--p\">Everything seems to be running just fine when I\u2019m running the application in a development environment, but the initial lighthouse score is not very high:<\/p>\n\n\n\n<figure class=\"wp-block-image graf graf--figure\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/3718.pastedimage1690979018205v1.png\" alt=\" Lighthouse score with development environment run\"\/><\/figure>\n\n\n\n<p class=\"graf graf--p\"><span class=\"TextRun SCXW93419127 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW93419127 BCX0\">When I <\/span><span class=\"NormalTextRun SCXW93419127 BCX0\">look<\/span><span class=\"NormalTextRun SCXW93419127 BCX0\"> at the suggestions for improving the lower-scoring sections<\/span><span class=\"NormalTextRun SCXW93419127 BCX0\">, I see where the issues are coming from<\/span><span class=\"NormalTextRun SCXW93419127 BCX0\">.<\/span> <\/span><span class=\"TextRun SCXW93419127 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW93419127 BCX0\">T<\/span><span class=\"NormalTextRun SCXW93419127 BCX0\">he first big issue is the size of the resources (JavaScript, styles, static resources) that are transferred to the client.<\/span><\/span><span class=\"EOP SCXW93419127 BCX0\">&nbsp;<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image graf graf--figure\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/2251.pastedimage1690979018205v2.png\" alt=\" Opportunities for improving performance of the Angular\u00a0app\"\/><\/figure>\n\n\n\n<p class=\"graf graf--p\">T<span class=\"TextRun SCXW30070099 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW30070099 BCX0\">his issue is resolved easily by running a production build of my Angular application rather than a development one.\u202fAlways build with production configuration prior to deployment. This will resolve the warning to reduce the size of <\/span><span class=\"NormalTextRun SCXW30070099 BCX0\">JavaScript<\/span><span class=\"NormalTextRun SCXW30070099 BCX0\"> and <\/span><span class=\"NormalTextRun SCXW30070099 BCX0\">CSS<\/span><span class=\"NormalTextRun SCXW30070099 BCX0\">. <\/span><span class=\"NormalTextRun SCXW30070099 BCX0\">Let\u2019s<\/span> <span class=\"NormalTextRun AdvancedProofingIssueV2Themed SCXW30070099 BCX0\">take a look<\/span><span class=\"NormalTextRun SCXW30070099 BCX0\"> at the<\/span><\/span><span class=\"TextRun SCXW30070099 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW30070099 BCX0\">\u202f<\/span><\/span><span class=\"TextRun Highlight SCXW30070099 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SpellingErrorV2Themed SCXW30070099 BCX0\">angular.json<\/span><\/span><span class=\"TextRun SCXW30070099 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW30070099 BCX0\">\u202f<\/span><\/span><span class=\"TextRun SCXW30070099 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW30070099 BCX0\">file at the root of our <\/span><span class=\"NormalTextRun SCXW30070099 BCX0\">A<\/span><span class=\"NormalTextRun SCXW30070099 BCX0\">ngular repository to see how the production build differs:<\/span><\/span><span class=\"EOP SCXW30070099 BCX0\">&nbsp;<\/span><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\"configurations\": {\n  \"production\": {\n    \"budgets\": [\n      {\n        \"type\": \"initial\",\n        \"maximumWarning\": \"2mb\",\n        \"maximumError\": \"5mb\"\n      },\n      {\n        \"type\": \"anyComponentStyle\",\n        \"maximumWarning\": \"10kb\"\n      }\n    ],\n    \"fileReplacements\": [\n      {\n        \"replace\": \"projects\/common\/src\/environments\/environment.ts\",\n        \"with\": \"projects\/common\/src\/environments\/environment.prod.ts\"\n      }\n    ],\n    \"localize\": true,\n    \"optimization\": true,\n    \"outputHashing\": \"all\",\n    \"sourceMap\": false,\n    \"namedChunks\": false,\n    \"extractLicenses\": true,\n    \"vendorChunk\": false,\n    \"buildOptimizer\": true,\n    \"serviceWorker\": true,\n    \"i18nMissingTranslation\": \"error\",\n    \"ngswConfigPath\": \"projects\/bellumgens\/src\/ngsw-config.json\"\n  },\n  \"bg\": {\n    \"localize\": [\n      \"bg\"\n    ]\n  }\n}<\/pre>\n\n\n\n<p class=\"graf graf--p\">There\u2019s <span class=\"TextRun SCXW7827957 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW7827957 BCX0\">quite a lot of <\/span><span class=\"NormalTextRun ContextualSpellingAndGrammarErrorV2Themed SCXW7827957 BCX0\">configuration<\/span><span class=\"NormalTextRun SCXW7827957 BCX0\"> here.<\/span> <span class=\"NormalTextRun SCXW7827957 BCX0\">H<\/span><span class=\"NormalTextRun SCXW7827957 BCX0\">owever<\/span><span class=\"NormalTextRun SCXW7827957 BCX0\">,<\/span><span class=\"NormalTextRun SCXW7827957 BCX0\"> the most important one, in this case, is the<\/span><\/span><span class=\"TextRun SCXW7827957 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW7827957 BCX0\">\u202f<code class=\"markup--code markup--p-code\">\"optimization\": true<\/code>&nbsp;one<\/span><\/span><span class=\"TextRun SCXW7827957 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW7827957 BCX0\">. <\/span><\/span><span class=\"TextRun SCXW7827957 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW7827957 BCX0\">Once I run the application with a production configuration, the difference in score is significant in terms of load-time performance:<\/span><\/span><span class=\"EOP SCXW7827957 BCX0\">&nbsp;<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image graf graf--figure\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/5875.pastedimage1690979018205v3.png\" alt=\" Lighthouse score with production build in dev environment\"\/><\/figure>\n\n\n\n<p class=\"graf graf--p\">If I&nbsp;<span class=\"TextRun SCXW239775082 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW239775082 BCX0\">look at the opportunities list again, the number of suggestions is much lower<\/span><span class=\"NormalTextRun SCXW239775082 BCX0\">.<\/span> <span class=\"NormalTextRun SCXW239775082 BCX0\">T<\/span><span class=\"NormalTextRun SCXW239775082 BCX0\">he biggest opportunities listed at about text compression<\/span><span class=\"NormalTextRun SCXW239775082 BCX0\"> are <\/span><span class=\"NormalTextRun SCXW239775082 BCX0\">unused JavaScript and caching of static resources:<\/span><\/span><\/p>\n\n\n\n<figure class=\"wp-block-image graf graf--figure\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/8508.pastedimage1690979018205v4.png\" alt=\" Remaining opportunities for performance improvements\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"angular-pre-rendering-and-server-side-rendering\">Angular Pre-Rendering and Server-Side Rendering&nbsp;<\/h3>\n\n\n\n<p>Angular is a Single Page Application (SPA) framework. By default, the lifecycle of the app is such that upon a request from a client, the server that hosts the application serves down an HTML file that includes all the necessary script and style references. However, it is empty of body content. Once the scripts and styles are requested and served, the application is bootstrapped and populated with content based on the JavaScript logic for the given application. Angular provides two mechanisms to improve this lifecycle by serving actual content in the initial HTML document. To do this, the JavaScript logic of the application needs to be executed prior to serving the document. The ways to do it:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Either at\u202fbuild time (<a href=\"https:\/\/angular.io\/guide\/prerendering\" rel=\"noopener\">pre-rendering<\/a>) &#8211; for pages with mostly static content.\u00a0<\/li>\n\n\n\n<li>Or at\u202frun time on the server (<a href=\"https:\/\/angular.io\/guide\/universal\" rel=\"noopener\">server-side rendering<\/a>)\u202f- for pages with more dynamic content that need to deliver up-to-date content on every request.\u00a0<\/li>\n<\/ul>\n\n\n\n<p>I have enabled server-side rendering for the Angular example app and I\u2019m using the\u202f<a href=\"https:\/\/expressjs.com\/\" rel=\"noopener\">express engine<\/a>\u202fto enable text compression and static resource caching. This is done by adding the following to my express server logic:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">export const app = (lang: string) => {\n  \/\/ server scaffolded by [ng add @nguniversal\/express-engine]\n...\n  \/\/ enable compression [npm install compression]\n  const compression = require('compression');\n  server.use(compression());\n...\n  \/\/ Serve static files from \/browser with 1y caching\n  server.get('*.*', express.static(distFolder, {\n    maxAge: '1y'\n  }));\n...\n}<\/pre>\n\n\n\n<p class=\"graf graf--p\">I will serve the app with server-side rendering and run the lighthouse test again. The initial load improved even further, bringing the first contentful paint to under a second, while the speed index is reduced to 1.2 seconds.<\/p>\n\n\n\n<figure class=\"wp-block-image graf graf--figure\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/7041.pastedimage1690979018205v5.png\" alt=\" Lighthouse score with Angular server-side rendering\"\/><\/figure>\n\n\n\n<p class=\"graf graf--p\">The leftover opportunities for Angular optimization are to reduce unused JavaScript and CSS.<\/p>\n\n\n\n<figure class=\"wp-block-image graf graf--figure\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/1665.pastedimage1690979018206v6.png\" alt=\" Leftover opportunities for performance improvements\"\/><\/figure>\n\n\n\n<p class=\"graf graf--p\">To deal with these, I will have to do some application refactoring.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"angular-lazy-loadingi\">Angular Lazy-Loading&nbsp;<\/h3>\n\n\n\n<p>In order to reduce the unused JavaScript, the best approach would be to create\u202f<a href=\"https:\/\/angular.io\/guide\/lazy-loading-ngmodules\" rel=\"noopener\">lazy-loaded routes<\/a>. This will tell the Angular framework which components are not needed in the top-level module and will split the JavaScript into modules, the logic for which is loaded only when the requested route is loaded.&nbsp;<\/p>\n\n\n\n<p>The Angular example app that I\u2019m using for this blog utilizes larger components, like the\u202f<a href=\"\/products\/ignite-ui-angular\/angular\/components\/grid\/grid\">igx-grid<\/a>, which are not part of the home route. I\u2019m separating the routes using this component into a separate module. This way, I\u2019m going to have that component loaded only after the routes using the component are loaded. After separating the modules, the routes look like this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">export const routes: Routes = [\n  { path: '', component: HomeComponent },\n  { path: 'register', component: RegistrationComponent },\n  { path: 'unauthorized', redirectTo: 'unauthorized\/', pathMatch: 'full' },\n  { path: 'unauthorized\/:message', component: UnauthorizedComponent },\n  { path: 'emailconfirm', component: EmailconfirmComponent },\n  { path: 'strategies', loadChildren: () => import('.\/strategies\/strategies.module').then(m => m.StrategiesModule) },\n  { path: 'emailconfirm\/:error', component: EmailconfirmComponent },\n  { path: 'players', loadChildren: () => import('.\/player-section\/player.module').then(m => m.PlayerModule) },\n  { path: 'team', loadChildren: () => import('.\/team-section\/team.module').then(m => m.TeamModule) },\n  { path: 'notifications', loadChildren: () => import('.\/notifications\/notifications.module').then(m => m.NotificationsModule) },\n  { path: 'search\/teams\/:query', component: TeamResultsComponent },\n  { path: 'search\/players\/:query', component: PlayerResultsComponent },\n  { path: '**', component: HomeComponent }\n];<\/pre>\n\n\n\n<p class=\"graf graf--p\">The <code class=\"markup--code markup--p-code\">team.module<\/code> is the one loading the grid I\u2019m using, so the code for it looks like this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@NgModule({\n  imports: [\n    CommonModule,\n    FormsModule,\n    \/\/ ...\n    IgxGridModule,\n    \/\/ ...\n    TeamComponent,\n    \/\/ ...\n  ]\n})\nexport class TeamModule { }<\/pre>\n\n\n\n<p class=\"graf graf--p\">Looking at the build, this is the result of the initial splitting:<\/p>\n\n\n\n<figure class=\"wp-block-image graf graf--figure\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/4370.pastedimage1690979018206v7.png\" alt=\" Separating the Angular app into lazy-loaded modules\"\/><\/figure>\n\n\n\n<p>Another thing that needs to be done to improve the performance of the Angular application is to limit the size of the CSS to the styles that are used. I\u2019m using\u202f<a href=\"\/products\/ignite-ui-angular\">Ignite UI for Angular<\/a>\u202fas my UI library and there\u2019s a great how-to article on\u202f<a href=\"\/products\/ignite-ui-angular\/angular\/components\/general\/how-to\/how-to-customize-theme#theme-optimization\">customizing and optimizing the component themes<\/a>.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"optimizing-images\">Optimizing Images&nbsp;<\/h3>\n\n\n\n<p>Another aspect of the Angular optimization that should be done is optimizing the images. Lighthouse check will tell you if you\u2019re using suboptimal images by type or size. Make sure the images you load are not larger than the containers they go in and they are with optimal encoding. I now use\u202f.webp\u202fformat for images. It reduces the quality a little, but, still, the application does not require the highest fidelity images.&nbsp;<\/p>\n\n\n\n<p>Images cause layout shifts after they are loaded. Hence, it\u2019s a good idea to set\u202fwidth\u202fand\u202fheight\u202fattributes on the images so the browser knows the dimensions before loading the images. If you\u2019re missing aspect-ratio settings (width and height) on the images, Lighthouse will warn you. This will reduce or completely eliminate the layout shifts.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">NgOptimizedImage to Enforce Image Best Practices&nbsp;<\/h3>\n\n\n\n<p>Angular exposes a directive that enforces image best practices and optimizes image loading for you. It\u2019s called <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/angular.io\/api\/common\/NgOptimizedImage\" target=\"_blank\" rel=\"noopener noreferrer\">NgOptimizedImage<\/a> and it is rather easy to use. All you need to do is import <code class=\"markup--code markup--p-code\">CommonModule<\/code> if you\u2019re still in an <code class=\"markup--code markup--p-code\">NgModule<\/code> based Angular application, or import <code class=\"markup--code markup--p-code\">NgOptimizedImage<\/code> in the component where you want to use it. Then, instead of using <code class=\"markup--code markup--p-code\">src<\/code> to set the image source attribute, you use <code class=\"markup--code markup--p-code\">ngSrc<\/code> instead.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;img ngSrc=\"\/assets\/wallpapers\/strat-editor.webp\" width=\"600\" height=\"347\" class=\"preview-image\" alt=\"Strategy Editor\" \/><\/pre>\n\n\n\n<p class=\"graf graf--p\"><span class=\"TextRun SCXW177496477 BCX0\" lang=\"EN-US\"><span class=\"NormalTextRun SCXW177496477 BCX0\">Finally, you<\/span><span class=\"NormalTextRun SCXW177496477 BCX0\"> can further specify the loading priority for each image and tell the app to lazy-load every non-critical image. If I remove the\u202fwidth\u202fand\u202fheight\u202fattributes, then what I get running the app is:<\/span><\/span><\/p>\n\n\n\n<figure class=\"wp-block-image graf graf--figure\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/3731.pastedimage1690979018206v8.png\" alt=\" NgOptimizedImage enforcing best practices\"\/><\/figure>\n\n\n\n<p>And that\u2019s it.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"wrap-up\">Wrap Up\u2026&nbsp;<\/h2>\n\n\n\n<p>Improving the performance of Angular applications may require continuous monitoring, optimization, and best practices to ensure the app performs efficiently and reliably under various conditions. But in the end, this is how you deliver the ultimate UX, attract and retain users, maintain competitiveness, and achieve business success.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"\/products\/ignite-ui-angular\/download\"><img decoding=\"async\" src=\"https:\/\/static.infragistics.com\/marketing\/Blog-in-content-ads\/Ignite-UI-Angular\/ignite-ui-angular-you-get-ad.gif\" alt=\"Ignite UI for Angular\"\/><\/a><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to improve the performance of Angular apps? Read this blog post to find the ways \u2013 from reducing unused JavaScript and CSS to Angular lazy loading.<\/p>\n","protected":false},"author":22,"featured_media":1208,"comment_status":"publish","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-761","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular"],"_links":{"self":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/761","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/users\/22"}],"replies":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/comments?post=761"}],"version-history":[{"count":4,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/761\/revisions"}],"predecessor-version":[{"id":1891,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/761\/revisions\/1891"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/media\/1208"}],"wp:attachment":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/media?parent=761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/categories?post=761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/tags?post=761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}