How can I optimize performance and animations for a portfolio website built with GSAP and Locomotive Scroll?

I’m building a design portfolio website similar to qcsstudio.com using GSAP for animations and Locomotive Scroll for smooth scrolling. While the animations look great on desktop, I’m experiencing performance issues on mobile devices — laggy scroll, delayed animations, and high CPU usage.

Here’s what I’ve tried so far:

Throttling scroll events

Reducing animation complexity

Using will-change and transform: translate3d for hardware acceleration

Lazy-loading images and assets

Has anyone successfully optimized a highly animated site like this for mobile performance? Any best practices or alternative libraries better suited for smooth scrolling and scroll-based animations on lower-end devices?

is there anyone who can make a custom caret cursor handle for ace editor js? (usually marked with a water drop icon) [closed]

is there anyone who can make a custom caret cursor handle for ace editor js? (usually marked with a water drop icon). I have made it, but when the cursor handle is touched using the touch event, the default ace cursor moves to the tip of the finger, as a result the ace cursor cannot be seen when the handle is touched. please if anyone can help.
this my code


    var editor = ace.edit("editor");
        editor.setTheme("ace/theme/github_dark");
    editor.session.setUseWorker(true);
    editor.session.setMode("ace/mode/html");
    editor.setOptions({
        enableBasicAutocompletion: true,
        enableLiveAutocompletion: true,
        enableSnippets: true,
        fontSize: "14px",
        wrap: true,
        
        animatedScroll: false,
        scrollSpeed: 0,
        
    });

    editor.setValue(`<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

</body>
</html>`, -1);







const ln = document.createElement("div");
const bx = document.createElement("div");
bx.id = "box";
ln.className = "line";
bx.innerHTML = `
t<svg id="caretHandle"  width="100%" height="100%" viewBox="0 0 24 29" xmlnsn="http://www.w3.org/2000/svg"><path fill="#558eff" d="m20.496197,8.485282c4.700846,4.700846 4.700846,12.269717 0,16.970563c-4.700846,4.700846 -12.269717,4.700846 -16.970563,0c-4.700846,-4.700846 -4.700846,-12.269717 0,-16.970563l8.485281,-8.485281l8.485281,8.485281z" /></svg>
`;

editor.container.append(bx);
editor.container.append(ln);
 

