Tips for maximizing efficiency when working with both a collection of items and additional elements inside and outside of the array

I am working with an array of items and need to dynamically add or remove extra items while dragging. The items are being accessed 60 times per second, and I'm curious about the performance impact of my current implementation.

class Hello {

  get constraints() {
    return [...this._constraints, ...(this._extras | [])]
  }

  _extras: Array<number> | undefined

  constructor(readonly _constraints: Array<number>) {
}
}

let hello = new Hello([1,2,3,4, 100000])
hello._extras = [5, 6, 7]

function step() {
  console.log(hello.constraints)
    requestAnimationFrame(step)
}

requestAnimationFrame(step)

At the moment, the arrays are cloned each time the items are accessed. I'm interested in understanding the penalty for this approach and exploring better coding practices for this kind of behavior.

Answer №1

Update the constraints array dynamically only when there are changes to the _extras. Implement a method to handle these updates.

class UpdateArray {
    constraints: Array<number>;
    
    setExtras(extras: Array<number>) {
        this.constraints = [...this._constraints, ...extras];
    }
    
    _extras: Array<number> | undefined

    constructor(readonly _constraints: Array<number>) {
        this.constraints = _constraints;
    }
}

const newArray = new UpdateArray([1, 2, 3, 4, 100000])
newArray.setExtras([5, 6, 7]);

function update() {
    console.log(newArray.constraints)
    requestAnimationFrame(update)
}
requestAnimationFrame(update)

Answer №2

Utilizing the requestAnimationFrame method implies that this process can be asynchronous, but with a sense of high priority?

If you integrate rxjs into your project and import the necessary rxjs components, you could implement something similar to the code snippet below...

const FRAMES_PER_SECOND = 15;

const initialConstraints = [1,2,3,4, 100000];
const others$: BehaviorSubject<number[]> = new BehaviorSubject();

// Subscribed to, emits combined
// constraints once per time
// others$.next(numArray) is called.
const constraints$ = others$.pipe(
  map(
    others => !others || !others.length ? initialConstraints
    : [...initialConstraints, ...others]
  )
);

// Subscribed to, emits a MouseEvent
// every time the mouse is moved
const moves$ = fromEvent(
  document,
  'mousemove'
);

type StepArgument = [MouseEvent, number[]];

// Subscribed, emits a two-element
// array each time others$.next is
// called or the mouse is moved, with
// actions executed as part of the
// animation scheduler.
const both$: Observable<StepArgument> = scheduled(
  moves$.pipe(
    debounceTime(1000 / FRAMES_PER_SECOND),
    combineLatestWith(constraints$)
  ),
  animationFrameScheduler
);

