<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: João Paulo Ávila</title>
    <description>The latest articles on DEV Community by João Paulo Ávila (@joaopaulo_avila).</description>
    <link>https://dev.to/joaopaulo_avila</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F174520%2F2cf39413-ceff-4a2d-9059-aadec9d5835d.jpg</url>
      <title>DEV Community: João Paulo Ávila</title>
      <link>https://dev.to/joaopaulo_avila</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joaopaulo_avila"/>
    <language>en</language>
    <item>
      <title>Slow and Fragile: The Hidden Math Killing Browser AI Agents (And Why WebMCP Fixes It) ⚡🤖</title>
      <dc:creator>João Paulo Ávila</dc:creator>
      <pubDate>Thu, 12 Nov 2026 20:16:59 +0000</pubDate>
      <link>https://dev.to/joaopaulo_avila/slow-and-fragile-the-hidden-math-killing-browser-ai-agents-and-why-webmcp-fixes-it-33n2</link>
      <guid>https://dev.to/joaopaulo_avila/slow-and-fragile-the-hidden-math-killing-browser-ai-agents-and-why-webmcp-fixes-it-33n2</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 2 of the WebMCP Series. (Read &lt;a href="https://dev.to/joaopaulo_avila/the-responsive-design-moment-for-ai-agents-why-your-company-cant-ignore-webmcp-22eo"&gt;Part 1: The Responsive Design Moment of AI Agents&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;If you have watched an autonomous AI browser agent complete a real-world task—such as booking a multi-city flight, filling out an insurance claim, or ordering food—you have probably felt two conflicting emotions.&lt;/p&gt;

&lt;p&gt;First: &lt;em&gt;“This is pure magic.”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Second, five seconds later: &lt;em&gt;“Why is this taking so painfully long—and why did it just click the wrong button?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://dev.to/joaopaulo_avila/the-responsive-design-moment-for-ai-agents-why-your-company-cant-ignore-webmcp-22eo"&gt;Part 1&lt;/a&gt;, we explored the macro shift: how &lt;strong&gt;WebMCP (Web Model Context Protocol)&lt;/strong&gt; is becoming the "responsive design" moment for AI agents, allowing websites to expose clean tool contracts rather than forcing models to reverse-engineer interfaces.&lt;/p&gt;

&lt;p&gt;Today, let’s peel back the layers and talk about the elephant in the room: &lt;strong&gt;the engineering bottleneck of browser automation.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Why are current visual workflows fundamentally slow and fragile—and what is the exact math behind how WebMCP fixes them?&lt;/p&gt;


&lt;h3&gt;
  
  
  The Anatomy of Failure: "Pixels-as-APIs" 🙈
&lt;/h3&gt;

&lt;p&gt;To understand why AI agents struggle on the modern web, we have to recognize a historical mismatch. &lt;/p&gt;

&lt;p&gt;For the past three decades, web development has focused entirely on &lt;strong&gt;human perception&lt;/strong&gt;. We construct visual hierarchies, CSS grids, responsive animations, and multi-step modal dialogues designed for eyes, mice, and fingers.&lt;/p&gt;

&lt;p&gt;When we ask an autonomous AI agent to navigate that interface using traditional automation tools (like Playwright, Puppeteer, or visual computer-use agents), it is forced into an iterative &lt;strong&gt;“screenshot-analyze-click” loop&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Capture:&lt;/strong&gt; Take a high-resolution screenshot and dump thousands of lines of raw, messy DOM markup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Perceive:&lt;/strong&gt; Stream that massive payload to a vision-language model (VLM).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infer:&lt;/strong&gt; The model tries to guess which CSS class or button corresponds to the desired action (e.g., trying to distinguish &lt;code&gt;.btn-primary-2&lt;/code&gt; from an identical decorative banner).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actuate:&lt;/strong&gt; The agent simulates a physical mouse click or types characters into the input.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait &amp;amp; Repeat:&lt;/strong&gt; Wait for animations or network requests, take another screenshot, and repeat the cycle.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On a simple task with 5 or 6 steps, this loop easily accumulates &lt;strong&gt;30 to 60 seconds of wall-clock latency&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Worse, this visual guesswork hits a hard reliability ceiling: studies and benchmarks consistently show that visual actuation hovers around a &lt;strong&gt;~70% success rate&lt;/strong&gt; on complex, multi-step web tasks. An agent might succeed nine times in a row, only to fail on the tenth because an A/B test shifted a button by 12 pixels or an unannounced promotional banner popped up.&lt;/p&gt;


