JSFiddle - React, Tailwind, and code Playground

by Artem

HTML

<ul id="root">
  <li id="1">1</li>
  <li id="2">2</li>
  <li id="3">3</li>
  <li id="4">4</li>
  <li id="5">5</li>
  <li id="6">6</li>
  <li id="7">7</li>
  <li id="8">8</li>
  <li id="9">9</li>
  <li id="10">10</li>
  <li id="11">11</li>
  <li id="12">12</li>
  <li id="13">13</li>
  <li id="14">14</li>
  <li id="15">15</li>
  <li id="16">16</li>
  <li id="17">17</li>
  <li id="18">18</li>
  <li id="19">19</li>
  <li id="20">20</li>
  <li id="21">21</li>
  <li id="22">22</li>
  <li id="23">23</li>
  <li id="24">24</li>
  <li id="25">25</li>
  <li id="26">26</li>
  <li id="27">27</li>
  <li id="28">28</li>
  <li id="29">29</li>
  <li id="30">30</li>
  <li id="31">31</li>
  <li id="32">32</li>
  <li id="33">33</li>
  <li id="34">34</li>
  <li id="35">35</li>
  <li id="36">36</li>
  <li id="37">37</li>
  <li id="38">38</li>
  <li id="39">39</li>
  <li id="40">40</li>
  <li id="41">41</li>
  <li id="42">42</li>
  <li id="43">43</li>
  <li id="44">44</li>
  <li id="45">45</li>
  <li id="46">46</li>
  <li id="47">47</li>
  <li id="48">48</li>
  <li id="49">49</li>
  <li id="50">50</li>
  <li id="51">51</li>
  <li id="52">52</li>
  <li id="53">53</li>
  <li id="54">54</li>
  <li id="55">55</li>
  <li id="56">56</li>
  <li id="57">57</li>
  <li id="58">58</li>
  <li id="59">59</li>
  <li id="60">60</li>
  <li id="61">61</li>
  <li id="62">62</li>
  <li id="63">63</li>
  <li id="64">64</li>
  <li id="65">65</li>
  <li id="66">66</li>
  <li id="67">67</li>
  <li id="68">68</li>
  <li id="69">69</li>
  <li id="70">70</li>
  <li id="71">71</li>
  <li id="72">72</li>
  <li id="73">73</li>
  <li id="74">74</li>
  <li id="75">75</li>
  <li id="76">76</li>
  <li id="77">77</li>
  <li id="78">78</li>
  <li id="79">79</li>
  <li id="80">80</li>
  <li id="81">81</li>
  <li id="82">82</li>
  <li id="83">83</li>
  <li id="84">84</li>
  <li id="85">85</li>
  <li id="86">86</li>
  <li id="87">87</li>
  <li id="88">88</li>
  <li id="89">89</li>
  <li id="90">90</li>
  <li...

CSS

body {
  margin: 0;
  padding: 0;
  font-size: 16px;
  line-height: 24px;
  font-family: 'Open Sans', Helvetica, sans-serif;
}

ul {
  margin: 0;
  padding: 0;
}

li {
  padding: 15px 20px;
}

JavaScript

'use strict';

/*
	#9 We are not using chain, just plaing setTimeout
  #29 We are using Promise chain
*/


/*
	Suggestions:
	1. cluster rendering, each cluster -> forEach
  2. We're walking through the queue and checking wether element is in viewport
*/

function elementInViewport(element) {
  const {
    top,
    bottom,
    right,
    left
  } = element.getBoundingClientRect();
  return top >= 0 && top < innerHeight && bottom > 0;
}

// init
let intervalMs = 1000;
let nodesLength = 1000;
let limit = 50;
let i = 1;
let slice;
let isRunning = false;
let event;
let chain = Promise.resolve();

// helper
function changeColour(element) {
  var randomColor = "#000000".replace(/0/g, function() {
    return (~~(Math.random() * 16)).toString(16);
  });
  // console.log(element, randomColor);
  element.style.backgroundColor = randomColor;
}

// subscriber?
function worker(data) {
  // emulate freezing
  for (let k = 0; k < 220; k++) {
    // console.log(k);
  }
  // console.log('data: ', data);
  const item = document.getElementById(data);
  changeColour(item);
}

function getPosition(data) {
  const item = document.getElementById(data);
  // console.log(elementInViewport(item));
  // return Math.round(Math.random());
  // console.log(item, elementInViewport(item));
  return elementInViewport(item);
}

// 1st step - update queue on dispatch(push)
let queue = [];
//queue.push(worker, worker, worker, worker, worker, worker, worker, worker, worker, worker);

function run() {
  let shouldCallTail = false;
  if (queue.length > 0) {
    // slice from particular point depending on elements in viewport
    slice = queue.splice(0, limit);
    slice.forEach((fn, index, array) => {

      // new bavior
      const inViewport = fn.element();
      if (!inViewport && queue.length >= 0) { // >= limit
        queue.push(fn);
        shouldCallTail = true;
        // break the loop  
        return false;
      }

      // using chain
      chain = chain
        .then(() => {
         ...