Skip to content

Commit f153154

Browse files
committed
chore: rename option to deferUpdates
1 parent 029e370 commit f153154

File tree

7 files changed

+33
-29
lines changed

7 files changed

+33
-29
lines changed

.changeset/green-days-give.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
'@qwik.dev/core': minor
33
---
44

5-
feat: introduce blockRender option for useTask$
5+
feat: introduce deferUpdates option for useTask$

packages/docs/src/routes/api/qwik/api.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2262,7 +2262,7 @@
22622262
}
22632263
],
22642264
"kind": "Interface",
2265-
"content": "```typescript\nexport interface TaskOptions \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[blockRender?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nboolean\n\n\n</td><td>\n\n_(Optional)_ If true, the task will block the rendering of the component until it is complete.\n\n\n</td></tr>\n</tbody></table>",
2265+
"content": "```typescript\nexport interface TaskOptions \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[deferUpdates?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nboolean\n\n\n</td><td>\n\n_(Optional)_ If true, the task will block the rendering of the component until it is complete.\n\n\n</td></tr>\n</tbody></table>",
22662266
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts",
22672267
"mdFile": "core.taskoptions.md"
22682268
},

packages/docs/src/routes/api/qwik/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8809,7 +8809,7 @@ Description
88098809
</th></tr></thead>
88108810
<tbody><tr><td>
88118811
8812-
[blockRender?](#)
8812+
[deferUpdates?](#)
88138813
88148814
</td><td>
88158815

packages/docs/src/routes/docs/(qwik)/core/tasks/index.mdx

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,17 @@ Tasks are meant for running asynchronous operations as part of component initial
3434
> **Note**: Tasks are similar to `useEffect()` in React, but there are enough differences that we did not want to call them the same so as not to bring preexisting expectations about how they work. The main differences are:
3535
>
3636
> - Tasks are asynchronous.
37-
> - Task run on server and browser.
38-
> - Tasks run before rendering and can block rendering.
37+
> - Tasks run on server and browser.
38+
> - Tasks run before initial rendering and block the initial render.
39+
> - Subsequent task re-executions (when tracked state changes) don't block rendering by default, but can be configured to block DOM updates with `deferUpdates: true`.
3940
4041
`useTask$()` should be your default go-to API for running either synchronous or asynchronous work as part of component initialization or state change. It is only when you can't achieve what you need with `useTask$()` that you should consider using `useVisibleTask$()` or `useResource$()`.
4142

4243
The basic use case for `useTask$()` is to perform work on component initialization. `useTask$()` has these properties:
4344
- It can run on either the server or in the browser.
44-
- It runs before rendering and blocks rendering.
45+
- It runs before the initial rendering and blocks the initial render.
4546
- If multiple tasks are running then they are run sequentially in the order they were registered. An asynchronous task will block the next task from running until it completes.
47+
- By default, subsequent re-executions (when tracked state changes) do not block DOM updates unless `deferUpdates: true` is specified.
4648

4749
Tasks can also be used to perform work when a component state changes. In this case, the task will rerun every time the tracked state changes. See: [`track()`](#track).
4850

@@ -100,26 +102,28 @@ When the user interacts with the application, it resumes on the client-side, con
100102

101103
```typescript
102104
interface TaskOptions {
103-
blockRender?: boolean;
105+
deferUpdates?: boolean;
104106
}
105107
```
106108

107-
#### `blockRender`
109+
#### `deferUpdates`
108110

109-
When set to `true`, the task will block the rendering of the component until the task completes. This is useful when you need to ensure that certain asynchronous operations finish before the component is rendered to the user.
111+
The `deferUpdates` option controls whether subsequent task re-executions (when tracked state changes) should block DOM updates.
110112

111-
**Behavior:**
112-
- **`true`**: The task becomes render-blocking. The component will not render until the task finishes executing.
113-
- **`false` (default)**: The task runs asynchronously without blocking the component rendering.
113+
**Default behavior (`deferUpdates: false` or not specified):**
114+
- **Initial render**: The task blocks rendering (runs before the component renders for the first time)
115+
- **Subsequent runs**: The task runs asynchronously without blocking DOM updates
114116

115-
**Use Cases:**
117+
**With `deferUpdates: true`:**
118+
- **Initial render**: The task blocks rendering (same as default)
119+
- **Subsequent runs**: The task blocks DOM updates until it completes - the journal flush is deferred until the task finishes
116120

117-
Use `blockRender: true` when:
118-
- You need to perform exit animations before removing elements from the DOM
119-
- You want to prevent a flash of incorrect content
121+
**When to use `deferUpdates: true`:**
122+
- When you need to ensure that asynchronous state updates complete before the UI reflects changes
123+
- When you want to prevent visual flickering by ensuring all related state updates happen atomically
120124

121125
**Performance Considerations:**
122-
- Use carefully as it can impact rendering performance
126+
- Use carefully as blocking DOM updates on subsequent runs can impact perceived performance
123127

124128
Additionally, this task can be reactive and will re-execute when **tracked** [state](/docs/(qwik)/core/state/index.mdx) changes.
125129

@@ -138,7 +142,7 @@ Additionally, this task can be reactive and will re-execute when **tracked** [st
138142

139143
> If `useTask$()` does not track any state, it will run **exactly once**, either in the server **or** in the browser (**not both**), depending where the component is initially rendered. Effectively behaving like an "on-mount" hook.
140144
141-
`useTask$()` will block the rendering of the component until after its async callback resolves, in other words, tasks execute sequentially even if they are asynchronous. (Only one task executes at a time).
145+
`useTask$()` will block the initial rendering of the component until after its async callback resolves. Tasks execute sequentially even if they are asynchronous (only one task executes at a time within a component). Subsequent re-executions (when tracking state changes) run asynchronously by default and don't block rendering unless `deferUpdates: true` is set.
142146

143147
Take a look at the simplest use case of the task to run some asynchronous work on component initialization:
144148

@@ -169,18 +173,18 @@ const delay = (time: number) => new Promise((res) => setTimeout(res, time));
169173

170174
> In this example
171175
>
172-
> - The `useTask$()` computes the fibonacci number one entry per 100 ms. So 40 entries take 4 seconds to render.
176+
> - The `useTask$()` computes the fibonacci number one entry per 100 ms. So 40 entries take 4 seconds to compute.
173177
> - The `useTask$()` executes on the server as part of the SSR (the result may be cached in CDN.)
174-
> - Because the `useTask$()` blocks rendering, the rendered HTML page takes 4 seconds to render.
175-
> - Because this task has no `track()` it will never rerun, making it effectively an initialization code.
178+
> - Because the `useTask$()` blocks initial rendering, the rendered HTML page takes 4 seconds to generate.
179+
> - Because this task has no `track()` it will never rerun, making it effectively initialization code.
176180
> - Because this component only renders on the server, the `useTask$()` will never be downloaded or run on the browser.
177181
178182
> Notice that `useTask$()` runs on the server **BEFORE** the actual rendering. Therefore if you need to do DOM manipulation, use [`useVisibleTask$()`](#usevisibletask) instead, which runs on the browser after rendering.
179183
180184
Use `useTask$()` when you need to:
181-
- Run async tasks before rendering
182-
- Run code only once before the component is first rendered
183-
- Programmatically run side-effect code when state changes
185+
- Run async tasks before initial rendering
186+
- Run code only once before the component is first rendered
187+
- Programmatically run side-effect code when state changes (with or without blocking DOM updates)
184188

185189
> Note, if you're thinking about loading data using `fetch()` inside of `useTask$`, consider using [`useResource$()`](/docs/core/state/#useresource) instead. This API is more efficient in terms of leveraging SSR streaming and parallel data fetching.
186190
@@ -262,7 +266,7 @@ const delay = (time: number) => new Promise((res) => setTimeout(res, time));
262266
>
263267
> The `useTask$()`
264268
>
265-
> - The `useTask$()` blocks rendering until it completes. If you don't want to block rendering, make sure that the task is resolved, and run the delay work on a separate unconnected promise. In this example, we don't await `delay()` because it would block rendering.
269+
> - By default, `useTask$()` blocks the initial rendering until it completes. Subsequent executions (when tracked state changes) don't block rendering by default. In this example, we don't await `delay()` to avoid blocking even the initial render - the delay runs independently while the task completes immediately.
266270
267271
> Sometimes it is required to only run code either in the server or in the client. This can be achieved by using the `isServer` and `isBrowser` booleans exported from `@qwik.dev/core` as shown above.
268272

packages/qwik/src/core/qwik.core.api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1667,7 +1667,7 @@ export type TaskFn = (ctx: TaskCtx) => ValueOrPromise<void | (() => void)>;
16671667

16681668
// @public (undocumented)
16691669
export interface TaskOptions {
1670-
blockRender?: boolean;
1670+
deferUpdates?: boolean;
16711671
}
16721672

16731673
// @internal (undocumented)

packages/qwik/src/core/tests/use-task.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ describe.each([
671671
(global as any).counter++;
672672
},
673673
{
674-
blockRender: true,
674+
deferUpdates: true,
675675
}
676676
);
677677
return (

packages/qwik/src/core/use/use-task.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export interface DescriptorBase<T = unknown, B = unknown> extends BackRef {
137137
/** @public */
138138
export interface TaskOptions {
139139
/** If true, the task will block the rendering of the component until it is complete. */
140-
blockRender?: boolean;
140+
deferUpdates?: boolean;
141141
}
142142

143143
/** @internal */
@@ -149,7 +149,7 @@ export const useTaskQrl = (qrl: QRL<TaskFn>, opts?: TaskOptions): void => {
149149
assertQrl(qrl);
150150
set(1);
151151

152-
const taskFlags = opts?.blockRender ? TaskFlags.RENDER_BLOCKING : 0;
152+
const taskFlags = opts?.deferUpdates ? TaskFlags.RENDER_BLOCKING : 0;
153153

154154
const task = new Task(
155155
TaskFlags.DIRTY | TaskFlags.TASK | taskFlags,

0 commit comments

Comments
 (0)