or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browser-apis.mddevice.mddom-events.mdindex.mdnavigation.mdnetwork.mdobservers.mdspecialized.mdstate-management.mdstorage.mdtiming.mdutilities.md

timing.mddocs/

0

# Timing & Performance

1

2

Performance optimization hooks including debouncing, throttling, intervals, timeouts, and callback optimization for efficient React applications.

3

4

## Capabilities

5

6

### useInterval

7

8

Declarative intervals with start/stop/toggle controls and automatic cleanup.

9

10

```typescript { .api }

11

/**

12

* Declarative interval with controls

13

* @param fn - Function to execute on interval

14

* @param interval - Interval duration in milliseconds

15

* @param options - Configuration for auto-invoke

16

* @returns Object with interval controls and state

17

*/

18

function useInterval(fn: () => void, interval: number, options?: UseIntervalOptions): UseIntervalReturnValue;

19

20

interface UseIntervalOptions {

21

autoInvoke?: boolean; // Start interval immediately (default: false)

22

}

23

24

interface UseIntervalReturnValue {

25

start: () => void;

26

stop: () => void;

27

toggle: () => void;

28

active: boolean;

29

}

30

```

31

32

**Usage Examples:**

33

34

```typescript

35

import { useInterval } from "@mantine/hooks";

36

37

function Timer() {

38

const [seconds, setSeconds] = useState(0);

39

40

const interval = useInterval(() => {

41

setSeconds(s => s + 1);

42

}, 1000);

43

44

return (

45

<div>

46

<p>Seconds: {seconds}</p>

47

<button onClick={interval.toggle}>

48

{interval.active ? 'Pause' : 'Start'}

49

</button>

50

<button onClick={() => setSeconds(0)}>Reset</button>

51

</div>

52

);

53

}

54

55

// Auto-start interval

56

function AutoTimer() {

57

const [count, setCount] = useState(0);

58

59

useInterval(() => {

60

setCount(c => c + 1);

61

}, 1000, { autoInvoke: true });

62

63

return <div>Count: {count}</div>;

64

}

65

```

66

67

### useTimeout

68

69

Declarative timeout with start/clear controls.

70

71

```typescript { .api }

72

/**

73

* Declarative timeout with controls

74

* @param callback - Function to execute after delay

75

* @param delay - Delay in milliseconds

76

* @param options - Configuration for auto-invoke

77

* @returns Object with timeout controls

78

*/

79

function useTimeout(callback: () => void, delay: number, options?: UseTimeoutOptions): UseTimeoutReturnValue;

80

81

interface UseTimeoutOptions {

82

autoInvoke?: boolean; // Start timeout immediately (default: false)

83

}

84

85

interface UseTimeoutReturnValue {

86

start: () => void;

87

clear: () => void;

88

}

89

```

90

91

### useDebouncedCallback

92

93

Debounced callback with cancel/flush/pending methods and advanced options.

94

95

```typescript { .api }

96

/**

97

* Debounced callback with advanced controls

98

* @param callback - Function to debounce

99

* @param delay - Debounce delay in milliseconds

100

* @param options - Debounce configuration

101

* @returns Debounced function with control methods

102

*/

103

function useDebouncedCallback<T extends (...args: any[]) => any>(

104

callback: T,

105

delay: number,

106

options?: UseDebouncedCallbackOptions

107

): UseDebouncedCallbackReturnValue<T>;

108

109

interface UseDebouncedCallbackOptions {

110

maxWait?: number; // Maximum time to wait before forcing execution

111

leading?: boolean; // Execute on leading edge

112

trailing?: boolean; // Execute on trailing edge (default: true)

113

}

114

115

type UseDebouncedCallbackReturnValue<T> = T & {

116

cancel: () => void;

117

flush: () => void;

118

pending: () => boolean;

119

};

120

```

121

122

**Usage Examples:**

123

124

```typescript

125

import { useDebouncedCallback } from "@mantine/hooks";

126

127

function SearchInput() {

128

const [query, setQuery] = useState('');

129

130

const handleSearch = useDebouncedCallback((searchQuery: string) => {

131

// API call

132

console.log('Searching for:', searchQuery);

133

}, 500, {

134

leading: false,

135

trailing: true

136

});

137

138

useEffect(() => {

139

if (query) {

140

handleSearch(query);

141

} else {

142

handleSearch.cancel(); // Cancel pending search

143

}

144

}, [query, handleSearch]);

145

146

return (

147

<div>

148

<input

149

value={query}

150

onChange={(e) => setQuery(e.target.value)}

151

placeholder="Search..."

152

/>

153

<button onClick={() => handleSearch.flush()}>

154

Search Now

155

</button>

156

<p>Pending: {handleSearch.pending() ? 'Yes' : 'No'}</p>

157

</div>

158

);

159

}

160

```

161

162

### useDebouncedState

163

164

State with debounced updates to reduce re-renders.

165

166

```typescript { .api }

167

/**

168

* State with debounced updates

169

* @param defaultValue - Initial state value

170

* @param wait - Debounce delay in milliseconds

171

* @param options - Debounce configuration

172

* @returns Tuple of debounced value and setter

173

*/

174

function useDebouncedState<T>(defaultValue: T, wait: number, options?: UseDebouncedStateOptions): UseDebouncedStateReturnValue<T>;

175

176

interface UseDebouncedStateOptions {

177

leading?: boolean; // Update on leading edge

178

}

179

180

type UseDebouncedStateReturnValue<T> = [T, React.Dispatch<React.SetStateAction<T>>];

181

```

182

183

### useDebouncedValue

184

185

Debounced value updates for derived state.

186

187

