requestIdleCallback 示例

requestIdleCallback 示例

通过具体例子,来理解浏览器性能优化相关的api,即requestIdleCallback.

https://www.cnblogs.com/galenyip/p/4856996.html
https://developer.mozilla.org/en-US/docs/Web/API/Background_Tasks_API#example
*requrestAnimationFrame 相关文章

示例一
/**
 * 原文网站
 * https://www.cnblogs.com/galenyip/p/4856996.html
 */

var eventsToSend = [];
var isRequestIdleCallbackScheduled = false;

function onNavOpenClick() {
    // animate the menu
    document.body.classList.add('open');

    eventsToSend.push({
        category: 'button',
        action: 'click',
        label: 'nav',
        value: 'open'
    });

    schedulePendingEvents();
}

function schedulePendingEvents() {
    if (isRequestIdleCallbackScheduled)
        return;

    isRequestIdleCallbackScheduled = true;

    if ('requestIdleCallback' in window) {
        requestIdleCallback(processPendingAnalyticsEvents, { timeout: 2000 });
    } else {
        processPendingAnalyticsEvents();
    }
}

function processPendingAnalyticsEvents(deadline) {
    isRequestIdleCallbackScheduled = false;

    if (typeof deadline === 'undefined') {
        deadline = { timeRemaining: function() { return Number.MAX_VALUE } };
    }

    while (deadline.timeRemaining() > 0 && eventsToSend.length > 0) {
        var evt = eventsToSend.pop();

        // 耗时操作
        console.log(evt);
    }

    if (eventsToSend.length > 0) {
        schedulePendingEvents();
    }
}
示例二
/**
 * 原文网站
 * https://www.cnblogs.com/galenyip/p/4856996.html
 */

var elementsToAdd = [];
var documentFragment;
var isVisualUpdateScheduled = false;

function onAddButtonClick() {
    elementsToAdd.push({
        tag: 'div',
        content: new Date().getTime()
    });

    scheduleElementCreation();
}

function scheduleElementCreation() {
    if ('requestIdleCallback' in window) {
        requestIdleCallback(processPendingElements, { timeout: 2000 });
    } else {
        processPendingElements();
    }
}

function processPendingElements(deadline) {
    if (typeof deadline === 'undefined') {
        deadline = { timeRemaining: function() { return Number.MAX_VALUE } };
    }

    if (!documentFragment) {
        documentFragment = document.createDocumentFragment();
    }

    while (deadline.timeRemaining() > 0 && elementsToAdd.length > 0) {
        var elToAdd = elementsToAdd.pop();
        var el = document.createElement(elToAdd.tag);
        el.textContent = elToAdd.content;

        documentFragment.appendChild(el);

        // Don't append to the document immediately, wait for the next
        // requestAnimationFrame callback.
        scheduleVisualUpdateIfNeeded();
    }

    if (elementsToAdd.length > 0) {
        scheduleElementCreation();
    }
}

function scheduleVisualUpdateIfNeeded() {
    if (isVisualUpdateScheduled)
        return;

    isVisualUpdateScheduled = true;

    requestAnimationFrame(appendDocumentFragment);
}

function appendDocumentFragment() {
    isVisualUpdateScheduled = false;

    // Append the fragment and reset.
    document.body.appendChild(documentFragment);
    documentFragment = null;
}
示例三
// https://developer.mozilla.org/en-US/docs/Web/API/Background_Tasks_API#example

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <style type="text/css">
        body {
            padding: 0;
            margin: 0;
        }

        svg:not(:root) {
            display: block;
        }

        .playable-code {
            background-color: #f4f7f8;
            border: none;
            border-left: 6px solid #558abb;
            border-width: medium medium medium 6px;
            color: #4d4e53;
            height: 100px;
            width: 90%;
            padding: 10px 10px 0;
        }

        .playable-canvas {
            border: 1px solid #4d4e53;
            border-radius: 2px;
        }

        .playable-buttons {
            text-align: right;
            width: 90%;
            padding: 5px 10px 5px 26px;
        }
    </style>

    <style type="text/css">
        body {
            font-family: "Open Sans", "Lucida Grande", "Arial", sans-serif;
            font-size: 16px;
        }

        .logBox {
            margin-top: 16px;
            width: 400px;
            height: 500px;
            border-radius: 6px;
            border: 1px solid black;
            box-shadow: 4px 4px 2px black;
        }

        .logHeader {
            margin: 0;
            padding: 0 6px 4px;
            height: 22px;
            background-color: lightblue;
            border-bottom: 1px solid black;
            border-radius: 6px 6px 0 0;
        }

        #log {
            font: 12px "Courier", monospace;
            padding: 6px;
            overflow: auto;
            overflow-y: scroll;
            width: 388px;
            height: 460px;
        }

        .container {
            width: 400px;
            padding: 6px;
            border-radius: 6px;
            border: 1px solid black;
            box-shadow: 4px 4px 2px black;
            display: block;
            overflow: auto;
        }

        .label {
            display: inline-block;
        }

        .counter {
            text-align: right;
            padding-top: 4px;
            float: right;
        }

        .button {
            padding-top: 2px;
            padding-bottom: 4px;
            width: 100px;
            display: inline-block;
            float: left;
            border: 1px solid black;
            cursor: pointer;
            text-align: center;
            margin-top: 0;
            color: white;
            background-color: darkgreen;
        }

        @keyframes slide {
            0% {
                margin-left: 0;
                /* transform: translateX(0); */
            }

            50% {
                margin-left: 200px;
                /* transform: translateX(200px); */
            }

            100% {
                margin-left: 0;
                /* transform: translateX(0); */
            }
        }

        p {
            animation-duration: 3s;
            animation-name: slide;
            animation-iteration-count: infinite;
        }

        #progress {
            width: 100%;
            padding-top: 6px;
        }
    </style>

    <title>Background Tasks API - Example - code sample</title>
