or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bom.mddom.mdframework-integration.mdindex.mdtypes.mdutilities.md

utilities.mddocs/

0

# Utilities & Performance APIs

1

2

Comprehensive utility functions, performance monitoring tools, event management, and optimization helpers for cross-platform Taro development.

3

4

## Overview

5

6

The utilities module provides essential tools for building performant cross-platform applications:

7

8

- **Performance Monitoring**: Timing, profiling, and performance measurement

9

- **Function Utilities**: Throttling, debouncing, and execution control

10

- **DOM Utilities**: Element type checking and manipulation helpers

11

- **Event Management**: Global event center and communication

12

- **Async Operations**: Next tick scheduling and update coordination

13

- **Hydration System**: DOM to mini-program data conversion

14

- **Router Utilities**: URL manipulation and navigation helpers

15

- **Cache Management**: Context-aware data caching

16

- **Options Configuration**: Runtime behavior configuration

17

18

## Performance APIs

19

20

### Performance Monitoring

21

22

```typescript { .api }

23

import { perf } from '@tarojs/runtime'

24

25

interface Performance {

26

// Timing methods

27

start(id: string): void

28

stop(id: string, now?: number): void

29

delayStop(id: string, delay?: number): void

30

31

// Internal timing storage

32

timers: Map<string, number>

33

}

34

35

const perf: Performance

36

```

37

38

#### Key Features

39

40

- **High-resolution Timing**: Uses `performance.now()` when available, falls back to `Date.now()`

41

- **Automatic Logging**: Logs timing results to console with formatted output

42

- **Delayed Stopping**: Debounced timing for frequent operations

43

- **Memory Management**: Automatic cleanup of completed timers

44

45

#### Usage Examples

46

47

```typescript

48

// Basic performance timing

49

perf.start('component-render')

50

// ... component rendering logic

51

perf.stop('component-render') // Logs: "component-render took X ms"

52

53

// Manual timing with custom timestamp

54

const startTime = performance.now()

55

// ... some operation

56

perf.stop('custom-operation', startTime)

57

58

// Delayed timing (debounced)

59

perf.start('frequent-operation')

60

perf.delayStop('frequent-operation', 100) // Waits 100ms before logging

61

62

// Multiple timing sessions

63

perf.start('data-fetch')

64

const data = await fetchData()

65

perf.stop('data-fetch')

66

67

perf.start('data-process')

68

const processed = processData(data)

69

perf.stop('data-process')

70

71

// Nested timing

72

perf.start('full-operation')

73

perf.start('sub-operation-1')

74

// ... work

75

perf.stop('sub-operation-1')

76

77

perf.start('sub-operation-2')

78

// ... more work

79

perf.stop('sub-operation-2')

80

perf.stop('full-operation')

81

```

82

83

## Function Utilities

84

85

### throttle

86

87

```typescript { .api }

88

import { throttle } from '@tarojs/runtime'

89

90

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

91

fn: T,

92

threshold?: number,

93

scope?: any

94

): T

95

96

// Default threshold: 250ms

97

```

98

99

#### Key Features

100

101

- **Leading and Trailing**: Executes immediately and after threshold

102

- **Context Preservation**: Maintains `this` context when scope provided

103

- **Return Value**: Returns result of first execution during threshold period

104

105

#### Usage Examples

106

107

```typescript

108

// Basic throttling

109

const expensiveFunction = (data: string) => {

110

console.log('Processing:', data)

111

// Expensive computation

112

}

113

114

const throttledFn = throttle(expensiveFunction, 1000)

115

116

// Multiple rapid calls - only executes every 1000ms

117

throttledFn('call 1') // Executes immediately

118

throttledFn('call 2') // Ignored

119

throttledFn('call 3') // Ignored

120

// ... 1000ms later, executes with last arguments

121

122

// Scroll event throttling

123

const handleScroll = throttle((event: Event) => {

124

const scrollTop = (event.target as Element).scrollTop

125

console.log('Scroll position:', scrollTop)

126

}, 100)

127

128

window.addEventListener('scroll', handleScroll)

129

130

// Resize handler with context

131

class ResponsiveComponent {

132

threshold = 768

133

134

handleResize = throttle(function(this: ResponsiveComponent) {

135

if (window.innerWidth < this.threshold) {

136

this.enterMobileMode()

137

} else {

138

this.enterDesktopMode()

139

}

140

}, 250, this)

141

142

enterMobileMode() { /* ... */ }

143

enterDesktopMode() { /* ... */ }

144

}

145

```

