{"id":33726,"date":"2026-05-29T14:33:11","date_gmt":"2026-05-29T12:33:11","guid":{"rendered":"https:\/\/www.angulararchitects.io\/?p=33726"},"modified":"2026-05-29T18:12:29","modified_gmt":"2026-05-29T16:12:29","slug":"how-i-made-my-a2ui-dashboard-300-times-faster","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/","title":{"rendered":"How I Made My A2UI Dashboard 300 Times Faster"},"content":{"rendered":"<div class=\"wp-post-series-box series-agentic-angular wp-post-series-box--expandable\">\n\t\t\t<input id=\"collapsible-series-agentic-angular6a4195fb7dfcb\" class=\"wp-post-series-box__toggle_checkbox\" type=\"checkbox\">\n\t\n\t<label\n\t\tclass=\"wp-post-series-box__label\"\n\t\t\t\t\tfor=\"collapsible-series-agentic-angular6a4195fb7dfcb\"\n\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\t\t<p class=\"wp-post-series-box__name wp-post-series-name\">\n\t\t\tThis is post 7 of 7 in the series <em>&ldquo;Agentic Angular&rdquo;<\/em>\t\t<\/p>\n\t\t\t<\/label>\n\n\t\t\t<div class=\"wp-post-series-box__posts\">\n\t\t\t<ol>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/understanding-ag-ui-the-standard-for-agentic-user-interfaces\/\">Understanding AG-UI: The Standard for Agentic User Interfaces<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/\">AG-UI in Practice: The SDK for TypeScript<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/implementing-ag-ui-with-angular\/\">Implementing AG-UI with Angular<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/a2ui-how-ai-generates-dynamic-uis-at-runtime\/\">A2UI: How AI Generates Dynamic UIs at Runtime<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/integrating-a2ui-with-ag-ui-in-angular\/\">Integrating A2UI with AG-UI in Angular<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/custom-catalogs-in-a2ui-your-own-components-for-ai-generated-uis\/\">Custom Catalogs in A2UI: Your Own Components for AI-Generated UIs<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><span class=\"wp-post-series-box__current\">How I Made My A2UI Dashboard 300 Times Faster<\/span><\/li>\n\t\t\t\t\t\t\t<\/ol>\n\t\t<\/div>\n\t<\/div>\n<p>39 seconds. Over 46,000 tokens. For <em>a single<\/em> dashboard. That's what the first version of my A2UI solution looked like \u2013 and nobody wants to see something like that in production, neither the users staring at an empty screen nor the person who pays the model provider's bill at the end of the month.<\/p>\n<p>Today the same solution runs at <strong>around 0.1 seconds<\/strong> and <strong>a little over 1,500 tokens<\/strong>. That's a speedup by a <strong>factor of 300<\/strong> and a reduction in token consumption by a <strong>factor of 30<\/strong>. The truly interesting part, though, isn't the number itself, but the surprisingly simple lever behind it \u2013 and the lesson it offers for any LLM-powered UI generation.<\/p>\n<p>In a previous article, I showed how A2UI can be used to generate entire dashboards. The result looked like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/dashboard.png\" alt=\"The generated dashboard with boarding passes, booked flights, flight search, rental cars, hotels, and weather\" \/><\/p>\n<p>In this article, I'll show how I dramatically sped up exactly that solution \u2013 and what consequences this optimization brings with it. Because every performance gain comes at a price.<\/p>\n<h2>The Problem: Why A2UI Generation Was Slow and Expensive<\/h2>\n<p>A bit of context first: <code>A2UI<\/code> is a protocol that lets you describe user interfaces \u2013 here, a dashboard \u2013 in a way that an LLM can generate them. So the model doesn't produce finished HTML, but a structured description of the interface that the client then renders. It was exactly this generation step that was the bottleneck in the first version.<\/p>\n<p>To generate A2UI, you first need a correspondingly long prompt with good examples \u2013 classic one-shot or few-shot prompting. Since LLMs handle such examples extremely well, I didn't even copy the full A2UI specification or JSON schema into the prompt. Even so, the whole thing was very large: in the example shown at the beginning, we ended up with <strong>over 43,000 input tokens<\/strong>.<\/p>\n<p>On top of that: generating the A2UI markup from this description took correspondingly long. The model has to produce an extensive structure token by token \u2013 and that's exactly what's expensive.<\/p>\n<p>In addition, the model has to repeatedly issue function calls to retrieve the data for the individual tiles. Each of these calls costs additional reasoning, and therefore time and tokens.<\/p>\n<p>And finally, perhaps the most unpleasant problem: when generating A2UI, the model can get confused and produce faulty markup. A2UI's basic design \u2013 which, for instance, deliberately avoids deep nesting \u2013 does help LLMs noticeably. But errors can't be ruled out entirely, and every error forces additional correction loops. Weaker (and thus cheaper) models in particular are affected by this.<\/p>\n<p>This is what a complete run looked like in the original variant:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/after.png\" alt=\"Trace of the original implementation: around 40 seconds, many tool calls, and a long step for A2UI generation\" \/><\/p>\n<p>It's easy to see: the model first gathers the data via several tool calls and then generates the complete A2UI markup in a single step lasting over 30 seconds. This one step dominates the entire runtime.<\/p>\n<h2>The Solution: an Application-Specific DSL Instead of A2UI Markup<\/h2>\n<p>The idea is remarkably simple: a small, application-specific <code>DSL<\/code> (Domain-Specific Language) \u2013 that is, a deliberately minimal description language tailored to exactly one purpose \u2013 that lets you describe precisely what should be generated: a dashboard with specific contents that fit the application. In our case, this DSL looks like this:<\/p>\n<pre><code class=\"language-json\">{\n  &quot;toolName&quot;: &quot;renderDashboard&quot;,\n  &quot;toolCallId&quot;: &quot;call_2mO2fjJD4ZpGHna4yXsW8QG0&quot;,\n  &quot;toolInput&quot;: {\n    &quot;tiles&quot;: [\n      {\n        &quot;type&quot;: &quot;boardingPasses&quot;,\n        &quot;count&quot;: 2\n      },\n      {\n        &quot;type&quot;: &quot;bookedFlightsList&quot;,\n        &quot;showCheckInButton&quot;: true\n      },\n      {\n        &quot;type&quot;: &quot;flightSearch&quot;,\n        &quot;defaultFrom&quot;: &quot;Graz&quot;,\n        &quot;defaultTo&quot;: &quot;Hamburg&quot;\n      },\n      {\n        &quot;type&quot;: &quot;rentalCars&quot;\n      },\n      {\n        &quot;type&quot;: &quot;hotels&quot;\n      },\n      {\n        &quot;type&quot;: &quot;weatherList&quot;\n      }\n    ]\n  }\n}<\/code><\/pre>\n<p>The model is now only instructed to translate the user's request into this DSL. That's all it does. Since this leads to a very short result, the conversion is fast, less error-prone, and even weaker models handle it without any trouble.<\/p>\n<p>There's another, often underestimated advantage: the application is thereby forced more strongly into a defined framework. The model can no longer do things that the application design didn't anticipate. As a result \u2013 despite the fundamentally non-deterministic behavior of an LLM \u2013 the outcome becomes much more controllable.<\/p>\n<p>This DSL is then used for two purposes:<\/p>\n<ol>\n<li><strong>Conversion into A2UI<\/strong> \u2013 deterministic, in code, without any model.<\/li>\n<li><strong>Retrieving the necessary data<\/strong> \u2013 likewise without any further reasoning by the model.<\/li>\n<\/ol>\n<p>The crucial point: both the translation into A2UI and the fetching of the data now happen in ordinary application code. The model is no longer involved in any of it.<\/p>\n<p>And the client notices none of this. It still receives A2UI as before and therefore doesn't need to know any details of the application logic. The DSL is purely an implementation decision on the server side.<\/p>\n<h2>Consequences: Pros and Cons of the DSL Approach<\/h2>\n<p>As always in software architecture, there's no such thing as &quot;free.&quot; Let's lay out the pros and cons.<\/p>\n<p><strong>Pros:<\/strong><\/p>\n<ul>\n<li>Significantly more performant.<\/li>\n<li>Significantly lower token consumption \u2013 and therefore significantly lower costs.<\/li>\n<li>Behavior becomes more controllable.<\/li>\n<li>Easier for weaker (cheaper) models.<\/li>\n<li>The client doesn't need to know all possible rendering options up front.<\/li>\n<\/ul>\n<p><strong>Cons:<\/strong><\/p>\n<p>The controllable behavior is at the same time the central drawback: the dynamism is limited to those aspects that the DSL explicitly provides for. If you want, say, to limit the amount of data displayed (e.g., at most three hotels), add weather information, or omit the check-in button, the DSL has to provide explicit options for that. Whatever it doesn't anticipate is simply not possible. Our example DSL, for instance, can't express which information about a flight should be presented or whether it should be shown in a table or as a list.<\/p>\n<p>So you trade away part of the generative flexibility in exchange for speed, cost, and control. For the vast majority of business applications, that's an excellent trade \u2013 because there, predictability and performance are almost always more important than unlimited freedom in presentation.<\/p>\n<p><div style=\"\nmargin: 8px 0;\npadding: 22px;\nborder: 1px solid #e5e7eb;\nborder-radius: 14px;\nbackground: #f8fafc;\n\">NOTE<\/p>\n<h3 style=\"margin-top:0\">New: Agentic UI with Angular<\/h3>\n<p>If you want to embed performance and architecture decisions around A2UI not just here and there, but cleanly into larger Angular applications: in my book Agentic UI with Angular, I cover exactly these patterns and trade-offs in detail \u2013 including DSLs, caching, and open standards such as AG-UI, A2UI, and MCP.<\/p>\n<p><a href=\"https:\/\/agentic-angular.com\/\"><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/cover.png\" width=\"400\" alt=\"Cover of the eBook Agentic UI with Angular\" style=\"cursor:pointer !important\"><\/a><\/p>\n<p><a style=\"cursor:pointer !important\" href=\"https:\/\/agentic-angular.com\/\">More about the eBook \u2192<\/a>\n<\/div>\n<\/p>\n<h2>Even More Performance: Caching the A2UI Markup<\/h2>\n<p>As long as the description stays the same, the generated markup can stay the same too. As a rule, that's even desirable: a fresh interpretation that leads to minor deviations would be rather confusing for users. Only the data has to be fetched anew on every call.<\/p>\n<p>Here a fundamental feature of A2UI plays into our hands: you can <strong>separate structure and data<\/strong>. An <code>updateComponents<\/code> message lets you announce the desired structure:<\/p>\n<pre><code class=\"language-json\">{\n    &quot;version&quot;: &quot;v0.9&quot;,\n    &quot;updateComponents&quot;: {\n        &quot;surfaceId&quot;: &quot;dash-bf0140eb-f2e4-4c53-a74b-56e9445cc7dc&quot;,\n        &quot;components&quot;: [\n            [...],\n            {\n                &quot;id&quot;: &quot;tile1&quot;,\n                &quot;component&quot;: &quot;TicketWidget&quot;,\n                &quot;ticketId&quot;: {\n                    &quot;path&quot;: &quot;\/tile1\/tickets\/0\/ticketId&quot;\n                },\n                &quot;from&quot;: {\n                    &quot;path&quot;: &quot;\/tile1\/tickets\/0\/from&quot;\n                },\n                &quot;to&quot;: {\n                    &quot;path&quot;: &quot;\/tile1\/tickets\/0\/to&quot;\n                },\n                &quot;date&quot;: {\n                    &quot;path&quot;: &quot;\/tile1\/tickets\/0\/date&quot;\n                },\n                &quot;delay&quot;: {\n                    &quot;path&quot;: &quot;\/tile1\/tickets\/0\/delay&quot;\n                }\n            },\n            [...]\n        ]\n    }\n}<\/code><\/pre>\n<p>It can contain data-binding expressions that reference a data model. In the example shown, the <code>path<\/code> property points to an array <code>\/tile1\/tickets<\/code> whose entries have properties such as <code>ticketId<\/code>, <code>from<\/code>, <code>to<\/code>, etc.<\/p>\n<p>This data can then be sent to the client with separate messages:<\/p>\n<pre><code class=\"language-json\">{\n    &quot;version&quot;: &quot;v0.9&quot;,\n    &quot;updateDataModel&quot;: {\n        &quot;surfaceId&quot;: &quot;dash-bf0140eb-f2e4-4c53-a74b-56e9445cc7dc&quot;,\n        &quot;path&quot;: &quot;\/tile1&quot;,\n        &quot;value&quot;: {\n            &quot;tickets&quot;: [\n                {\n                    &quot;ticketId&quot;: 1,\n                    &quot;from&quot;: &quot;Graz&quot;,\n                    &quot;to&quot;: &quot;Hamburg&quot;,\n                    &quot;date&quot;: &quot;2026-06-06&quot;,\n                    &quot;delay&quot;: 0\n                },\n                {\n                    &quot;ticketId&quot;: 2,\n                    &quot;from&quot;: &quot;Hamburg&quot;,\n                    &quot;to&quot;: &quot;Graz&quot;,\n                    &quot;date&quot;: &quot;2026-06-06&quot;,\n                    &quot;delay&quot;: 0\n                }\n            ]\n        }\n    }\n}<\/code><\/pre>\n<p>This lets us cache the entire \u2013 and usually fairly large \u2013 <code>updateComponents<\/code> message and only regenerate the comparatively small <code>updateDataModel<\/code> messages on subsequent calls. The parameters needed for that are found in the DSL, which is cached as well.<\/p>\n<p>In our implementation, a hash of the textual description provided by the user serves as the key. In practice, each dashboard is often stored as a record in a design mode of the application \u2013 and the ID of that record, which represents the dashboard, then becomes the cache key.<\/p>\n<h2>The Result: 300 Times Faster, 30 Times Fewer Tokens<\/h2>\n<p>The DSL makes drastic speedups possible. Let's compare the two worlds directly once more:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/after.png\" alt=\"Trace of the original implementation: around 40 seconds with a long A2UI generation step\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/before.png\" alt=\"Trace of the optimized implementation: the model now only produces the compact DSL \u2013 a few seconds instead of minutes\" \/><\/p>\n<p>The model now only creates the DSL from the request \u2013 no longer the complete A2UI markup. This yields a nice side effect: the necessary tool calls for data retrieval can also be derived from the DSL. So the model no longer has to take care of that itself, which results in additional, smaller performance improvements \u2013 simply because less reasoning is needed for individual tool calls.<\/p>\n<p>The second major improvement comes from caching: here the model is no longer needed at all for identical dashboards. Both the DSL and the structure described with A2UI come straight from the cache; only the current data is freshly loaded.<\/p>\n<p>And with that we're back to the numbers from the beginning: <strong>39 seconds<\/strong> and <strong>over 46,000 tokens<\/strong> turned into <strong>around 0.1 seconds<\/strong> and <strong>a little over 1,500 tokens<\/strong> \u2013 a factor of 300 in speed, a factor of 30 in tokens. Importantly, the 30x token reduction already comes from the DSL alone, since the model now only has to produce this compact description instead of the complete A2UI markup. Caching goes on top of that: on a cache hit, the model isn't called at all \u2013 so no tokens are consumed whatsoever.<\/p>\n<h2>Conclusion: LLM for the Intent, Code for the Structure<\/h2>\n<p>At its core, the solution is a deliberate shift of responsibility: instead of letting the LLM generate extensive A2UI markup, it now only translates the request into a compact, application-specific DSL. The expensive work \u2013 creating the structure and fetching the data \u2013 is then handled by deterministic application code.<\/p>\n<p>The result speaks for itself: 300 times faster, 30 times fewer tokens, and a much more controllable behavior that especially benefits weaker and cheaper models. With caching, the model can even be taken out of the hot path entirely for recurring dashboards.<\/p>\n<p>The price for this is a bit of generative freedom: the application can only display what the DSL provides for. For most real-world business applications, however, that's not a loss but a gain \u2013 because there, predictability counts for more than unlimited dynamism. The overarching lesson is: let the LLM do what it does best \u2013 understand intent \u2013 and leave the creation of reliable structures to your code.<\/p>\n<h2>Interested in Production-Ready Agentic UI Architectures?<\/h2>\n<p>In my workshop, we dive into AG-UI, A2UI, MCP Apps, HITL patterns, and modern Angular architectures for real-world agentic systems.<\/p>\n<p><a href=\"https:\/\/www.angulararchitects.io\/en\/training\/agentic-ai-with-angular-architecture-patterns\/\"><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/sujet-workshop-en.png\" alt=\"Workshop: Agentic AI with Angular \u2013 AG-UI, A2UI, MCP Apps & HITL patterns\" style=\"width:100%; max-width:560px;\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.angulararchitects.io\/en\/training\/agentic-ai-with-angular-architecture-patterns\/\">English Version<\/a> | <a href=\"https:\/\/www.angulararchitects.io\/training\/agentic-ai-with-angular-architecture-patterns\/\">German Version<\/a><\/p>\n<h2>FAQ<\/h2>\n<p><strong>Why is direct A2UI generation with an LLM slow and expensive?<\/strong><br \/>\nThe model has to produce an extensive structure token by token from a long few-shot prompt (over 43,000 input tokens in the example) and, on top of that, issue several tool calls for the data. This single generation step dominates the runtime and can additionally produce faulty markup that forces correction loops.<\/p>\n<p><strong>How does an application-specific DSL speed up generation?<\/strong><br \/>\nThe LLM now only translates the request into a compact DSL instead of complete A2UI markup. The result is short, fast, and less error-prone. The expensive work \u2013 conversion into A2UI and data retrieval \u2013 is then handled by deterministic application code without any model.<\/p>\n<p><strong>What does caching add on top of that?<\/strong><br \/>\nA2UI allows you to separate structure (<code>updateComponents<\/code>) and data (<code>updateDataModel<\/code>). The usually large structure can be cached; on subsequent calls, only the small data messages need to be regenerated. For identical dashboards, the model is no longer needed at all.<\/p>\n<p><strong>What's the downside of the DSL approach?<\/strong><br \/>\nThe dynamism is limited to what the DSL explicitly provides for. Whatever it doesn't represent isn't possible. So you trade away part of the generative flexibility in exchange for speed, cost, and control \u2013 a good trade for most business applications.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is post 7 of 7 in the series &ldquo;Agentic Angular&rdquo; Understanding AG-UI: The Standard for Agentic User Interfaces AG-UI in Practice: The SDK for TypeScript Implementing AG-UI with Angular A2UI: How AI Generates Dynamic UIs at Runtime Integrating A2UI with AG-UI in Angular Custom Catalogs in A2UI: Your Own Components for AI-Generated UIs How [&hellip;]<\/p>\n","protected":false},"author":25,"featured_media":33723,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[18],"tags":[],"class_list":["post-33726","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","post_series-agentic-angular"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How I Made My A2UI Dashboard 300 Times Faster - ANGULARarchitects<\/title>\n<meta name=\"description\" content=\"39 seconds and over 46,000 tokens for a single dashboard \u2013 that had to be better. This article shows how a small, application-specific DSL speeds up A2UI generation by a factor of 300, cuts token consumption by a factor of 30, and makes the model&#039;s behavior more controllable along the way.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How I Made My A2UI Dashboard 300 Times Faster - ANGULARarchitects\" \/>\n<meta property=\"og:description\" content=\"39 seconds and over 46,000 tokens for a single dashboard \u2013 that had to be better. This article shows how a small, application-specific DSL speeds up A2UI generation by a factor of 300, cuts token consumption by a factor of 30, and makes the model&#039;s behavior more controllable along the way.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2026-05-29T12:33:11+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-05-29T16:12:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/sujet-en.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Manfred Steyer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/sujet-en.png\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/\"},\"author\":{\"name\":\"Manfred Steyer\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\"},\"headline\":\"How I Made My A2UI Dashboard 300 Times Faster\",\"datePublished\":\"2026-05-29T12:33:11+00:00\",\"dateModified\":\"2026-05-29T16:12:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/\"},\"wordCount\":1825,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/ChatGPT-Image-May-29-2026-01_52_17-PM.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/\",\"name\":\"How I Made My A2UI Dashboard 300 Times Faster - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/ChatGPT-Image-May-29-2026-01_52_17-PM.png\",\"datePublished\":\"2026-05-29T12:33:11+00:00\",\"dateModified\":\"2026-05-29T16:12:29+00:00\",\"description\":\"39 seconds and over 46,000 tokens for a single dashboard \u2013 that had to be better. This article shows how a small, application-specific DSL speeds up A2UI generation by a factor of 300, cuts token consumption by a factor of 30, and makes the model's behavior more controllable along the way.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/ChatGPT-Image-May-29-2026-01_52_17-PM.png\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/ChatGPT-Image-May-29-2026-01_52_17-PM.png\",\"width\":1672,\"height\":941},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How I Made My A2UI Dashboard 300 Times Faster\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\",\"name\":\"Manfred Steyer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How I Made My A2UI Dashboard 300 Times Faster - ANGULARarchitects","description":"39 seconds and over 46,000 tokens for a single dashboard \u2013 that had to be better. This article shows how a small, application-specific DSL speeds up A2UI generation by a factor of 300, cuts token consumption by a factor of 30, and makes the model's behavior more controllable along the way.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/","og_locale":"en_US","og_type":"article","og_title":"How I Made My A2UI Dashboard 300 Times Faster - ANGULARarchitects","og_description":"39 seconds and over 46,000 tokens for a single dashboard \u2013 that had to be better. This article shows how a small, application-specific DSL speeds up A2UI generation by a factor of 300, cuts token consumption by a factor of 30, and makes the model's behavior more controllable along the way.","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/","og_site_name":"ANGULARarchitects","article_published_time":"2026-05-29T12:33:11+00:00","article_modified_time":"2026-05-29T16:12:29+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/sujet-en.png","type":"image\/png"}],"author":"Manfred Steyer","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/sujet-en.png","twitter_misc":{"Written by":"Manfred Steyer","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/"},"author":{"name":"Manfred Steyer","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a"},"headline":"How I Made My A2UI Dashboard 300 Times Faster","datePublished":"2026-05-29T12:33:11+00:00","dateModified":"2026-05-29T16:12:29+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/"},"wordCount":1825,"commentCount":0,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/ChatGPT-Image-May-29-2026-01_52_17-PM.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/","name":"How I Made My A2UI Dashboard 300 Times Faster - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/ChatGPT-Image-May-29-2026-01_52_17-PM.png","datePublished":"2026-05-29T12:33:11+00:00","dateModified":"2026-05-29T16:12:29+00:00","description":"39 seconds and over 46,000 tokens for a single dashboard \u2013 that had to be better. This article shows how a small, application-specific DSL speeds up A2UI generation by a factor of 300, cuts token consumption by a factor of 30, and makes the model's behavior more controllable along the way.","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/ChatGPT-Image-May-29-2026-01_52_17-PM.png","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/05\/ChatGPT-Image-May-29-2026-01_52_17-PM.png","width":1672,"height":941},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/how-i-made-my-a2ui-dashboard-300-times-faster\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"How I Made My A2UI Dashboard 300 Times Faster"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a","name":"Manfred Steyer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","caption":"Manfred Steyer"}}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/33726","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=33726"}],"version-history":[{"count":10,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/33726\/revisions"}],"predecessor-version":[{"id":33742,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/33726\/revisions\/33742"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/33723"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=33726"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=33726"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=33726"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}