```typescript { .api }

188

/**

189

* Debounced value updates

190

* @param value - Value to debounce

191

* @param wait - Debounce delay in milliseconds

192

* @param options - Debounce configuration

193

* @returns Tuple of debounced value and cancel function

194

*/

195

function useDebouncedValue<T>(value: T, wait: number, options?: UseDebouncedValueOptions): UseDebouncedValueReturnValue<T>;

196

197

interface UseDebouncedValueOptions {

198

leading?: boolean;

199

}

200

201

type UseDebouncedValueReturnValue<T> = [T, () => void];

202

```

203

204

**Usage Examples:**

205

206

```typescript

207

import { useDebouncedValue } from "@mantine/hooks";

208

209

function ExpensiveComponent({ searchQuery }: { searchQuery: string }) {

210

const [debouncedQuery, cancel] = useDebouncedValue(searchQuery, 300);

211

212

// Only re-compute when debounced value changes

213

const expensiveResults = useMemo(() => {

214

return performExpensiveSearch(debouncedQuery);

215

}, [debouncedQuery]);

216

217

return (

218

<div>

219

<p>Searching for: {debouncedQuery}</p>

220

<button onClick={cancel}>Cancel Search</button>

221

<Results data={expensiveResults} />

222

</div>

223

);

224

}

225

```

226

227

### useThrottledCallback

228

229

Throttled callback execution to limit call frequency.

230

231

```typescript { .api }

232

/**

233

* Throttled callback execution

234

* @param callback - Function to throttle

235

* @param wait - Throttle delay in milliseconds

236

* @returns Throttled function

237

*/

238

function useThrottledCallback<T extends (...args: any[]) => any>(

239

callback: T,

240

wait: number

241

): T;

242

```

243

244

### useThrottledState

245

246

State with throttled updates to limit update frequency.

247

248

```typescript { .api }

249

/**

250

* State with throttled updates

251

* @param defaultValue - Initial state value

252

* @param wait - Throttle delay in milliseconds

253

* @returns Tuple of throttled value and setter

254

*/

255

function useThrottledState<T>(defaultValue: T, wait: number): [T, React.Dispatch<React.SetStateAction<T>>];

256

```

257

258

### useThrottledValue

259

260

Throttled value updates for performance optimization.

261

262

```typescript { .api }

263

/**

264

* Throttled value updates

265

* @param value - Value to throttle

266

* @param wait - Throttle delay in milliseconds

267

* @returns Throttled value

268

*/

269

function useThrottledValue<T>(value: T, wait: number): T;

270

```

271

272

**Usage Examples:**

273

274

```typescript

275

import { useThrottledValue, useThrottledCallback } from "@mantine/hooks";

276

277

function ScrollHandler() {

278

const [scrollY, setScrollY] = useState(0);

279

280

// Throttle scroll updates for performance

281

const throttledScrollY = useThrottledValue(scrollY, 100);

282

283

const handleScroll = useThrottledCallback(() => {

284

setScrollY(window.scrollY);

285

}, 16); // ~60fps

286

287

useEffect(() => {

288

window.addEventListener('scroll', handleScroll);

289

return () => window.removeEventListener('scroll', handleScroll);

290

}, [handleScroll]);

291

292

return <div>Scroll position: {throttledScrollY}</div>;

293

}

294

```

295

296

## Performance Patterns

297

298

### Search Optimization

299

300

```typescript

301

import { useDebouncedCallback, useDebouncedValue } from "@mantine/hooks";

302

303

function OptimizedSearch() {

304

const [query, setQuery] = useState('');

305

const [results, setResults] = useState([]);

306

const [loading, setLoading] = useState(false);

307

308

// Debounce the search function

309

const debouncedSearch = useDebouncedCallback(async (searchTerm: string) => {

310

if (!searchTerm.trim()) {

311

setResults([]);

312

return;

313

}

314

315

setLoading(true);

316

try {

317

const response = await searchAPI(searchTerm);

318

setResults(response.data);

319

} finally {

320

setLoading(false);

321

}

322

}, 300);

323

324

// Alternative: debounce the value

325

const [debouncedQuery] = useDebouncedValue(query, 300);

326

327

useEffect(() => {

328

debouncedSearch(query);

329

}, [query, debouncedSearch]);

330

331

return (

332

<div>

333

<input

334

value={query}

335

onChange={(e) => setQuery(e.target.value)}

336

placeholder="Search..."

337

/>

338

{loading && <div>Searching...</div>}

339

<SearchResults results={results} />

340

</div>

341

);

342

}

343

```

344

345

### Animation Control

346

347

```typescript

348

import { useInterval, useTimeout } from "@mantine/hooks";

349

350

function AnimationController() {

351

const [progress, setProgress] = useState(0);

352

const [isPlaying, setIsPlaying] = useState(false);

353

354

const animation = useInterval(() => {

355

setProgress(p => {

356

if (p >= 100) {

357

animation.stop();

358

setIsPlaying(false);

359

return 100;

360

}

361

return p + 1;

362

});

363

}, 50);

364

365

const resetTimeout = useTimeout(() => {

366

setProgress(0);

367

}, 1000);

368

369

const startAnimation = () => {

370

setIsPlaying(true);

371

animation.start();

372

};

373

374

const resetAnimation = () => {

375

animation.stop();

376

setIsPlaying(false);

377

resetTimeout.start();

378

};

379

380

return (

381

<div>

382

<div style={{ width: `${progress}%`, height: '20px', background: 'blue' }} />

383

<button onClick={startAnimation} disabled={isPlaying}>

384

Start

385

</button>

386

<button onClick={resetAnimation}>

387

Reset

388

</button>

389

</div>

390

);

391

}

392

```