146

147

### debounce

148

149

```typescript { .api }

150

import { debounce } from '@tarojs/runtime'

151

152

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

153

fn: T,

154

ms?: number,

155

scope?: any

156

): T

157

158

// Default delay: 250ms

159

```

160

161

#### Key Features

162

163

- **Trailing Execution**: Only executes after delay period with no new calls

164

- **Context Preservation**: Maintains `this` context when scope provided

165

- **Cancellation**: Automatically cancels previous delayed executions

166

167

#### Usage Examples

168

169

```typescript

170

// Basic debouncing

171

const searchFunction = (query: string) => {

172

console.log('Searching for:', query)

173

// API call

174

}

175

176

const debouncedSearch = debounce(searchFunction, 500)

177

178

// Rapid typing - only searches after 500ms of no input

179

debouncedSearch('a') // Cancelled

180

debouncedSearch('ap') // Cancelled

181

debouncedSearch('app') // Cancelled

182

debouncedSearch('apple') // Executes after 500ms

183

184

// Form validation

185

const validateForm = debounce((formData: FormData) => {

186

// Validate form fields

187

console.log('Validating form...')

188

}, 300)

189

190

// API call debouncing

191

const saveData = debounce(async (data: any) => {

192

try {

193

await api.saveUserData(data)

194

console.log('Data saved successfully')

195

} catch (error) {

196

console.error('Save failed:', error)

197

}

198

}, 1000)

199

200

// Method debouncing with context

201

class AutoSave {

202

data: any = {}

203

204

updateData(key: string, value: any) {

205

this.data[key] = value

206

this.debouncedSave()

207

}

208

209

debouncedSave = debounce(function(this: AutoSave) {

210

console.log('Auto-saving data:', this.data)

211

// Save to storage

212

}, 2000, this)

213

}

214

```

215

216

## DOM Utilities

217

218

### Element Type Checking

219

220

```typescript { .api }

221

import { isElement, isText, isComment } from '@tarojs/runtime'

222

223

// Element type checks

224

function isElement(node: TaroNode): node is TaroElement

225

function isText(node: TaroNode): node is TaroText

226

function isComment(node: TaroNode): boolean

227

```

228

229

#### Usage Examples

230

231

```typescript

232

// Type-safe DOM manipulation

233

function processNode(node: TaroNode) {

234

if (isElement(node)) {

235

// TypeScript knows this is TaroElement

236

console.log('Element tag:', node.tagName)

237

console.log('Element attributes:', node.attributes)

238

node.setAttribute('processed', 'true')

239

} else if (isText(node)) {

240

// TypeScript knows this is TaroText

241

console.log('Text content:', node.textContent)

242

node.textContent = node.textContent.trim()

243

} else if (isComment(node)) {

244

console.log('Comment node found')

245

// Handle comment node

246

}

247

}

248

249

// Filter node collections

250

function getElements(nodes: TaroNode[]): TaroElement[] {

251

return nodes.filter(isElement)

252

}

253

254

function getTextNodes(nodes: TaroNode[]): TaroText[] {

255

return nodes.filter(isText)

256

}

257

258

// DOM traversal

259

function walkDOM(node: TaroNode, callback: (node: TaroNode) => void) {

260

callback(node)

261

262

if (isElement(node)) {

263

node.childNodes.forEach(child => walkDOM(child, callback))

264

}

265

}

266

```

267

268

### Property Utilities

269

270

