HTML Canvas 2D is too slow

Please help me understand why the process of rendering on an HTML canvas in a 2D context takes so long with several frames falling out of the animation with a large number of points. Moreover, the execution time of the javascript code falls within the allotted 16ms by a large margin, and the main animation time is occupied by the work of the GPU, according to the Performance tab of the developer tools. I will indicate in advance that I am testing on the Google Chrome v122.0.6261.111 browser.

Here I have visualized the problem. In short, there are several datasets (7 to be specific). In each subsequent frame, I draw all data sets with a Y-axis offset of one pixel below the previous frame.
The code is quite primitive – no matrices or path objects. However, the use of matrices, etc. does not affect the problem – the time it takes to send data for rendering by javascript code is reduced, but the operating time of the GPU has almost no correlation with this fact.

    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
    ctx.beginPath()

    for (let dataset of datasets) {
        for (let i = 0; i < dataset.length; i++) {
            if (!i) ctx.moveTo(dataset[i][0], dataset[i][1] + count)
            else ctx.lineTo(dataset[i][0], dataset[i][1] + count)
        }
    }

    ctx.stroke()

I’ll give you a few screenshots to help you understand what we’re talking about.
Here is a performance measurement on the first frame. Please note that the javascript code execution time barely exceeds 1ms, and the GPU loading time is already more than 50ms! Naturally, several animation frames are dropped.
The situation changes as the data sets go beyond the canvas – the execution time of the javascript code does not change, and the GPU load time decreases accordingly. For example, here is the last frame with one data set on the canvas and the subsequent frames again with all the data sets shown. As you can see, as soon as we have to draw all the data sets in the visible area again, the graphics processor immediately falls under load, again leading to frame drops.

Several facts add interest to the problem:

  1. In Mozilla, animation is much smoother without such a colossal load on the GPU.
  2. If you reduce the range of Y values ​​without reducing the number of points for a line, then the animation is smoother. (That is, when the depicted data set tends to a straight line in shape)

In this regard, I have several questions for the community:

  1. Why does the GPU come into play?
  2. Is there somewhere a detailed description of the canvas rendering process under the browser hood?
  3. It seems that the data being drawn is sent to the GPU and sending this data takes a very long time. If this is at least partly true, then is it possible to somehow cache this data in the GPU and update only the transformation matrix? (Let me remind you that other methods known to me to optimize the rendering process (matrices, path objects) do not affect the problem in any way)
  4. On the other hand, the improvement in animation smoothness with a decrease in the range of Y values ​​indicates that the more pixels are covered on the canvas, the longer the rendering process takes. That is, the amount of data sent to the GPU has little effect on the operating time of the GPU. But if the GPU draws several pixels in parallel, then does it matter how long the line is…?

Thank you in advance, and I really hope that there will be people who can help me figure out at least some of the issues raised.

Trouble with parsing a string into a tree in JS

This code converts string into an array tree, but does so with a bug –

// I have this input
const input = "(1 (2 (4 5 6 (7) 108 (9)) 3))";

// and this function


class TreeNode {
  constructor(value) {
    this.value = value;
    this.children = [];
  }
}


function parseInput(input) {
  let root = null;
  let current = null;
  const stack = [];

  for (let i = 0; i < input.length; i++) {
    const char = input[i];

    if (char === '(') {
      if (current !== null) {
        const newNode = new TreeNode(current);
        if (stack.length > 0) {
          stack[stack.length - 1].children.push(newNode);
        } else {
          root = newNode;
        }
        stack.push(newNode);
        current = null;
      }
    } else if (char === ')') {
      stack.pop();
    } else if (char !== ' ' && char !== 'n') {
      let numStr = char;
      while (i + 1 < input.length && /d/.test(input[i + 1])) {
        numStr += input[++i];
      }
      const newNode = new TreeNode(parseInt(numStr));
      if (stack.length > 0) {
        stack[stack.length - 1].children.push(newNode);
      } else {
        root = newNode;
      }
      current = newNode.value;
    }
  }

  return root;
}


// And this function to print the parsed tree 