&lt;h3&gt;
  
  
  The Hidden Math: The Token Burn Formula 📉
&lt;/h3&gt;

&lt;p&gt;Beyond latency and fragility, there is a brutal economic reality that kills browser automation in production: &lt;strong&gt;token consumption&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In technical reports analyzing agentic actuation, the cost of the visual loop can be formalized as:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;C&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord text mtight"&gt;&lt;span class="mord mtight"&gt;visual&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop op-limits"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mrel mtight"&gt;=&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="mop op-symbol large-op"&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;T&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord text mtight"&gt;&lt;span class="mord mtight"&gt;DOM&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;T&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord text mtight"&gt;&lt;span class="mord mtight"&gt;screenshot&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;Where 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 represents the number of visual screenshot-and-analyze iterations required to complete a multi-step task, and 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;T&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 represents the thousands of tokens consumed per image and raw DOM tree. A single flight booking can easily incinerate tens of thousands of tokens just trying to figure out which calendar date picker to click.&lt;/p&gt;

&lt;p&gt;Now compare that with the &lt;strong&gt;WebMCP cost function&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;C&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord text mtight"&gt;&lt;span class="mord mtight"&gt;webmcp&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;T&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord text mtight"&gt;&lt;span class="mord mtight"&gt;schema&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;T&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord text mtight"&gt;&lt;span class="mord mtight"&gt;payload&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;Under WebMCP, the entire iterative feedback loop collapses into a &lt;strong&gt;single, deterministic function call&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent reads the concise JSON Schema exposed by the website (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;T&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord text mtight"&gt;&lt;span class="mord mtight"&gt;schema&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
).&lt;/li&gt;
&lt;li&gt;It executes the tool with structured parameters and receives typed JSON data (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;T&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord text mtight"&gt;&lt;span class="mord mtight"&gt;payload&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;~89% reduction in token overhead&lt;/strong&gt; (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;C&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord text mtight"&gt;&lt;span class="mord mtight"&gt;webmcp&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;≪&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;C&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord text mtight"&gt;&lt;span class="mord mtight"&gt;visual&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task execution accuracy jumps from ~70% to ~98%&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency drops from 45 seconds to sub-second execution&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Why Web Automation (Playwright) Wasn't Built for This 🛠️
&lt;/h3&gt;

&lt;p&gt;A common misconception among developers is: &lt;em&gt;"Why do we need WebMCP when we already have Playwright MCP and headless browsers?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The answer comes down to &lt;strong&gt;intent vs. perception&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Browser Automation (Playwright / E2E)&lt;/th&gt;
&lt;th&gt;WebMCP (Browser-Native Standard)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary Goal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Verify Human UI:&lt;/strong&gt; Test if a human user can see, click, and interact with visual elements (QA testing).&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Execute Agentic Logic:&lt;/strong&gt; Allow AI agents to invoke business functions directly with 98% determinism.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mechanism&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Actuation (simulating mouse clicks, keystrokes, parsing accessibility trees).&lt;/td&gt;
&lt;td&gt;Direct invocation of client-side JavaScript tools registered on the page.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Resilience&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Zero:&lt;/strong&gt; CSS refactoring, class renames, or responsive breakpoints break the automation.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;High:&lt;/strong&gt; The visual layout can be completely redesigned without breaking the agent's underlying contract.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bot Defenses&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Often blocked by Cloudflare, WAFs, or visual CAPTCHAs due to simulated mouse events.&lt;/td&gt;
&lt;td&gt;A sanctioned, browser-mediated "front door" operating inside the user's authenticated session.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Playwright is an incredible tool for software quality assurance. But using it as an API layer for AI agents is like using a mechanical robot hand to physically type on a keyboard instead of plugging in a USB cable.&lt;/p&gt;




&lt;h3&gt;
  
  
  What This Means for Product and Engineering Teams 🚀
&lt;/h3&gt;

&lt;p&gt;If your company operates a SaaS platform, an e-commerce store, a dashboard, or a customer portal, here is what this performance gap means for your roadmap:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stop Building "Scraping" Copilots:&lt;/strong&gt; Relying on agents that click around your own UI creates massive maintenance debt. Expose your core client-side functions via declarative HTML or the imperative &lt;code&gt;document.modelContext.registerTool()&lt;/code&gt; API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contextual Tool Lifecycle:&lt;/strong&gt; Unlike backend MCP servers that overwhelm models by dumping hundreds of tools into the context window, WebMCP tools are &lt;strong&gt;page-bound&lt;/strong&gt;. On the search page, only search tools exist; on the checkout page, only checkout tools appear. This keeps context windows lean and reasoning sharp.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Speed Advantage Compounds:&lt;/strong&gt; In the agentic era, users will not wait 60 seconds watching an AI stumble through a checkout flow on Website A if Website B allows the same agent to complete the order in 2 seconds via WebMCP.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The era of making AI agents "pretend to be human" is ending. The web of tomorrow is deterministic, fast, and structured.&lt;/p&gt;




&lt;p&gt;How is your engineering team thinking about agentic performance? Are you still relying on visual actuation, or are you preparing structured tool surfaces? Let's discuss in the comments! 👇&lt;/p&gt;




</description>
    </item>
    <item>
      <title>The "Responsive Design Moment" for AI Agents: Why Your Company Can't Ignore WebMCP</title>
      <dc:creator>João Paulo Ávila</dc:creator>
      <pubDate>Thu, 12 Nov 2026 18:47:28 +0000</pubDate>
      <link>https://dev.to/joaopaulo_avila/the-responsive-design-moment-for-ai-agents-why-your-company-cant-ignore-webmcp-22eo</link>
      <guid>https://dev.to/joaopaulo_avila/the-responsive-design-moment-for-ai-agents-why-your-company-cant-ignore-webmcp-22eo</guid>
      <description>&lt;p&gt;Remember 2012? It was when businesses realized they could no longer ignore smartphones. Instead of rebuilding entire systems from scratch, the web adapted with an elegant solution: Responsive Design. We added breakpoints, structured our HTML, and the same websites suddenly served humans on screens of any size.&lt;/p&gt;

&lt;p&gt;In 2026, we are living through that exact same shift. But this time, the adaptation isn't for smaller screens — it is for AI agents.&lt;/p&gt;

&lt;p&gt;Introducing WebMCP (Web Model Context Protocol), an open standard currently in incubation by the W3C and co-developed by engineers from Google and Microsoft. It is poised to permanently change how AI assistants interact with the internet.&lt;/p&gt;

&lt;p&gt;The Problem: AI Agents are Navigating the Web "Blindfolded" &lt;br&gt;
Until today, when you ask an AI agent to perform a task on a website (like booking a flight or building a shopping cart), it has to mimic human behavior:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It takes screenshots of the page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It parses messy HTML (the DOM).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It tries to guess which button to click or which field to fill out.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This visual method (known as actuation) is extremely slow, token-heavy, and comically fragile. If a designer changes a button's color or shifts the page layout, the AI gets lost and the automation breaks. The average success rate of this "guesswork" navigation hovers around 70%.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: WebMCP and the "Tool Contract"
&lt;/h2&gt;

&lt;p&gt;WebMCP flips this workflow. Instead of forcing the AI to guess your website's design, your website clearly tells the AI what it is capable of doing.&lt;/p&gt;

&lt;p&gt;Through a native browser API (navigator.modelContext), your site registers a list of structured tools with defined inputs (JSON Schemas) and natural language descriptions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Without WebMCP&lt;/strong&gt;: The AI scrapes the DOM, desperately trying to find where to click to add a pizza to the cart.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;With WebMCP&lt;/strong&gt;: A restaurant's website exposes a structured function: add_to_cart({ itemId: string, quantity: number, notes: string }). The AI agent simply invokes this function directly, deterministically, and instantaneously.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The results are game-changing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;98% task execution accuracy (no more hallucinations or wrong clicks!).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;89% savings in tokens (less data transferred, near-instantaneous local processing).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complete design freedom: You can redesign your entire website without worrying about breaking AI integrations, because the "tool contract" remains intact.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Big Win: Native Session and Cookie Inheritance
&lt;/h2&gt;

&lt;p&gt;Integrating systems with AI agents has historically been an infrastructure and security nightmare, requiring complex API keys, dedicated backend servers, and exhaustive OAuth authentication flows.&lt;/p&gt;

&lt;p&gt;Because WebMCP runs entirely client-side in the user's browser, it elegantly solves this: the AI agent automatically inherits the user's active cookies, logins (SSO), and sessions.&lt;/p&gt;

&lt;p&gt;If a user is already logged into your platform or e-commerce store, the AI agent instantly inherits that secure identity. It operates within the exact same permissions and boundaries as the user, without you having to write a single line of backend authentication logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Human-in-the-Loop: Keeping the User in Control
&lt;/h2&gt;

&lt;p&gt;Sensitive actions—like payments, checkouts, or deleting accounts—cannot be left 100% to autonomous AI agents. WebMCP is designed around the principle of cooperation. Sensitive tools can (and should) require on-screen physical validation, such as displaying a confirmation modal so the user can physically approve the transaction before sending an order to the kitchen or processing a payment.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Prepare Today?
&lt;/h2&gt;

&lt;p&gt;WebMCP has just transitioned from an experimental prototype to a public Origin Trial in Chrome (versions 149 to 156). Native support across the Chromium engine (Chrome and Edge) is paving the way for the broader ecosystem.&lt;/p&gt;

&lt;p&gt;You don't need to rebuild your site. The implementation is incremental:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Audit your HTML&lt;/strong&gt;: Ensure semantic and clean HTML (which already helps your traditional SEO).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adopt Progressive Enhancement&lt;/strong&gt;: Add declarative markups or register imperative JavaScript tools that gracefully no-op on older browsers without breaking the human experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write clear descriptions&lt;/strong&gt;: In the age of AI, clean tool and parameter descriptions are the new conversion "meta tags."&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The era of the agent-ready web has already begun. Brands that make it easy for AI to complete tasks will win. Those that still require manual clicking will be left behind.&lt;/p&gt;

&lt;p&gt;Is your website ready to be "executed" by robots, or are you still forcing them to guess your interface?&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Image Optimization and Lazy Loading</title>
      <dc:creator>João Paulo Ávila</dc:creator>
      <pubDate>Mon, 17 Jun 2024 13:03:18 +0000</pubDate>
      <link>https://dev.to/joaopaulo_avila/image-optimization-and-lazy-loading-30gj</link>
      <guid>https://dev.to/joaopaulo_avila/image-optimization-and-lazy-loading-30gj</guid>
      <description>&lt;p&gt;In the era of modern frontends, we often raise the question, "How do I make my application more performant?" In this article, I will discuss image optimization and lazy loading to help improve performance and make our application increasingly faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Images are always a problem in the life of frontenders.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Very large and heavy images can hinder our application in various aspects, from super slow loading when you have a not-so-fast internet connection, especially when on 3G or 4G, to the initial bootstrap on a desktop, failing to provide elegant feedback to the user. There are many other issues we encounter along the way as well, hehe.&lt;/p&gt;

&lt;p&gt;Here, I present some good practice ideas to assist in application development and perhaps provide some tips for those facing this issue. We will use the &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive, which helps improve image loading speed.&lt;/p&gt;

&lt;p&gt;We will create the project using the Angular CLI. I will assume you already know what we are talking about and import the &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive in the AppModule file. &lt;strong&gt;Remember that this directive is available from version 14.2.0 onwards.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// If you are using standalone, it can be done as below.&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StandaloneComponent&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the &lt;code&gt;src&lt;/code&gt; property to &lt;code&gt;ngSrc&lt;/code&gt; in your HTML template and it will also be necessary to set a width and height.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"../assets/img/image.jpeg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"4000"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"3000"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For responsive images, provide various sizes so the browser can choose the best one to render, thus avoiding performance loss.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"../assets/img/image.jpeg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"4000"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"3000"&lt;/span&gt;
  &lt;span class="na"&gt;ngSrcset=&lt;/span&gt;&lt;span class="s"&gt;"200w, 400w, 600w, 800w, 1000w, 1200w, 1600w, 2000w, 3000w"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Angular &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive already loads images by default with lazy loading, but non-visible images should also be loaded this way.&lt;/p&gt;

&lt;p&gt;For example, images in a carousel or those lower down the page do not need to be "loaded" when the page is first called. For this, we use another attribute to assist, which is &lt;code&gt;priority&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"../assets/img/image.jpeg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"4000"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"3000"&lt;/span&gt;
  &lt;span class="na"&gt;ngSrcset=&lt;/span&gt;&lt;span class="s"&gt;"200w, 400w, 600w, 800w, 1000w, 1200w, 1600w, 2000w, 3000w"&lt;/span&gt;
  &lt;span class="na"&gt;priority&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, all images shown on the page to the user will be marked with priority and will load first. If you have a CDN, from this version of Angular onwards, you can add the provider &lt;code&gt;provideImageKitLoader&lt;/code&gt;, making it easier to import images.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provideImageKitLoader&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;provideImageKitLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cdn_url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By doing this, you only need to use the image name in the &lt;code&gt;src&lt;/code&gt;, without always typing the full image path, as it will already be called in the provider.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"image.jpeg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"4000"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"3000"&lt;/span&gt;
  &lt;span class="na"&gt;ngSrcset=&lt;/span&gt;&lt;span class="s"&gt;"200w, 400w, 600w, 800w, 1000w, 1200w, 1600w, 2000w, 3000w"&lt;/span&gt;
  &lt;span class="na"&gt;priority&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below are some data showing the differences between using lazy loading and not.&lt;/p&gt;

&lt;p&gt;Without Lazy Loading&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjs5k9rl14u7d7sa631z5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjs5k9rl14u7d7sa631z5.png" alt="Without Lazy Loading" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With Lazy Loading&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhqqxfj27dcnmm3etk4e7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhqqxfj27dcnmm3etk4e7.png" alt="With Lazy Loading" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These were some tips on how we can use image lazy loading to our advantage, bringing faster loading speeds to our pages and providing good usability for the user.&lt;/p&gt;

&lt;p&gt;twitter &lt;a class="mentioned-user" href="https://dev.to/joaopaulo_avila"&gt;@joaopaulo_avila&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Otimização de imagem e lazy loading</title>
      <dc:creator>João Paulo Ávila</dc:creator>
      <pubDate>Fri, 24 Feb 2023 22:30:00 +0000</pubDate>
      <link>https://dev.to/joaopaulo_avila/otimizacao-de-imagem-e-lazy-loading-3gd8</link>
      <guid>https://dev.to/joaopaulo_avila/otimizacao-de-imagem-e-lazy-loading-3gd8</guid>
      <description>&lt;p&gt;Nos tempos de frontends modernos, sempre levantamos a questão de… "Como faço para tornar minha aplicação mais performática?” Neste artigo irei falar sobre otimização de imagem e lazy loading para auxiliar nesse processo de performance e ter nossa aplicação cada vez mais rápida.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;As imagens sempre são um problema na vida dos frontenders.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Imagem muito grande e pesada pode atrapalhar em vários aspectos nossa aplicação, desde a um carregamento super lento quando se tem uma internet não tão rápida, principalmente quando se está em um 3g ou 4g, como também em um desktop para primeiro bootstrap da aplicação, não dando um feedback para o usuário de forma elegante. Além de vários outros problemas também que as vezes encontramos por esse caminho hehe.&lt;/p&gt;

&lt;p&gt;Trago aqui alguma ideia de boa prática e poder auxiliar no desenvolvimento das aplicações e quem sabe dar alguma dica para as pessoas que estão passando por esse problema. Vamos utilizar a diretiva &lt;code&gt;NgOptimizedImage&lt;/code&gt;&amp;nbsp;que ajuda a melhorar a velocidade de carregamento de imagens.&lt;/p&gt;

&lt;p&gt;Vamos criar o projeto usando a CLI do angular. Vou considerar que você já sabe do que estamos falando e importe a diretiva &lt;code&gt;NgOptimizedImage&lt;/code&gt; no arquivo do AppModule. &lt;strong&gt;Lembrando que essa diretiva está disponível a partir da versão 14.2.0.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Caso voce esteja usando standalone pode ser feito da forma a baixo.&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;StandaloneComponent&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Troque a propriedade src para ngSrc no seu template html e também será necessário colocar um width e um height.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"../assets/img/image.jpeg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"4000"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"3000"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para imagens responsivas passe diversos tamanhos, assim o browser escolherá a melhor para renderizar e assim você não irá perder performance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"../assets/img/image.jpeg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"4000"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"3000"&lt;/span&gt;
  &lt;span class="na"&gt;ngSrcset=&lt;/span&gt;&lt;span class="s"&gt;"200w, 400w, 600w, 800w, 1000w, 1200w, 1600w, 2000w, 3000w"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A diretiva &lt;code&gt;NgOptimizedImage&lt;/code&gt; do angular, já carrega as imagens por default em lazy loading, porém as imagens não visíveis também devem ser carregadas dessa forma.&lt;/p&gt;

&lt;p&gt;Por exemplo, imagens de um carrosel ou que esteja mais a baixo da página, não precisa ser "carregada” quando a página é chamada, com isso, usamos um outro atributo para nos auxiliar, que é o &lt;code&gt;priority&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"../assets/img/image.jpeg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"4000"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"3000"&lt;/span&gt;
  &lt;span class="na"&gt;ngSrcset=&lt;/span&gt;&lt;span class="s"&gt;"200w, 400w, 600w, 800w, 1000w, 1200w, 1600w, 2000w, 3000w"&lt;/span&gt;
  &lt;span class="na"&gt;priority&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com ele, todas as imagens que são mostradas na página para o usuário serão marcadas com prioridade e irão ser carregadas primeiro. Caso voce tenha algum CDN, a partir dessa versão do angular, é possível adicionar o provider provideImageKitLoader, assim facilita a importação das imagens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provideImageKitLoader&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;provideImageKitLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url_cdn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fazendo isso basta usar só o nome da imagem no src assim, não precisa ficar digitando sempre o caminho da imagem, pois já estará sendo chamado no provider.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"image.jpeg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"4000"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"3000"&lt;/span&gt;
  &lt;span class="na"&gt;ngSrcset=&lt;/span&gt;&lt;span class="s"&gt;"200w, 400w, 600w, 800w, 1000w, 1200w, 1600w, 2000w, 3000w"&lt;/span&gt;
  &lt;span class="na"&gt;priority&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alguns dados a baixo com as diferenças de usar com e sem lazy loading.&lt;/p&gt;

&lt;p&gt;Sem Lazy Loading&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DrRyz1wI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/js5k9rl14u7d7sa631z5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DrRyz1wI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/js5k9rl14u7d7sa631z5.png" alt="Sem Lazy Loading" width="880" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com lazy Loading&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sG9jBS8G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqqxfj27dcnmm3etk4e7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sG9jBS8G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqqxfj27dcnmm3etk4e7.png" alt="Com Lazy Loading" width="880" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Estas foram algumas dicas de como podemos utilizar o lazy loading de imagem ao nosso favor, trazendo mais velocidade de carregamento em nossas páginas e dando uma boa usabilidade para o usuário.&lt;/p&gt;

&lt;p&gt;twitter &lt;a class="mentioned-user" href="https://dev.to/joaopaulo_avila"&gt;@joaopaulo_avila&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Criando eventBinding com exportAs</title>
      <dc:creator>João Paulo Ávila</dc:creator>
      <pubDate>Thu, 20 Jan 2022 22:37:48 +0000</pubDate>
      <link>https://dev.to/joaopaulo_avila/criando-eventbinding-com-exportas-10p4</link>
      <guid>https://dev.to/joaopaulo_avila/criando-eventbinding-com-exportas-10p4</guid>
      <description>&lt;p&gt;Estava criando um componente angular e pensei "Será que é possível pegar um método ou retorno de função sem precisar emitir um evento em si?". &lt;/p&gt;

&lt;p&gt;Foi onde achei uma propriedade do angular que é o &lt;code&gt;exportAs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O exportAs basicamente exporta seu componente com todas as variáveis e métodos públicos.&lt;/p&gt;

&lt;p&gt;Começando com o básico vamos criar um projeto Angular simples rodando o comando&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ng new nameProject&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Para este caso vou escolher as opções básicas do CLI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bjmkda6axkrjwx9gdog.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bjmkda6axkrjwx9gdog.png" alt="Criando novo projeto"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;para rodar o projeto execute o comando&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ng serve&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;E ele irá rodar na porta &lt;a href="https://localhost:4200/" rel="noopener noreferrer"&gt;&lt;code&gt;https://localhost:4200&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4nwwanfbvg3utg6tmwe.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4nwwanfbvg3utg6tmwe.jpeg" alt="Página principal do angular"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feito isso, vamos criar nosso componente onde vamos exportar ele para o "pai". &lt;/p&gt;

&lt;p&gt;Para criar um novo componente você pode criar na "mão"  ou rodar o comando &lt;code&gt;ng g c nameComponent&lt;/code&gt;  ou &lt;code&gt;ng generate component nameComponent&lt;/code&gt; ambos criam um novo component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpea2h3yr4r4um0zc6hnn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpea2h3yr4r4um0zc6hnn.png" alt="Criação de um novo component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quando inicia um novo componente vamos criar um método qualquer aqui que retorno uma informação. Vamos fazer o exemplo do Output primeiro para demonstrar a diferença de ambos.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;app.component.html&lt;/code&gt; ficaria dessa forma&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: flex"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;app-user&lt;/span&gt; &lt;span class="na"&gt;#exportUser&lt;/span&gt;&lt;span class="err"&gt;="&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/app-user&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"exportUser.hideUser()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hide User&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"exportUser.user"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;User:&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ exportUser.user.name }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ exportUser.user.age }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, estou importando o component &lt;code&gt;app-user&lt;/code&gt; no html e criando uma variável nele chamada &lt;code&gt;exportUser&lt;/code&gt; , o nome desta variável você quem escolhe e não precisa ter o nome “export” nela, usei apenas como exemplo.&lt;/p&gt;

&lt;p&gt;Feito isso eu posso pegar os valores de variáveis e métodos publicos dentro do meu componente e poder fazer todas as interações com ele.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;user.component.ts&lt;/code&gt; fica dessa forma&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user.component.scss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;exportAs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;clickedButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;showTextClickedButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;showUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Joao&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;hideUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O “Pulo do Gato” está em colocar o exportAs no decorator, &lt;code&gt;exportAs: 'user'&lt;/code&gt; , o nome da variável que utilizei para atribuir ao exportAs é a qual voce vai usar dentro do &lt;code&gt;app.component.html&lt;/code&gt; então o nome delas precisam ser iguais. Você também pode escolher o nome da variável que achar mais viável para o seu component.&lt;/p&gt;

&lt;p&gt;Essa é uma forma que podemos trabalhar com eventos, além do &lt;code&gt;Output&lt;/code&gt; e pegar o retorno de alguma variável específica, podendo facilitar assim para algo que precise.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