```typescript { .api }

271

import {

272

isHasExtractProp,

273

isParentBinded,

274

shortcutAttr

275

} from '@tarojs/runtime'

276

277

// Property extraction check

278

function isHasExtractProp(element: TaroElement): boolean

279

280

// Event binding check

281

function isParentBinded(element: TaroElement, eventType: string): boolean

282

283

// Attribute shortcuts

284

function shortcutAttr(key: string): string

285

```

286

287

#### Usage Examples

288

289

```typescript

290

// Check if element has extractable properties

291

const element = document.createElement('custom-component')

292

element.setAttribute('custom-prop', 'value')

293

294

if (isHasExtractProp(element)) {

295

console.log('Element has non-standard properties')

296

// Handle custom property extraction

297

}

298

299

// Check event delegation

300

const child = document.createElement('button')

301

const parent = document.createElement('view')

302

parent.addEventListener('tap', handleTap)

303

parent.appendChild(child)

304

305

if (isParentBinded(child, 'tap')) {

306

console.log('Parent handles tap events')

307

// Skip adding duplicate listener

308

} else {

309

child.addEventListener('tap', handleTap)

310

}

311

312

// Attribute shortcuts

313

console.log(shortcutAttr('className')) // 'class'

314

console.log(shortcutAttr('htmlFor')) // 'for'

315

```

316

317

### ID Generation

318

319

```typescript { .api }

320

import { incrementId } from '@tarojs/runtime'

321

322

function incrementId(): () => string

323

```

324

325

#### Key Features

326

327

- **Unique IDs**: Generates unique identifiers using A-Z, a-z sequence

328

- **Deterministic**: Consistent ID generation across sessions

329

- **Performance**: Fast generation without collision checking

330

331

#### Usage Examples

332

333

```typescript

334

// Create ID generator

335

const getId = incrementId()

336

337

// Generate unique IDs

338

const id1 = getId() // 'A'

339

const id2 = getId() // 'B'

340

const id3 = getId() // 'C'

341

// ... continues through alphabet

342

343

// Use in component creation

344

function createUniqueElement(tagName: string): TaroElement {

345

const element = document.createElement(tagName)

346

element.id = getId()

347

return element

348

}

349

350

// Multiple generators for different purposes

351

const nodeIdGen = incrementId()

352

const componentIdGen = incrementId()

353

354

const nodeId = nodeIdGen() // Independent sequence

355

const componentId = componentIdGen() // Independent sequence

356

```

357

358

## Event Management

359

360

### Event Center

361

362

```typescript { .api }

363

import { eventCenter, Events } from '@tarojs/runtime'

364

365

interface EventsType {

366

// Event registration

367

on(eventName: string, listener: Function, context?: any): EventsType

368

once(eventName: string, listener: Function, context?: any): EventsType

369

370

// Event emission

371

trigger(eventName: string, ...args: any[]): EventsType

372

emit(eventName: string, ...args: any[]): EventsType

373

374

// Event removal

375

off(eventName?: string, listener?: Function, context?: any): EventsType

376

}

377

378

const eventCenter: EventsType

379

```

380

381

#### Key Features

382

383

- **Global Communication**: Cross-component and cross-page event communication

384

- **Context Binding**: Automatic `this` binding for event handlers

385

- **One-time Events**: Support for single-execution event handlers

386

- **Flexible Removal**: Remove specific listeners or all listeners for an event

387

388

#### Usage Examples

389

390