function printTree(node, depth = 0) {
  const indent = '  '.repeat(depth);
  console.log(`${indent}value: ${node.value}`);
  if (node.children.length > 0) {
    console.log(`${indent}children: [`);
    node.children.forEach((child) => printTree(child, depth + 1));
    console.log(`${indent}]`);
  }
}

const parsed = parseInput(input);
console.log(printTree(parsed));
value: 1
children: [
  value: 2
  value: 2
  children: [
    value: 4
    value: 5
    value: 6
    value: 6
    children: [
      value: 7
    ]
    value: 108
    value: 108
    children: [
      value: 9
    ]
  ]
  value: 3
]

Nodes, that have children, get double printed. I.E the output should be like this –

value: 1
children: [
  value: 2
  children: [
    value: 4
    value: 5
    value: 6
    children: [
      value: 7
    ]
    value: 108
    children: [
      value: 9
    ]
  ]
  value: 3
]

PLS, give me at least a hint at what wrong with my code, I have a bit more then an hour to send it!!!

Tinkering the code, commenting out the code, asking AI, searching web

rxjs insert delayed data

Into a rxjs-Stream i want to conditionaly insert data, a delay and then the original event.

from(Array(10).keys())
  .pipe(
    map(i => ({ data: i })),
    concatMap(e => {
      if (e.data === 3) {
        return of(e)
          .pipe(
            delay(500),
          );
      }
      return of(e);
    }),
  )
  .subscribe(i => console.log(i));

This creates a delay before { data: 3 }.

But i want to emit { data: 'a' }, delay, { data: 3 }.

Interacting with a specific checkbox with all having the same type and ID

I need to click on a checkbox for a specific row based on input criteria so someone might input say the Number (e.g 9) and the code needs to enable the check box.

However, all of the checkboxes have the same ID and type of <input "type="checkbox" id="checkBox" style="outline-offset: -2px;">.

I am trying to use Javascript to do this but I’m not sure if its possible?

enter image description here

How I can detect a value has changed upon a textarea that has been initialized using easyeditor?

I have initialized a rich text editor for a textarea using the [easyeditor][1] library:

$(document).ready(function(){
    $("#editor").easyEditor({
         buttons: ['bold', 'italic', 'link', 'h2', 'h3', 'h4', 'alignleft', 'aligncenter', 'alignright']
     });
})
<link rel="stylesheet" href="https://unpkg.com/[email protected]/src/easyeditor.css">

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://unpkg.com/[email protected]/src/jquery.easyeditor.js"></script>

<textarea id="editor"></textarea>

And I want upon a change into the textarea to trigger some logic (eg. form validation) how I can do this?
[1]: https://www.npmjs.com/package/easyeditor?activeTab=readme

Executing test using Jest in Node Express Rest API

I am doing Integration test using Jest in my node express Rest API application. I am using node version 18.19.1 and using Common Javascript Modules(cjs). I am getting Jest encountered an unexpected token error even thought I made a plenty of changes in my jest.config.js. Nothing helps to fix this issue.


 FAIL  test/user.test.js
  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    /node_modules/bson/lib/bson.cjs:593
            inspect ??= defaultInspect;
                    ^^^

    SyntaxError: Unexpected token '??='

    > 1 | const mongoose = require('mongoose');
        |                                                                              ^
      2 | const request = require('supertest')
      3 | const app = require("../app");
      4 |

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1505:14)
      at Object.<anonymous> (node_modules/mongodb/src/bson.ts:3:1)
      at Object.<anonymous> (node_modules/mongodb/src/admin.ts:1:1)
      at Object.<anonymous> (node_modules/mongodb/src/index.ts:1:1)
      at Object.<anonymous> (node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:9:20)
      at Object.<anonymous> (node_modules/mongoose/lib/drivers/node-mongodb-native/index.js:7:22)
      at Object.<anonymous> (node_modules/mongoose/lib/index.js:7:25)
      at Object.<anonymous> (node_modules/mongoose/index.js:8:18)
      at Object.<anonymous> (test/user.test.js:1:120)

What are the exact config transform should I use to make this working? Even through I tried to make this file Module Javascript (mjs), and added type:'module' in the package.json. But nothing working. If I change this, its affecting my entire project execution.

