A simple program that animates the Y position of multiple elements based on the window scroll position
Faster does not mean smoother.

Some very quick notes.

Queries to the DOM are very slow compared too what they do. You should only query the DOM for the elements once and then just use the references you have.

When page is ready

// query the DOM a stash the elements in an array of objects so you can add 
// And more DOM related info as you find it.
const articles = [...document.querySelectorAll('article')].map(element=&gt; ({element}));


Then in the code

const calcVisibilityForAllArticles = () =&gt; {
  // Now you can loop through the element without needing to traverse the DOM each time.
  for(const item of articles){ // item holds the element as element
    const top = calcVisibilityForElem(item.element);

    // for the first pass 
    if (top !== 0) {
       // for the first pass  of visible do the query and save the element
       if(!item.span) { item.span = item.querySelector('span') }
       // now you can use it directly
      item.span.style.transform = `translateY(${Math.floor(top * 1.5)}px)`;
    }
    // do the same for all the other elements you search the DOM for each animation cycle.


Timing

As you have not supplied a working example there is no way to know if you are overloading the page or not.

The important thing to remember is that all browsers have a fixed display rate of 60FPS. Making changes to the DOM at a rate higher than this will only result in shearing and flickering. It can also have a pull down effect on the browser as you block it from doing what it needs to do.

You must particularly be careful with events that are driven by the mouse. Some mice can trigger 500+ events a second. You should never update the DOM from move events that can come from the mouse.

RequestAnimationFrame

When ever you make any regular changes to the DOM use the timer callback via the function requestAnimationFrame. It is designed to present the smoothest possible animations. It is synced to the browsers frame rate, and will not present changes until the display device is not scanning out the pixels.

To use

var scrollPos;  // this holds the current scroll position

// In the scroll event only get the scroll position and make no changes to the
// DOM
function yourScrollEvent() {  ... scrollPos = foo ...}


You make the DOM updates via the frame request

 var lastScrollPos; // used to check if there is a need to animate

 function scrollLoop(){
      if(lastScrollPos !== scrollPos){ // only render if needed
          lastScrollPos = scrollPos;

          // do your DOM stuff here

       }

      requestAnimationFrame(scrollLoop); // request next frame

  }


   // start it off via the frame request.
   requestAnimationFrame(scrollLoop); 


This will produce the smoothest possible animation. If it can not keep up and drops frames then you need to reduce the complexity of the animation.