```typescript

391

// Basic event communication

392

eventCenter.on('user-login', (user: User) => {

393

console.log('User logged in:', user.name)

394

updateUserInterface(user)

395

})

396

397

eventCenter.trigger('user-login', { name: 'John', id: '123' })

398

399

// Cross-component communication

400

// Component A

401

class ComponentA extends React.Component {

402

sendMessage = () => {

403

eventCenter.trigger('message-sent', {

404

from: 'ComponentA',

405

message: 'Hello from A'

406

})

407

}

408

}

409

410

// Component B

411

class ComponentB extends React.Component {

412

componentDidMount() {

413

eventCenter.on('message-sent', this.handleMessage, this)

414

}

415

416

componentWillUnmount() {

417

eventCenter.off('message-sent', this.handleMessage, this)

418

}

419

420

handleMessage = (data: { from: string, message: string }) => {

421

console.log(`Message from ${data.from}: ${data.message}`)

422

}

423

}

424

425

// One-time events

426

eventCenter.once('app-initialized', () => {

427

console.log('App initialization complete')

428

// This handler will only run once

429

})

430

431

// Event cleanup

432

class EventfulComponent {

433

listeners = new Map()

434

435

componentDidMount() {

436

// Store listeners for cleanup

437

this.listeners.set('data-update', this.handleDataUpdate)

438

this.listeners.set('user-action', this.handleUserAction)

439

440

// Register events

441

eventCenter.on('data-update', this.handleDataUpdate, this)

442

eventCenter.on('user-action', this.handleUserAction, this)

443

}

444

445

componentWillUnmount() {

446

// Clean up all listeners

447

this.listeners.forEach((handler, eventName) => {

448

eventCenter.off(eventName, handler, this)

449

})

450

}

451

452

handleDataUpdate = (data: any) => { /* ... */ }

453

handleUserAction = (action: any) => { /* ... */ }

454

}

455

```

456

457

## Async Operations

458

459

### nextTick

460

461

```typescript { .api }

462

import { nextTick } from '@tarojs/runtime'

463

464

function nextTick(

465

callback: Function,

466

context?: Record<string, any>

467

): void

468

```

469

470

#### Key Features

471

472

- **Update Coordination**: Executes callback after next DOM update cycle

473

- **Context Binding**: Supports custom execution context

474

- **Timeout Fallback**: Uses `setTimeout` if update queue unavailable

475

476

#### Usage Examples

477

478

```typescript

479

// Wait for DOM updates

480

function updateComponent() {

481

// Modify DOM

482

element.textContent = 'Updated content'

483

element.className = 'new-class'

484

485

// Execute after DOM update

486

nextTick(() => {

487

console.log('DOM updates completed')

488

// Safe to read computed styles, dimensions, etc.

489

const rect = element.getBoundingClientRect()

490

console.log('Element dimensions:', rect)

491

})

492

}

493

494

// React integration

495

class ReactComponent extends React.Component {

496

updateData = () => {

497

this.setState({ data: newData }, () => {

498

// Execute after React update

499

nextTick(() => {

500

// Execute after Taro DOM update

501

console.log('Both React and Taro updates complete')

502

})

503

})

504

}

505

}

506

507

// Custom context

508

const context = { name: 'CustomContext' }

509

nextTick(function() {

510

console.log('Context:', this.name) // 'CustomContext'

511

}, context)

512

513

// Chained operations

514

function performComplexUpdate() {

515

// Step 1: Update data

516

updateApplicationData()

517

518

nextTick(() => {

519

// Step 2: Update DOM after data update

520

updateDOMElements()

521

522

nextTick(() => {

523

// Step 3: Final operations after DOM update

524

performFinalOperations()

525

})

526

})

527

}

528

```

529

530

### Hydration System

531

532

```typescript { .api }

533

import { hydrate } from '@tarojs/runtime'

534

535

function hydrate(node: TaroElement | TaroText): MiniData

536

537

interface MiniData {

538

[key: string]: any

539

// Converted mini-program data structure

540

}

541

```

542

543

#### Key Features

544

545

- **DOM to Data**: Converts DOM nodes to mini-program data structure

546

- **Component Aliasing**: Maps generic components to platform-specific ones

547

- **View Optimization**: Optimizes view types for performance

548

- **Property Filtering**: Filters out non-standard properties

549

550

#### Usage Examples

551

552