What are the steps I need to do here without touch anything on my existing project?

How to redirect user to a specific route when tries to refresh the page manually in react?

I’m trying to re-direct the user to a specific route when tries to refresh the page. Also is their any way to show an alert before routing to different url?

I have tried the approach given below but when I navigate back to the page the user gets navigated to that specific url without refreshing the page.

useEffect(() => {    
  // Check if flag exists   
  if (localStorage.getItem("redirectAfterRefresh")) {
    localStorage.removeItem("redirectAfterRefresh");
    // Redirect user to specific page
    window.location.href = "/ndr";  // Replace with your actual URL
  } else {
    // Set flag for next refresh
    localStorage.setItem("redirectAfterRefresh", true);
  }

  return () => {
    window.onbeforeunload = null;
  };
}, []);

DirectionsRenderer overwrite the Marker when rendering

I’m working on setting up a tracking system so customers can see where their deliveries are in real-time. I managed to setup for marker destination and pickup location along with route path toward it. The issues is when I tried to render it, Two Custom Markers being overwrite/overlap by existing two (including the one with bike icon). Here is pic of what happening.

pic of marker being overlap by Direction Renderer Marker

My Question is there any way to show custom Markers instead of DirectionRenderer Marker? Here is my implementation.

"use client";
import React,{useEffect,useState} from 'react'
import { GoogleMap, useJsApiLoader,Marker,DirectionsRenderer } from '@react-google-maps/api';
import { DeliveryData } from '@/lib/types';
const containerStyle = {
  width: '400px',
  height:'400px '
};

let directionsService: google.maps.DirectionsService;

function MapContainer({ deliveryData }: { deliveryData: DeliveryData }) {
  const { isLoaded } = useJsApiLoader({
    id: 'google-map-script',
    googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY || ""
  });
  
  const pickupCoordinates = {
    lat: -33.8827923,
    lng: 151.1959758
  }

  const deliveryCoordinates = {
    lat: -33.8876642,
    lng: 151.2086783
  }
  
  const [deliveryGuyPosition, setDeliveryGuyPosition] = useState(deliveryCoordinates);
  const [directions, setDirections] = useState<google.maps.DirectionsResult | null>(null);
  
  const [_, setMap] = React.useState<google.maps.Map | null>(null)

  const onLoad = React.useCallback(function callback(map: google.maps.Map) {
    const bounds = new window.google.maps.LatLngBounds();
    directionsService = new google.maps.DirectionsService();
    bounds.extend(deliveryCoordinates);
    bounds.extend(pickupCoordinates);
    map.fitBounds(bounds);    
    changeDirection(pickupCoordinates, deliveryCoordinates);
    setMap(map)
  }, []);

  const changeDirection = (origin: any, destination: any) => {
    directionsService.route(
      {
        origin: origin,
        destination: destination,
        travelMode: google.maps.TravelMode.DRIVING
      },
      (result, status) => {
        if (status === google.maps.DirectionsStatus.OK) {
          // Change the state of directions to the result of direction service
          setDirections(result);
        } else {
          console.error(`Error fetching directions ${result}`);
        }
      }
    );
  };

  const onUnmount = React.useCallback(function callback() {
    setMap(null)
  }, [])

  return (isLoaded && <GoogleMap mapContainerStyle={containerStyle} onLoad={onLoad} onUnmount={onUnmount}>
      
      {directions !== null && <DirectionsRenderer directions={directions} />}
      <Marker position={pickupCoordinates} title="pick up loaction"
        icon={'images/destination.png'}
      />
      <Marker position={deliveryGuyPosition} title="Delivery Guy"
      icon={'images/delivery.png'}
      />
      </GoogleMap>)

}

export default React.memo(MapContainer)

How to show custom JSX on the top of the webpage for web extension

I am using this boilerplate code https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite .
The use case is, if the user clicks a context menu that is associated with the web extension, it should open a JSX modal on the current webpage.

background.ts

import reloadOnUpdate from 'virtual:reload-on-update-in-background-script';
import 'webextension-polyfill';

reloadOnUpdate('pages/background');