// Upon invocation, `both$` will emit values
// into the step argument until the subscribed
// object's `unsubscribe` function is invoked. 
function watchMouse(step: ((arg: StepArgument) => void) {
  return both$.subscribe(step);
}

In this context, the merging of two arrays takes place whenever the state of others$ changes. The code structure aims for readability.

This approach also provides room for future adaptability. If each variable constraint is represented by its own observable, an alternative implementation could be instead:

function getOtherObservables(): Observable<number | number[]>[] {?? whatever ??}

const constraints$: Observable<number[]> = of(initialConstraints).pipe(
  combineLatest(...getOtherObservables()),
  map(a => a.flat()),
  shareReplay(1)
);

It might be more efficient not to generate a new two-element array per mouse event, however, this method prioritizes readability and flexibility while maintaining performance by limiting updates to a maximum of 15 frames/second and only performing operations when necessary.

Note: When subscribing to both$, it may not emit any values until the mouse moves since it starts monitoring the mouse event stream without recollection of prior movements. Solutions to address this issue are available if required.

(Disclaimer: example code has not been debugged)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Locate an element within an array of strings to refine the contents of a flatlist

Currently, I have a FlatList that I am attempting to filter using multiple inputs from dropdown selectors. Here is the code snippet for my FlatList component: <FlatList style={styles.list} data={data.filter(filteredUsers)} ...

Rollup's watch/build feature is slow to catch up with a single change made

I have a react component library written in typescript that I am using within a monorepo with Lerna. However, I've noticed an issue when working directly in the package or watching for changes through Lerna. Whenever I make changes to the code and sa ...

"Implementing a retry feature for Angular http requests triggered by a button

Imagine having a situation where a component has a method that triggers an http request defined in a service. The observable is subscribed to within the component: Component: fetchData() { this.apiService.fetchDataFromServer().subscribe( respo ...

Challenges with TypeScript Interfaces When Using JSX.Element in React

I am attempting to define a type for an array in React, but I keep encountering the following error. Unfortunately, I can't figure out what is causing this issue. Can someone please assist me in identifying what I am missing? Thank you interface Row ...

Using Angular2, assign a value to the session and retrieve a value from the session

I am having trouble getting and setting a session. Here is my code: login_btnClick() { var NTLoginID = ((document.getElementById("NTLoginID") as HTMLInputElement).value); this._homeService.get(Global.BASE_USER_ENDPOINT + '/EmployeeDe ...

Unable to locate the resource when trying to query DynamoDB

I am having trouble accessing a DynamoDb table, as I keep encountering a "Resource not found" error. The table is set up like this; it's Active and located in the Paris Region (eu-west-3). https://i.sstatic.net/W0IZs.png This is the code snippet I ...

How can I change a ReactNode into a text format?

I am looking for a way to convert the following code snippet into a string while preserving Tailwind CSS and other elements. My project uses Next.js with TypeScript and Tailwind CSS. Input : export default function Header_1() { return ( <div clas ...

In Angular, dynamically updating ApexCharts series daily for real-time data visualization

I am currently working with apexchart and struggling to figure out how to properly utilize the updateseries feature. I have attempted to directly input the values but facing difficulties. HTML <apx-chart [chart]="{ type: ...

Is there a way to expand the web part width to fill the entire screen in SPFx 1.10?

After setting up SharePoint framework SPFx 1.10 with React template, I ran it on https://localhost:4321/temp/workbench.html and attempted to enable full bleed width by adding "supportsFullBleed": true in the "WebPartName.manifest.json" file, but ...

Implement the useState setter functionality within a child component

I need help figuring out how to properly type a useState setter that I'm trying to pass to a child component. const Parent = () => { const [count, setCount] = useState(0); return( Child count={count} setCount={setCount} /> ); } W ...

Combining arrays of objects sharing a common key yet varying in structure

Currently, I am facing a challenge while working on this problem using Typescript. It has been quite some time since I started working on it and I am hoping that the helpful community at StackOverflow could provide assistance :) The scenario involves two ...

Is there a way to locate a model using a value within a OneToMany connection?

I am trying to develop a function to retrieve a user model based on a specific value within a OneToMany relationship. Below is the function in question: async getUserViaPlatform(provider: string, id: string) { return await this.webUserRepository. ...

Disable alerts for specific files in Visual Studio 2017

I have a project that utilizes TypeScript and various external libraries. I am trying to find a solution to suppress all errors and warnings for files with the extensions .js, .ts, .d.ts, etc. located within the node_modules folder and a separate folder c ...

What is the best method for connecting a ref to a component that I am duplicating with React.cloneElement?

Hi everyone! I'm trying to pass a ref into my component so that I can access the variables on the component like state. The only problem is, I'm having trouble getting it to work. It needs to be functional for both classes and functions. Every t ...

Output Scalable Vector Graphics (SVG) content on a webpage

I need to include an SVG element in my Angular 2+ code. My goal is to provide users with the option to print the SVG element as it appears on the screen. <div class="floor-plan" id="printSectionId2" (drop)="onDrop($event)" (dragover)="onDragOver ...

The argument provided, which is of type 'any[]', cannot be assigned to a parameter of type 'A' because the property 'a' is missing in the 'any[]' type

As a newcomer to TypeScript, I am currently trying to grasp the workings of interfaces within a Class Method of a React Component. Despite creating a simple case for it, I am encountering errors similar to those described in this post. I would greatly app ...

A step-by-step guide on leveraging swagger-autogen in TypeScript applications

Is it possible to integrate the swagger-autogen module into a Typescript project? I have attempted multiple methods, but have been unsuccessful. The error message "Failed" keeps appearing when using a swagger.js file: const swaggerAutogen = require("swagge ...

"Utilize the handle property of a component when interacting with the window.onclick

In my component, I have a property called enableButtons which is set to true when I click on an ion-menu label. However, I want this property to revert to false if I click anywhere else. Here's the code I tried: export class ProfilePage implements OnI ...

Leverage RxJs Pipe for transforming Observables into various data types

Currently, I am dealing with an Observable<Recipe[]> that I need to transform into an array of a different class called ChartData[]. This transformed array will be used as a data source for creating highcharts graphs, such as column charts and pie ch ...

Guide on creating a universal template from a collection of interfaces

Two interfaces, AllTypes type: interface A { // ... } interface B { // ... } type AllTypes = A | B; How can I utilize generics to ensure that a function's argument is an object with either interface A or B? // pseudocode function test<T ...