```typescript

553

// Hydrate DOM tree for mini-program

554

const element = document.createElement('view')

555

element.className = 'container'

556

element.textContent = 'Hello World'

557

element.style.color = 'red'

558

559

const miniData = hydrate(element)

560

console.log('Mini-program data:', miniData)

561

// Output: { cn: [{ v: 'Hello World' }], st: { color: 'red' }, ... }

562

563

// Hydrate complex component tree

564

const complexElement = document.createElement('scroll-view')

565

complexElement.setAttribute('scroll-y', 'true')

566

567

const listItem = document.createElement('view')

568

listItem.className = 'list-item'

569

listItem.textContent = 'Item 1'

570

complexElement.appendChild(listItem)

571

572

const hydratedData = hydrate(complexElement)

573

console.log('Complex hydration:', hydratedData)

574

575

// Use in custom rendering

576

function customRender(virtualDOM: TaroElement) {

577

const miniData = hydrate(virtualDOM)

578

579

// Send to mini-program

580

if (getCurrentInstance().page) {

581

getCurrentInstance().page.setData({

582

customComponent: miniData

583

})

584

}

585

}

586

```

587

588

## Router Utilities

589

590

### URL Utilities

591

592

```typescript { .api }

593

import {

594

addLeadingSlash,

595

hasBasename,

596

stripBasename,

597

stripTrailing,

598

stripSuffix

599

} from '@tarojs/runtime'

600

601

// URL formatting

602

function addLeadingSlash(path: string): string

603

function stripTrailing(path: string): string

604

function stripSuffix(path: string, suffix: string): string

605

606

// Basename handling

607

function hasBasename(path: string, basename: string): boolean

608

function stripBasename(path: string, basename: string): string

609

```

610

611

#### Usage Examples

612

613

```typescript

614

// URL formatting

615

console.log(addLeadingSlash('path/to/page')) // '/path/to/page'

616

console.log(addLeadingSlash('/path/to/page')) // '/path/to/page'

617

618

console.log(stripTrailing('/path/to/page/')) // '/path/to/page'

619

console.log(stripTrailing('/path/to/page')) // '/path/to/page'

620

621

console.log(stripSuffix('/page.html', '.html')) // '/page'

622

console.log(stripSuffix('/page', '.html')) // '/page'

623

624

// Basename handling

625

const basename = '/app'

626

const fullPath = '/app/pages/home'

627

628

console.log(hasBasename(fullPath, basename)) // true

629

console.log(stripBasename(fullPath, basename)) // '/pages/home'

630

631

// Route processing

632

function processRoute(rawPath: string, appBasename: string = ''): string {

633

let path = addLeadingSlash(rawPath)

634

path = stripTrailing(path)

635

636

if (appBasename && hasBasename(path, appBasename)) {

637

path = stripBasename(path, appBasename)

638

}

639

640

return path

641

}

642

643

console.log(processRoute('pages/home/', '/myapp')) // '/pages/home'

644

```

645

646

### Page Utilities

647

648

```typescript { .api }

649

import { getHomePage, getCurrentPage } from '@tarojs/runtime'

650

651

// Get application home page

652

function getHomePage(): string

653

654

// Get current page path

655

function getCurrentPage(): string

656

```

657

658

#### Usage Examples

659

660

```typescript

661

// Navigation helpers

662

function navigateHome() {

663

const homePage = getHomePage()

664

wx.navigateTo({ url: homePage })

665

}

666

667

function refreshCurrentPage() {

668

const currentPage = getCurrentPage()

669

wx.redirectTo({ url: currentPage })

670

}

671

672

// Breadcrumb generation

673

function generateBreadcrumb(): string[] {

674

const current = getCurrentPage()

675

const home = getHomePage()

676

677

const breadcrumb = [home]

678

if (current !== home) {

679

breadcrumb.push(current)

680

}

681

682

return breadcrumb

683

}

684

```

685

686

## Cache Management

687

688

### RuntimeCache

689

690

```typescript { .api }

691

import { RuntimeCache } from '@tarojs/runtime'

692

693

class RuntimeCache<T = any> {

694

// Cache operations

695

set(key: string, value: T): void

696

get(key: string): T | undefined

697

has(key: string): boolean

698

delete(key: string): boolean

699

clear(): void

700

701

// Iteration

702

keys(): IterableIterator<string>

703

values(): IterableIterator<T>

704

entries(): IterableIterator<[string, T]>

705

706

// Properties

707

readonly size: number

708

}

709

```

710

711

#### Key Features

712

713

- **Context-aware**: Automatic cleanup based on page context