</head>

<body>

    <p>
        Demonstration
    </p>

    <div class="container">
        <div class="label">Decoding quantum filament tachyon emissions...</div>
        <progress id="progress" value="0"></progress>
        <div class="button" id="startButton">
            Start
        </div>
        <div class="label counter">
            Task <span id="currentTaskNumber">0</span> of <span id="totalTaskCount">0</span>
        </div>
    </div>

    <div class="logBox">
        <div class="logHeader">
            Log
        </div>
        <div id="log">
        </div>
    </div>


    <script>
        let taskList = [];
        let totalTaskCount = 0;
        let currentTaskNumber = 0;
        let taskHandle = null;

        let totalTaskCountElem = document.getElementById("totalTaskCount");
        let currentTaskNumberElem = document.getElementById("currentTaskNumber");
        let progressBarElem = document.getElementById("progress");
        let startButtonElem = document.getElementById("startButton");
        let logElem = document.getElementById("log");

        let logFragment = null;
        let statusRefreshScheduled = false;

        window.requestIdleCallback = window.requestIdleCallback || function (handler) {
            let startTime = Date.now();

            return setTimeout(function () {
                handler({
                    didTimeout: false,
                    timeRemaining: function () {
                        return Math.max(0, 50.0 - (Date.now() - startTime));
                    }
                });
            }, 1);
        };

        window.cancelIdleCallback = window.cancelIdleCallback || function (id) {
            clearTimeout(id);
        };

        function enqueueTask(taskHandler, taskData) {
            taskList.push({
                handler: taskHandler,
                data: taskData
            });

            totalTaskCount++;

            if (!taskHandle) {
                taskHandle = requestIdleCallback(runTaskQueue, { timeout: 1000 });
            }

            scheduleStatusRefresh();
        }

        function runTaskQueue(deadline) {
            while ((deadline.timeRemaining() > 0 || deadline.didTimeout) && taskList.length) {
                let task = taskList.shift();
                console.log(taskList.length)
                console.log(deadline.didTimeout)
                currentTaskNumber++;

                task.handler(task.data);
                scheduleStatusRefresh();
            }

            if (taskList.length) {
                taskHandle = requestIdleCallback(runTaskQueue, { timeout: 1000 });
            } else {
                taskHandle = 0;
            }
        }

        function scheduleStatusRefresh() {
            if (!statusRefreshScheduled) {
                requestAnimationFrame(updateDisplay);
                statusRefreshScheduled = true;
            }
        }

        function updateDisplay() {
            let scrolledToEnd = logElem.scrollHeight - logElem.clientHeight <= logElem.scrollTop + 1;
            let m = getRandomIntInclusive(1, 10);
            document.querySelector('p').textContent = m;
            if (totalTaskCount) {
                if (progressBarElem.max != totalTaskCount) {
                    totalTaskCountElem.textContent = totalTaskCount;
                    progressBarElem.max = totalTaskCount;
                }

                if (progressBarElem.value != currentTaskNumber) {
                    currentTaskNumberElem.textContent = currentTaskNumber;
                    progressBarElem.value = currentTaskNumber;
                }
            }

            if (logFragment) {
                logElem.appendChild(logFragment);
                logFragment = null;
            }

            if (scrolledToEnd) {
                logElem.scrollTop = logElem.scrollHeight - logElem.clientHeight;
            }

            statusRefreshScheduled = false;
        }
        function log(text) {
            if (!logFragment) {
                logFragment = document.createDocumentFragment();
            }

            const el = document.createElement("div");
            el.textContent = text;
            logFragment.appendChild(el);
        }

        function logTaskHandler(data) {
            log("<strong>Running task #" + currentTaskNumber + "</strong>");

            for (i = 0; i < data.count; i += 1) {
                log((i + 1).toString() + ". " + data.text);
            }
        }

        function getRandomIntInclusive(min, max) {
            min = Math.ceil(min);
            max = Math.floor(max);
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }

        function decodeTechnoStuff() {
            totalTaskCount = 0;
            currentTaskNumber = 0;
            updateDisplay();

            let n = getRandomIntInclusive(1, 10);

            for (i = 0; i < n; i++) {
                let taskData = {
                    count: getRandomIntInclusive(75, 150),
                    text: "This text is from task number " + (i + 1).toString() + " of " + n
                };

                enqueueTask(logTaskHandler, taskData);
            }
        }

        document.getElementById("startButton").addEventListener("click", decodeTechnoStuff, false);
    </script>

</body>

</html>

至此,结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值