/**
 * Extension reloading is necessary because the browser automatically caches the css.
 * If you do not use the css of the content script, please delete it.
 */
reloadOnUpdate('pages/content/style.scss');

chrome.runtime.onInstalled.addListener(() => {
  console.log('onInstalled....');

  chrome.contextMenus.create({
    id: 'typelessPopup',
    title: 'Add to typless',
    contexts: ['selection'],
  });
  chrome.contextMenus.onClicked.addListener((info, tab) => {
    chrome.storage.local.set({ selectedText: info.selectionText });
   });
});

console.log('background loaded', chrome);

What are the code changes I have to make according to the boilerplate code ?

Search a number in string using a charCodes and one for loop that starts from the end

I have string:
const text = “I spent 1430 USD today”

I need to get the amount 1430 using the for loop from the end
Forbidden: do not use parseInt, parseFloat, Number, +str, 1 * str, 1 / str, 0 + str, etcc

Limitations: 1 for loop, charCodeAt

I tried solving it and it makes sense that the numbers would be written in reverse order. How can I avoid this without using reverse (or other native methods) or additional loops functions ?

function searchAmount(str) {
  let amount = 0;

  for (let i = str.length - 1; i >= 0; i--) {
    const charCode = str.charCodeAt(i);

    if (charCode >= 48 && charCode <= 57) {
      amount = amount * 10 + (charCode - 48);
    }
  }
  return amount;
}

console.log(searchAmount(text));

Content of textarea is not empty after deleting it

I have a simple textarea in html like this:

<textarea name="sitetitl" id="sitetitle" class="feld" maxlength="255" data-check-length="255"></textarea>

Now let’s say there is text in this textarea, because it loads something from the database and puts it in there:

<textarea name="sitetitl" id="sitetitle" class="feld" maxlength="255" data-check-length="255">Here is some text from the database</textarea>

Now when I delete that text manually by pressing the return key on my keyboard, the text gets deleted visually. But when I inspect the element it still says that text is in there.

The problem here is that there is a specific button which appears when there is no text in the textarea. This also works as intended. This button has a function that generates text in that textarea on click. If there is text in that area, a jquery popup will appear, asking the user if he wants to override the current text. But there is no text, because I deleted it. So the popup comes, because on inspecting the element, you can still see the text, although I deleted it.

Any advice?

why after clicking my hamburger menu some links are disappeared to my personal portfolio website?

enter code here i have been trying to add a hamburger functionality to my website but after hitting the hamburger menu 3 links of my navbar disappeared.
this is my HTML –

 <header>

        <nav>

            <div class="logo">
                <span><a href="#home">Aditya.</a></span>
            </div>

            <div class="menu-toggle">
                <div class="hamburger"><img src="/assets/svg/hamburger.svg" alt="hamburger"></div>
            </div>

            <ul class="nav-links">
                <li><a href="#about">About</a></li>
                <li><a href="#projects">Projects</a></li>
                <li><a href="#skills">Skills</a></li>
                <li><a href="#contact">Contact</a></li>

            </ul>

            <div class="social">
                <a href="https://github.com/aditya9-2" target="_blank"> <img src="assets/github.png" alt="github"
                        width="25" height="25"></a>
                <a href="https://linkedin.com/in/aadityabasak20" target="_blank"> <img src="assets/LinkedIn.png"
                        alt="LinkedIn" width="25" height="25"></a>
                <a href=" https://x.com/aadityaa027?t=QolEyjPnS_MgghSikQeP0g&s=08" target="_blank"> <img
                        src="assets/x.png" alt="x" width="25" height="25"></a>
            </div>

        </nav>

    </header>

this is my CSS-

/* hamburger functionality */
.menu-toggle {
    display: none;
}

.menu-open .nav-links {
    display: flex;
}

.menu-open .social {
    display: flex;
}



header>nav ul {
    display: flex;
    align-items: center;

}

nav ul li {
    margin: 0 23px;
    list-style: none;
}

nav ul li a {
    text-decoration: none;
    color: var(--text-color);
    font-size: 18px;
    transition: all 0.3s ease-out;
}