714

- **Type-safe**: Generic type support for cached values

715

- **Memory Management**: Automatic cleanup to prevent memory leaks

716

717

#### Usage Examples

718

719

```typescript

720

// Create cache instance

721

const pageCache = new RuntimeCache<PageData>()

722

const componentCache = new RuntimeCache<ComponentState>()

723

724

// Cache page data

725

interface PageData {

726

userInfo: User

727

settings: AppSettings

728

}

729

730

pageCache.set('user-profile', {

731

userInfo: { id: '123', name: 'John' },

732

settings: { theme: 'dark', lang: 'en' }

733

})

734

735

// Retrieve cached data

736

const cachedData = pageCache.get('user-profile')

737

if (cachedData) {

738

console.log('Cached user:', cachedData.userInfo.name)

739

}

740

741

// Cache management

742

console.log('Cache size:', pageCache.size)

743

console.log('Has user data:', pageCache.has('user-profile'))

744

745

// Iterate cache

746

for (const [key, value] of pageCache.entries()) {

747

console.log(`Cached ${key}:`, value)

748

}

749

750

// Cleanup

751

pageCache.delete('old-data')

752

pageCache.clear() // Clear all cache

753

754

// Component state caching

755

class CacheableComponent extends React.Component {

756

cache = new RuntimeCache<ComponentState>()

757

758

componentDidMount() {

759

const cached = this.cache.get('component-state')

760

if (cached) {

761

this.setState(cached)

762

}

763

}

764

765

componentWillUnmount() {

766

this.cache.set('component-state', this.state)

767

}

768

}

769

```

770

771

## Runtime Configuration

772

773

### Options

774

775

```typescript { .api }

776

import { options } from '@tarojs/runtime'

777

778

interface Options {

779

prerender: boolean // Enable prerendering (default: true)

780

debug: boolean // Enable debug mode (default: false)

781

}

782

783

const options: Options

784

```

785

786

#### Usage Examples

787

788

```typescript

789

// Configure runtime behavior

790

options.prerender = false // Disable prerendering

791

options.debug = true // Enable debug logging

792

793

// Conditional behavior

794

if (options.debug) {

795

console.log('Debug mode enabled')

796

// Additional logging

797

}

798

799

if (options.prerender) {

800

// Prerender optimization enabled

801

performPrerenderOptimizations()

802

}

803

804

// Environment-based configuration

805

if (process.env.NODE_ENV === 'development') {

806

options.debug = true

807

}

808

809

if (process.env.NODE_ENV === 'production') {

810

options.prerender = true

811

options.debug = false

812

}

813

```

814

815

## Polyfills

816

817

### handlePolyfill

818

819

```typescript { .api }

820

import { handlePolyfill } from '@tarojs/runtime'

821

822

function handlePolyfill(): void

823

```

824

825

#### Key Features

826

827

- **Conditional Polyfills**: Only applies needed polyfills based on environment

828

- **Standard APIs**: Polyfills for `Object.assign`, `Array.find`, etc.

829

- **Web-specific**: `IntersectionObserver` polyfill for web platforms

830

831

#### Usage Examples

832

833

```typescript

834

// Apply polyfills (usually done automatically)

835

handlePolyfill()

836

837

// Manual polyfill check

838

if (typeof Object.assign !== 'function') {

839

handlePolyfill() // Will apply Object.assign polyfill

840

}

841

842

// Environment-specific polyfills

843

if (typeof window !== 'undefined') {

844

// Web environment - full polyfills applied

845

handlePolyfill()

846

}

847

```

848

849

## Helper Functions

850

851

### General Utilities

852

853

```typescript { .api }

854

import { extend, getComponentsAlias, convertNumber2PX } from '@tarojs/runtime'

855

856

// Object extension

857

function extend(target: any, ...sources: any[]): any

858

859

// Component mapping

860

function getComponentsAlias(): Record<string, string>

861

862

// Unit conversion

863

function convertNumber2PX(value: number | string): string

864

```

865

866

#### Usage Examples

867

868

