Watch & Computed
Exploring the differences between Watch and Computed, and examining their source code
Which executes faster: Watch or Computed?
A friend recently got asked this question in an interview - super interesting! I want to dive deep into Vue's source code to study the differences between Watch and Computed and see which one is actually faster!
First, Let's Understand Vue's Reactivity System
Before we can compare them, we need to understand how Vue's reactivity works. Simply put, Vue 3 uses Proxy to listen for data changes, and when data updates, the page updates accordingly.
Proxy basically helps Vue intercept object read (get) and modify (set) operations. Let's look at a simplified implementation from the official docs:
There are two key concepts here that are fundamental to understanding Watch and Computed:
- track: Records "who" depends on this property (like component render functions or computed properties)
- trigger: When a property changes, notifies all dependents to update
Looking at the actual source code implementation, you'll find the same track and trigger mechanisms:
Understanding the reactivity system helps us dive deeper into Watch and Computed!
What is Watch?
Simply put, Watch is a "tracker." You tell it which data to watch, and when that data changes, it executes the callback function you provided.
Watch characteristics:
- Explicitly tracks specific data sources (can be ref, reactive objects, or functions)
- Executes callbacks when data changes, usually providing new and old values
- Suitable for executing "side effects" like async operations or complex logic
Let's see how Vue's source code implements Watch:
From the source code, we can see that Watch's core is creating a ReactiveEffect instance. When dependencies change, it executes the callback function you provided. This is why Watch is suitable for handling "side effects" - its design purpose is to execute operations when data changes, not to compute new values.
What is Computed?
Computed "calculates" new data based on existing data. It's like a smart assistant that remembers calculation results until the dependent data changes.
Computed characteristics:
- Calculates new values based on existing reactive data
- Has caching mechanism to avoid redundant calculations
- Suitable for simple operations, keeping templates cleaner
Let's look at the key implementation of Computed in the source code:
From the source code, we can clearly see Computed's two core features:
- When dependencies change, it only marks as "dirty" (
EffectFlags.DIRTY
), doesn't immediately recalculate - Only when the value is actually needed (someone reads
.value
) does it decide whether to recalculate based on the "dirty" flag
This is the secret to Computed's efficiency - lazy evaluation plus caching mechanism, avoiding unnecessary redundant calculations, especially suitable for scenarios where calculation results are used multiple times.
Watch vs Computed: Detailed Comparison
Now that we've seen the source code implementations, let's summarize the core differences between Watch and Computed:
Feature | Computed | Watch |
---|---|---|
Purpose | Calculate new data | Execute side effects |
Return Value | Has return value | No return value |
Caching | Has caching mechanism | Executes every time |
Calculation Timing | Calculated when needed (lazy evaluation) | Executes when data changes |
Side Effects | Not suitable (anti-pattern) | Designed for this |
Async Operations | Not suitable | Perfectly suitable |
Programming Style | Declarative | Imperative |
Performance Consideration | Automatically efficient (caching) | Developer needs to optimize manually |
These differences directly reflect their implementation approaches in the source code: Computed focuses on efficiently generating and caching values, while Watch focuses on executing callbacks at the right time.
Practical Application Guidelines
Based on source code analysis, here are some practical guidelines:
When to use Computed:
- When you need to calculate new data from other data
- When calculation results will be used multiple times (leveraging cache for performance)
- When you want to make templates cleaner by moving complex logic out
- When you need to use the same calculation logic in multiple places
When to use Watch:
- When you need to call APIs when data changes
- When executing operations with "side effects"
- When you need to implement debouncing or throttling (watch supports options like
deep
andimmediate
) - When you need to compare values before and after data changes (watch callback provides new and old values)
- When you need to monitor multiple data sources and execute operations when any one changes
Who's Faster? The Source Code's Answer
Back to our original question: At the source code level, Computed usually executes faster. Why? Let's find the answer in the source code:
- Computed has caching mechanism: From the source code, we can see that Computed uses
refreshComputed(this)
to determine whether recalculation is needed. It only recalculates when:- Dependent data has changed (marked as "dirty")
- Someone actually accesses this computed property
- Watch has no caching: Watch's callback executes every time dependencies change, with no skip mechanism (unless you implement it yourself)
But in reality, the speed of both depends on your application scenario:
- For calculation results that need to be accessed multiple times, Computed is definitely faster (thanks to its caching mechanism)
- For async operations or complex side effects, Watch is more suitable (though not necessarily faster)
Best Practices Revealed by Source Code
From Vue's source code design, we can learn an important principle: Consider using Computed first (declarative), and only use Watch when you truly need side effects or async operations (imperative).
This not only aligns with Vue's design philosophy but also gives your application better performance and maintainability. The carefully designed caching mechanism in Vue's source code for Computed not only improves performance but also "prevents unnecessary downstream updates," which is especially important in complex applications.
Choose the right tool to make your Vue application more efficient!