(function() {
    const box = document.querySelector("#box");
    const line = document.querySelector(".line");
    const aceCursorEl = document.querySelector(".ace_cursor");
    let editorRect;
    let offsetX = 0;
    let offsetY = 0;
    let isDragging = false; 
    line.style.opacity = 0;
    // Tambahkan flag untuk menandakan apakah sedang di-drag
    
    function updateCursorPosition() {
        if (!isDragging) { // Hanya update jika tidak sedang di-drag
            const cursorPos = editor.getCursorPosition();
        
            const screenPos = editor.renderer.textToScreenCoordinates(cursorPos.row, cursorPos.column);
            editorRect = editor.container.getBoundingClientRect();
            const relativeX = screenPos.pageX - editorRect.left;
            const relativeY = screenPos.pageY - editorRect.top;
            line.style.transform = `translate(${relativeX}px,${relativeY}px)`;
        } else {
            // Selama drag, posisikan line di atas box
            const boxCurrentRect = box.getBoundingClientRect();
            const lineOffsetUp = -line.offsetHeight - 5; // Offset ke atas agar tidak menempel
            line.style.transform = `translate(${boxCurrentRect.left - editorRect.left}px,${boxCurrentRect.top - editorRect.top + lineOffsetUp}px)`;
        }
    }
    
    function updateWaterDrop() {
        const cursorPos = editor.getCursorPosition();
        const screenPos = editor.renderer.textToScreenCoordinates(cursorPos.row, cursorPos.column);
        editorRect = editor.container.getBoundingClientRect();
        const relativeX = screenPos.pageX - editorRect.left;
        const relativeY = screenPos.pageY - editorRect.top;
        const handleOffsetDown = 25; // Sesuaikan offset ke bawah agar tidak tertutup jari saat touch start
        box.style.transform = `translate(${relativeX}px,${relativeY + handleOffsetDown}px)`;
    }
    
    box.ontouchstart = function(eventStart) {
        isDragging = true; // Set flag menjadi true saat mulai drag
    line.style.opacity = 1;
        
        let touchStart = eventStart.touches.item(0);
        editorRect = editor.container.getBoundingClientRect();
        offsetX = touchStart.clientX - this.getBoundingClientRect().left;
        offsetY = touchStart.clientY - this.getBoundingClientRect().top;
        
        // Posisikan line di atas box saat touch start
        const boxCurrentRect = this.getBoundingClientRect();
        const lineOffsetUp = -line.offsetHeight - 5; // Offset ke atas
        line.style.transform = `translate(${boxCurrentRect.left - editorRect.left +16}px,${boxCurrentRect.top - editorRect.top + lineOffsetUp}px)`;
        
        // Pastikan kursor Ace terlihat saat mulai drag
        const aceCursorElement = document.querySelector(".ace_cursor");
        if (aceCursorElement) {
            aceCursorElement.style.visibility = 'visible';
            aceCursorElement.style.zIndex = 100000001; // Pastikan di atas
        }
    };
    
    

    
    
    box.ontouchmove = function(eventMove) {
        if (!isDragging) return;
        
        let touchMove = eventMove.touches.item(0);
        let touchX = touchMove.clientX - editorRect.left;
        let touchY = touchMove.clientY - editorRect.top;
 const cursorPos = editor.getCursorPosition();
       
       
        // Posisikan caret handle agar offset ke bawah dari posisi sentuhan
        const handleOffsetDown = 25; // Sesuaikan offset ke bawah
        box.style.transform = `translate(${touchX - offsetX}px,${touchY - offsetY + handleOffsetDown}px)`;
        
        // Selama drag, posisikan line di atas box yang bergerak
        const boxCurrentRect = box.getBoundingClientRect();
        const lineOffsetUp = -line.offsetHeight - 5; // Offset ke atas
        line.style.transform = `translate(${boxCurrentRect.left -editorRect.left +22}px,${boxCurrentRect.top - editorRect.top + lineOffsetUp}px)`;
        
        // Update posisi kursor ACE yang sebenarnya berdasarkan sentuhan
//mendeteksi posisi kursor row sekarang 

        if (
            touchMove.clientX >= editorRect.left &&
            touchMove.clientX <= editorRect.right &&
            touchMove.clientY >= editorRect.top &&
            touchMove.clientY <= editorRect.bottom
        ) {
     

const screenToText = editor.renderer.screenToTextCoordinates(touchX, touchY);
console.log()
//editor.moveCursorTo(screenToText.row, screenToText.column);
editor.clearSelection();
        
}            

    };
    
    box.ontouchend = function(eventEnd) {
        isDragging = false; // Set flag menjadi false saat selesai drag
        
     line.style.opacity = 0;
       updateCursorPosition(); // Kembalikan posisi line ke posisi kursor Ace
        updateWaterDrop(); // Pastikan posisi box tetap sinkron setelah drag selesai
        
        // Kembalikan z-index kursor Ace
        const aceCursorElement = document.querySelector(".ace_cursor");
        if (aceCursorElement) {
            aceCursorElement.style.zIndex = '';
        }
    };
    
    editor.on("changeSelection", function() {
        updateWaterDrop();
        updateCursorPosition();
        
    });
    
    editor.renderer.on("afterRender", function() {
           

        updateCursorPosition();
        updateWaterDrop();
    });
    
    // Inisialisasi posisi awal caret handle agar berada di bawah kursor
    function initializeCaretHandlePosition() {
        const cursorPos = editor.getCursorPosition();
        const screenPos = editor.renderer.textToScreenCoordinates(cursorPos.row, cursorPos.column);
        editorRect = editor.container.getBoundingClientRect();
        const relativeX = screenPos.pageX - editorRect.left;
        const relativeY = screenPos.pageY - editorRect.top;
        const handleOffsetDown = 25; // Sesuaikan offset ke bawah
        line.style.transform = `translate(${relativeX}px,${relativeY}px)`;
        box.style.transform = `translate(${relativeX}px,${relativeY + handleOffsetDown}px)`;
    }
    initializeCaretHandlePosition();
    
})();




How to get Google Sheets window dimensions?

I’m working on a Google Sheets add-on and want to open a modal dialog (showModalDialog) with dimensions proportional to the current window size of the main Google Sheets interface.

I’m using the standard SpreadsheetApp.getUi().showModalDialog(…) API as described in the documentation. https://developers.google.com/apps-script/reference/base/ui#showmodaldialoguserinterface,-title

Here’s the code I’m using:

export const openDialog = (dialogTitle: string): void => {
  const ui = SpreadsheetApp.getUi();

  const dialog = HtmlService.createHtmlOutputFromFile('dialog').setWidth(500).setHeight(500);

  ui.showModalDialog(dialog, dialogTitle);
};

We are calling these method from a side panel. The side panel can’t access the parent (Google Sheets) window dimensions due to cross-origin restrictions.

Is there any reliable way to get the dimensions of the main Google Sheets window (not the iframe) in order to open a dialog with proportional width and height?

Silent dependency injection issue