```typescript

869

// Object extension (like Object.assign)

870

const base = { a: 1, b: 2 }

871

const extended = extend(base, { b: 3, c: 4 }, { d: 5 })

872

console.log(extended) // { a: 1, b: 3, c: 4, d: 5 }

873

874

// Component aliasing

875

const aliases = getComponentsAlias()

876

console.log(aliases) // { 'scroll-view': 'ScrollView', ... }

877

878

// Convert to px units

879

console.log(convertNumber2PX(16)) // '16px'

880

console.log(convertNumber2PX('16')) // '16px'

881

console.log(convertNumber2PX('16px')) // '16px'

882

883

// Use in style processing

884

function normalizeStyleValue(value: any): string {

885

if (typeof value === 'number') {

886

return convertNumber2PX(value)

887

}

888

return String(value)

889

}

890

```

891

892

## Environment & Runtime APIs

893

894

### Environment Detection

895

896

```typescript { .api }

897

import { env } from '@tarojs/runtime'

898

899

interface Env {

900

window: Window | {}

901

document: Document | {}

902

}

903

904

const env: Env

905

```

906

907

#### Usage Examples

908

909

```typescript

910

// Check platform capabilities

911

if (env.window && 'addEventListener' in env.window) {

912

// Web platform - use native APIs

913

env.window.addEventListener('resize', handleResize)

914

} else {

915

// Mini-program platform - use alternatives

916

// Handle resize through Taro lifecycle

917

}

918

919

// Safe document access

920

if (env.document && 'createElement' in env.document) {

921

// Native DOM available

922

const element = env.document.createElement('div')

923

} else {

924

// Use Taro DOM polyfills

925

const element = document.createElement('view')

926

}

927

```

928

929

### URL Parsing

930

931

```typescript { .api }

932

import { parseUrl } from '@tarojs/runtime'

933

934

function parseUrl(url?: string): {

935

href: string

936

origin: string

937

protocol: string

938

hostname: string

939

host: string

940

port: string

941

pathname: string

942

search: string

943

hash: string

944

}

945

```

946

947

#### Usage Examples

948

949

```typescript

950

// Parse complete URLs

951

const parsed = parseUrl('https://example.com:8080/path?query=value#section')

952

console.log(parsed.hostname) // 'example.com'

953

console.log(parsed.port) // '8080'

954

console.log(parsed.pathname) // '/path'

955

console.log(parsed.search) // '?query=value'

956

console.log(parsed.hash) // '#section'

957

958

// Handle partial URLs

959

const relative = parseUrl('/api/users?page=1')

960

console.log(relative.pathname) // '/api/users'

961

console.log(relative.search) // '?page=1'

962

963

// Safe URL parsing

964

function getUrlParts(url: string) {

965

try {

966

const parts = parseUrl(url)

967

return parts.pathname + parts.search

968

} catch (error) {

969

return '/'

970

}

971

}

972

```

973

974

### Hooks System

975

976

```typescript { .api }

977

import { hooks } from '@tarojs/runtime'

978

979

interface Hooks {

980

call<T>(hookName: string, ...args: any[]): T

981

tap(hookName: string, callback: Function): void

982

}

983

984

const hooks: Hooks

985

```

986

987

#### Usage Examples

988

989

```typescript

990

// Register hook handlers

991

hooks.tap('beforeMount', (component) => {

992

console.log('Component mounting:', component)

993

})

994

995

hooks.tap('afterUpdate', (instance) => {

996

console.log('Component updated:', instance)

997

})

998

999

// Call hooks programmatically

1000

const eventCenter = hooks.call('getEventCenter', Events)

1001

const router = hooks.call('getRouter')

1002

1003

// Custom hook integration

1004

hooks.tap('customEvent', (data) => {

1005

// Handle custom events

1006

processCustomData(data)

1007

})

1008

1009

// Trigger custom hooks

1010

hooks.call('customEvent', { type: 'user-action', payload: data })

1011

```

1012

1013

The utilities module provides essential tools for building performant, maintainable cross-platform applications with comprehensive performance monitoring, event management, and optimization capabilities.