nav ul li a:hover {
    cursor: pointer;
    color: var(--text-hover);
    transform: scale(1.3);
}

.social {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 50px;
    background: none;
}

.social img {
    transition: all 0.3s ease-out;
}

.social img:hover {
    cursor: pointer;
    transform: scale(1.3);
}


@media screen and (max-width:718px) {

 .menu-toggle {
        display: block;
        cursor: pointer;
    }

    .hamburger img {
        width: 35px;
        filter: invert(1);
    }

    .nav-links,
    .social {
        display: none;
        flex-direction: column;
        position: absolute;
        top: 100%;
        left: 0;
        width: 100%;
        background: var(--background);
        padding: 10px 0;
        box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1);
        z-index: 10;
    }


    .nav-links li {
        margin: 10px 0;
        text-align: center;
        /* gap: 30px; */
    }

    .nav-links a {
        color: var(--text-color);
    }

    .nav-links a:hover {
        color: var(--text-hover);
    }

    .social {
        display: none;
    }

    .menu-open .nav-links {
        position: absolute;
        top: 0;
        display: flex;
    }
}

and this is my JS –


const menuToggle = document.querySelector('.menu-toggle');
const navLinks = document.querySelector('nav ul.nav-links');
const socialLinks = document.querySelector('.social');

menuToggle.addEventListener('click', () => {
    document.body.classList.toggle('menu-open');
});

the “projects, skills, and contacts” links are not visible in the hamburger functionality.
result –
this is the result i got after clicking the hamburger, here projects skills and contact links are not visible

and i am not able to close the hamburger.

this is the closing SVG i want to use-

<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="100" height="100" viewBox="0,0,256,256">
<g fill="#d5d5d5" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(5.12,5.12)"><path d="M9.15625,6.3125l-2.84375,2.84375l15.84375,15.84375l-15.9375,15.96875l2.8125,2.8125l15.96875,-15.9375l15.9375,15.9375l2.84375,-2.84375l-15.9375,-15.9375l15.84375,-15.84375l-2.84375,-2.84375l-15.84375,15.84375z"></path></g></g>
</svg>

can anyone please help me with this two problem?. it will be very helpful for me.
thank you.

event Listener close browser

i wanna call event listener when just close browser
event listener ‘unload’ and ‘beforeUnload’ when referesh browsering and close browser run.i wanna run just when close browser.

useEffect(() => {
// // move userData to Context-API ////////////////////////////////////////////////////////////////
const userDataStorage = JSON.parse(window.sessionStorage.getItem(‘userData’)) || JSON.parse(window.localStorage.getItem(‘userData’));
if (userDataStorage) {
changeUserData(ACTION_TYPE.PATCH_DATA, { …userDataStorage });
// window.localStorage.setItem(‘userData’, JSON.stringify(userDataStorage)); // for login in new tab browser
// window.sessionStorage.setItem(‘userData’, JSON.stringify(userDataStorage)); // for login in new tab browser
}

const beforeUnloadBrowser = () => {
  window.localStorage.removeItem('userData');
  if (!userData.isRemember) {
    // when Refresh Browser localStorage clear but sessionStorage Save Data
    // when Close Browser sessionStorage auto cleat and if isRemember false localStorage clear
  }
};
window.addEventListener('bef', beforeUnloadBrowser);

// update Time ///////////////////////////////////////////////////////////////////////////////////
const elementDay = elementDate.current.children[0];
const elementTime = elementDate.current.children[1];

const updateTime = () => {
  const date = new persianDate(new Date());
  elementDay.innerText = date.format('dddd');
  elementTime.innerText = date.format('HH:mm:ss');
};
const timer = window.setInterval(updateTime, 1000);

// Function Cleanup //////////////////////////////////////////////////////////////////////////////
return () => {
  window.clearTimeout(timer);
  // window.removeEventListener('close', beforeUnloadBrowser);
};

}, []);

Manifest.json multiple background services

I used the below in a Manifest v3 to create a Chrome extension.

"background": { 
  "service_worker": "js/background.js", 
  "type":"module" 
},

Can I put multiple background.js files in a manifest?

I did not found any information about this. Thanks for help!