My modules structure:

  • Working:
    • ModuleA exports ServiceA
    • ModuleB imports ModuleA
    • ServiceB injects ServiceA → all good here
  • Not working:
    • ModuleB exports ServiceB
    • ModuleC imports ModuleA & ModuleB
    • ServiceC injects ServiceA & ServiceB → PROBLEM!

All 3 modules are imported in AppModule

ServiceC implements OnApplicationBootstrap, and its onApplicationBootstrap ceased executing as soon as I injected ServiceA & ServiceB.

This may be a dependency injection issue.

Here is what I’ve tried:

  • Verified all exports & imports & Injectable, etc.

  • Tried injecting ServiceC to ensure its initialization.

  • Tried dynamically injecting using moduleRef

There is no log, no crash, the application is successfully started, but the onApplicationBootstrap is never triggered (meaning ServiceC is never initialized).

What might cause this behaviour? Thank you!

SelectUnstyled with custom Component

I am trying to implement a <SelectUnstyled /> with a custom <button /> component (here simplified with a native DOM <button/>.

<SelectUnstyled
                    onChange={(_, newValue) => _onChange(newValue)}
                    defaultValue={defaultValue}
                    renderValue={(option: SelectOption<number> | null) => {
                        if (option == null || option.value === 0) return placeholder 
                        return `${option.label} (${option.value})`;
                    }}
                    slots={{
                        root: ({children, ...props}) => (
                                <button
                                {...props}
                                onClick={props.onClick}>
                                Test
                            </button>
                        )
                    }}
                    slotProps={{
                        listbox: {className: clsx(...)}
                    }}
                    className={clsx(...)}
                    id={ariaForId.current}>
                    {options.map((option, index) => <OptionUnstyled
                        value={option.value}
                        key={index}>{...}</OptionUnstyled>)}
                </SelectUnstyled>

When I click on the <button />, the ListBox does not appear.
Whats really strange is: When I give

<SelectUnstyled listboxOpen={true) ... />

its not showing either.

When I remove the slots-prop, it works as expected. What do I need to do to open the ListBox?

How can I prevent an app from crashing on unhandled promise rejections?

I’m working on a Vue 3 application using TypeScript and Axios. I already have an axios interceptor that handles errors and shows alerts/modals using a custom system. However, if I make a request in a component using await axios.post(…) and the request fails (e.g., with HTTP 409), my app crashes and I get a black screen.

Here’s what I’ve already tried:

Axios interceptor

instance.interceptors.response.use(
  response => response,
  error => {
    if (error.response?.status === 409) {
      // show alert, etc.
      return Promise.reject("Conflict");
    }
    return Promise.reject(error);
  }
);

Global error handlers

// in main.ts
app.config.errorHandler = (err, instance, info) => {
  console.error("Global Vue error:", err);
};

window.addEventListener("unhandledrejection", (event) => {
  console.error("Unhandled Promise:", event.reason);
  event.preventDefault(); // still doesn't prevent crash
});

If I do this in a component:

async setup() {
  const res = await axios.post("/api/test");
}

I get the error:

Uncaught runtime errors:
ERROR
Request failed with status code 409

What I want:

  • I don’t want to put .catch() or try/catch manually in every request.

  • I want Axios errors to be handled centrally, and I want the component
    not to crash or stop rendering even if a request fails.

  • I want a global or safe way to allow components to continue rendering
    if a request fails.

How to list all available props of any third-party components in React or Angular

I am building a system where users can add widgets (such as charts, gauges, etc.) from multiple third-party libraries. Whenever a user clicks on a widget, I want to dynamically retrieve and display the supported properties (like width, height, dataset, clickable, etc.) for that specific widget. This will allow users to manage styling and data bindings directly from the UI. Since users can use any widget from any library, the solution must support retrieving properties dynamically, without hardcoding. How can I achieve this in React or Angular?

How to inject scss into shadow dom

I am working on a personal ReactJS project and have created two projects using Module Federation.

In the main project, I added some CSS which is affecting the remote project. After Googling, I found that a better way to handle this is by using Shadow DOM, which isolates the remote component.

However, while implementing the Shadow DOM, I’m unable to inject or apply SCSS styles to the elements.

I am using Create React App with CRACO, and I have included the craco.config.js file below.

Does anyone have any ideas on how to inject SCSS?

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './components/App';

import './index.scss';

// Get the root container
const container = document.getElementById('root') as HTMLElement;

// Create the Shadow Root
const shadowRoot = container.attachShadow({ mode: 'open' });

// Create an app container inside Shadow DOM
const shadowAppContainer = document.createElement('div');
shadowRoot.appendChild(shadowAppContainer);

// Mount React into the shadow root
const root = ReactDOM.createRoot(shadowAppContainer);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Craco.config.js:

module.exports = function () {
  const env = process.env.ENV || 'local';

  return {
    plugins: [
      {
        plugin: require('./build/craco'),
      },
    ],
    style: {
      sass: {
        loaderOptions: {
          // Prefer 'sass' (dart-sass) over 'node-sass' if both packages are installed.
          implementation: require('sass'),
          // Workaround for this bug: https://github.com/webpack-contrib/sass-loader/issues/804
          webpackImporter: false,
        },
      },
    },
    webpack: {
      plugins: {
        remove: ['ModuleScopePlugin'],
      },
    },
  };
};

Local React App Not Loading Styles After Deployment to GitHub Pages [closed]

I had my React app fully working and deployed to GitHub Pages, where it runs fine.

However, when I run npm start locally, the app only displays plain HTML — none of the styles are being applied. This is strange because everything was working correctly before I deployed.

I even tried downloading the project again from GitHub to start fresh, but I still run into the same issue.

I’ve tried a bunch of fixes and looked everywhere, but I can’t figure out what’s going wrong.

Has anyone experienced this before or have ideas on what might be causing it?

How to open the JavaScript debug console in Mobile Safari from a MacBook while Running Appium tests on iOS?

As the overly long title suggests, I’m using Selenium Appium on a MacBook Pro with Javascript (nodejs) to automate tests on a website opened on Safari via the Webdriver on an iPhone 7

It works great! However, on the MacBook’s Safari, when I want to open the Javascript Console of the device, as is usually possible when opening a Safari page on the iPhone, I see the site only greyed out.

As per usual of course, Web Inspector is on, on the device, as well as MacBook. I can access the js console of the iOS device from the MacBook normally without the automated test. Just, when the test starts and webdriver starts safari, that doesn’t work.

Is there a way to somehow get access from the MacBook to the iPhone Safari’s javascript console, while running automated tests?

Vue.js Error TypeError: Cannot read properties of undefined (reading ‘backend’)

i dont know how to solve this one on my final project, i try to find it anywhere but havent found it. help me guys

TypeError: Cannot read properties of undefined (reading 'backend')
    at _Engine.moveData (@tensorflow_tfjs.js?v=a02446f2:3915:29)
    at DataStorage.get (@tensorflow_tfjs.js?v=a02446f2:1638:22)
    at Object.reshape4 [as kernelFunc] (@tensorflow_tfjs.js?v=a02446f2:56356:41)
    at kernelFunc (@tensorflow_tfjs.js?v=a02446f2:4060:22)
    at @tensorflow_tfjs.js?v=a02446f2:4104:21
    at _Engine.scopedRun (@tensorflow_tfjs.js?v=a02446f2:3953:19)
    at _Engine.runKernelFunc (@tensorflow_tfjs.js?v=a02446f2:4098:10)
    at _Engine.runKernel (@tensorflow_tfjs.js?v=a02446f2:4014:17)
    at reshape_ (@tensorflow_tfjs.js?v=a02446f2:6554:17)
    at reshape__op (@tensorflow_tfjs.js?v=a02446f2:4702:22)

Up navigation from opensearch dashboards security analytics plugin

I need to move navigation from the security analytics plugin to the main navigation sidebar. I was able to move it and the transition only occurs if I am not inside the plugin.
For example, If I am in Discover and want to go to alerts (SAP), then I can do it, but if I want to go to rules(SAP) from alerts (SAP), then nothing will happen. The route will change, but the page does not react in any way.

What am i doing wrong in this Image slider project?

My code html and js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>image slider</title>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js" ></script>
    <style>
        .container {
            display: flex;
            align-items: center;
            justify-content: center;
            text-align: center;
            flex-direction: column;
        }
        #btn {
            cursor: pointer;
        }
    </style>
</head>
<body>
    <h1>Image Slider</h1>
    <div class="container">
        <img src="first.png" class="img" height="300px"><br>
        <button id="btn">~Slide~</button>
    </div>

    <script>
        let img = $(".img")[0]; 

        let images = ["first.png", "second.png", "third.png", "fourth.png", "fifth.png"];

        let current = 0;

        $("#btn").click(() => {
            current++;
            if (current >= images.length) {
                current = 0;
            }
            img.src = images[current];
        });
    </script>
</body>
</html>

Problem:

  • All files are in the same folder.
  • First image (first.png) loads correctly.
  • Clicking the button does nothing.

GSMArena API Proxy

I can’t find a way to add proxy to the gsmarena-api.

So far, I tried following codes but it ignores the proxy.

import { HttpsProxyAgent } from 'https-proxy-agent';

const proxyAgent = new HttpsProxyAgent('proxy_url');

const device = await gsmarena.catalog.getDevice('apple_iphone_13_pro_max-11089', {
    httpsAgent: proxyAgent
});
console.log(device);