Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(packages/sui-performance): add performance package #1794

Merged
merged 3 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/sui-performance/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# CHANGELOG
57 changes: 57 additions & 0 deletions packages/sui-performance/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# @s-ui/performance

> Performance utilities to make your web application go fast ⚡️

## Installation

```sh
npm install @s-ui/performance
```

## Usage

### Delay code execution

Use this function to delay the execution of an expensive operation and prioritize user actions. Keep in mind that it only delays the response by a maximum of 1 frame, an average of 8ms, which is too little for a human to notice for the types of major actions where you’d use this function.

```jsx
import {delayTask} from '@s-ui/performance';

export default function Example() {
const [counter, setCounter] = useState(0)

const handleClick = async () => {
setCounter(counter => counter + 1)

await delayTask()

work() // expensive work
}

return <button onClick={handleClick}>{counter}</button>
}
```

### Delay code execution until urgent

Use this function to delay the execution of an expensive operation while the main thread is idle, using [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback), and to prioritize user actions. This method ensures the execution is completed before the user leaves the page. It is especially useful for delaying tracking execution.

The `delayTaskUntilUrgent` function optionally receives an options object. The documentation can be found [here](https://github.com/redbus-labs/idlefy/tree/main?tab=readme-ov-file#methods) ([idlefy](https://github.com/redbus-labs/idlefy/tree/main) is used under the hood).

```jsx
import {delayTaskUntilUrgent} from '@s-ui/performance';

export default function Example() {
const [counter, setCounter] = useState(0)

const handleClick = async () => {
setCounter(counter => counter + 1)

await delayTaskUntilUrgent()

track() // expensive work
}

return <button onClick={handleClick}>{counter}</button>
}
```
26 changes: 26 additions & 0 deletions packages/sui-performance/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "@s-ui/performance",
"version": "1.0.0",
"description": "",
"type": "module",
"main": "lib/index.js",
"scripts": {
"lib": "babel --presets sui ./src --out-dir ./lib",
"prepublishOnly": "npm run lib",
"test:browser:watch": "NODE_ENV=test npm run test:browser -- --watch",
"test:browser": "NODE_ENV=test sui-test browser",
"test:server:watch": "npm run test:server -- --watch",
"test:server": "NODE_ENV=test sui-test server",
"test": "npm run test:server && npm run test:browser"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"idlefy": "1.1.1"
},
"peerDependencies": {},
"devDependencies": {
"@s-ui/test": "8"
}
}
18 changes: 18 additions & 0 deletions packages/sui-performance/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {IdleQueue} from 'idlefy'

const queue = new IdleQueue({ensureTasksRun: true})

export function delayTask() {
return new Promise(resolve => {
setTimeout(resolve, 100)
requestAnimationFrame(() => {
setTimeout(resolve, 0)
})
})
}

export function delayTaskUntilUrgent(options) {
return new Promise(resolve => {
queue.pushTask(resolve, options)
})
}
26 changes: 26 additions & 0 deletions packages/sui-performance/test/browser/indexSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {expect} from 'chai'
import sinon from 'sinon'

import {waitFor} from '@testing-library/react'

import {delayTask, delayTaskUntilUrgent} from '../../src/index.js'

describe('delayTask', () => {
it('should execute function', async () => {
const callback = sinon.spy()

delayTask().then(callback)

await waitFor(() => expect(callback.called).to.be.true)
})
})

describe('delayTaskUntilUrgent', () => {
it('should execute function', async () => {
const callback = sinon.spy()

delayTaskUntilUrgent().then(callback)

await waitFor(() => expect(callback.called).to.be.true)
})
})