Upgrade to Pro — share decks privately, control downloads, hide ads and more …

requestIdleCallback()による協調的バックグラウンド処理の実現 / requestIdleCallback()

requestIdleCallback()による協調的バックグラウンド処理の実現 / requestIdleCallback()

久保田光則

July 24, 2017
Tweet

More Decks by 久保田光則

Other Decks in Programming

Transcript

  1. requestIdleCallback()
    ʹΑΔڠௐతόοΫάϥ΢ϯυ
    ॲཧͷ࣮ݱ
    "TQFDUJWF--$ٱอాޫଇ!BOBUPP

    View full-size slide

  2. ٱอాޫଇ
    "TQFDUJWF--$୅ද
    !BOBUPP
    HJUIVCDPNBOBUPP
    ࣗݾ঺հ

    View full-size slide

  3. IUUQSFMBZIVCJP
    ࣾ಺Ͱʮۀ຿͕উखʹճΔ࢓૊Έʯɺ࡞Ε·͢

    View full-size slide

  4. ޷ධൃചதʂ

    View full-size slide

  5. ࠓճͷ࿩
    requestIdleCallback()

    View full-size slide

  6. SFRVFTU*EMF$BMMCBDL
    ͱ͸
    +BWB4DSJQUͷ࠷ۙग़͖ͯͨ"1*
    ϒϥ΢β͕Ջͳ࣌ʹ͍ͨ͠ॲཧ

    ͷίʔϧόοΫΛొ࿥͢Δ

    View full-size slide

  7. +BWB4DSJQUͷඇಉظॲཧ
    TFU5JNFPVU
    TFU*OUFSWBM

    SFRVFTU"OJNBUJPO'SBNF

    TFU*NNFEJBUF

    ͳΜͰ͞Βʹ·ͨඇಉظॲཧ͕૿͑Δ

    View full-size slide

  8. // Idleঢ়ଶͷ࣌ʹॲཧΛߦ͏
    requestIdleCallback(function(deadline) {
    doSomething();
    });

    View full-size slide

  9. // ࢒͍ͬͯΔ͕࣌ؒ͋Ε͹ॲཧΛߦ͏
    requestIdleCallback(function(deadline) {
    while (deadline.timeRemaining() > 0) {
    doSomething();
    }
    });

    View full-size slide

  10. requestIdleCallback(function (deadline) {
    while (deadline.timeRemaining() > 0) {
    doSomething();
    }
    // ·ͩ΍Γ͍ͨλεΫ͕࢒͍ͬͯΔ৔߹
    requestIdleCallback(callback);
    });

    View full-size slide

  11. 6*εϨουͷॲཧ
    6*εϨου্Ͱ+BWB4DSJQU͸࣮ߦ͞ΕΔ
    +BWB4DSJQUҎ֎ʹ΋ඞཁͳλεΫ͕࣮ߦ͞ΕΔ
    Layout Paint
    Composite

    Layers
    Idle
    Style
    Frame
    Scripting
    Կ΋΍͍ͬͯͳ͍ঢ়ଶ

    View full-size slide

  12. 4DSJQUJOH͕௕Ҿ͘ͱ
    ଞͷॲཧ͕஗ΕΔɻը໘͕൓Ԡ͠ͳ͘ͳΔ
    όοΫάϥ΢ϯυॲཧ͕Ͱ͖ͳ͍
    Scripting

    View full-size slide

  13. ͦ͜Ͱొ৔ͨ͠8FC8PSLFS
    ผϓϩηεͰ+BWB4DSJQUΛ࣮ߦͰ͖Δ
    Scripting
    Background Task
    UIεϨου
    ϫʔΧʔεϨου
    Scripting

    View full-size slide

  14. // ΢ΣϒϖʔδଆͷJS
    <br/>var worker = new Worker(‘task.js’);<br/>
    // task.js
    … // ϫʔΧʔεϨουͰॲཧ͢ΔίʔυΛॻ͘

    View full-size slide

  15. // ΢ΣϒϖʔδଆͷJS
    <br/>var worker = new Worker(‘task.js’);<br/>worker.postMessage({msg: ‘hello’});<br/>
    // task.js
    self.addEventListener(‘message’, function(e) {
    // e.data.msg === ‘hello’
    });

    View full-size slide

  16. // ΢ΣϒϖʔδଆͷJS
    <br/>var worker = new Worker(‘task.js’);<br/>worker.addEventListener(‘message’, callback);<br/>worker.postMessage({msg: ‘hello’});<br/>
    // task.js
    self.addEventListener(‘message’, function(e)
    {
    self.postMessage({msg: e.data.msg});
    });

    View full-size slide

  17. ࣌ؒͷ͔͔ΔόοΫάϥ΢ϯυλεΫ͕ແࣄ
    ॲཧͰ͖ΔΑ͏ʹͳͬͨ
    Scripting
    Background Task
    UIεϨου
    ϫʔΧʔεϨου
    Scripting
    postMessage() postMessage()

    View full-size slide

  18. ΊͰͨ͠ΊͰͨ͠ ☺

    View full-size slide

  19. 8FC8PSLFS࢖͍ͮΒ͍໰୊
    ׬શʹίϯςΩετ͕ผ
    σʔλͷड͚౉͠͸ίϐʔ͢Δඞཁ͋Γ
    5SBOTGFSBCMFΛ࣋ͭ஋ͷΈ͕ࢀর౉͠Ͱ
    ͖Δ

    View full-size slide

  20. ίϯςΩετ͕׬શʹผ
    XJOEPXΦϒδΣΫτ͕ແ͍
    %0.ཁૉͷ஋ΛಡΈࠐΜͩΓૢ࡞
    ͨ͠ΓͰ͖ͳ͍
    σʔλͷҾ͖౉͠ʹ೉͋Γ

    View full-size slide

  21. QPTU.FTTBHF
    ͷบ
    σʔλ͸શͯίϐʔ͞ΕΔ
    େ͖ͳ഑ྻΛ౉͢ͱΦʔόʔϔουʹ
    5SBOTGFSBCMFͳΦϒδΣΫτͷΈࢀর౉͠Մೳ
    "SSBSZ#V⒎FS΍0⒎TDSFFO$BOWBTͳͲʹݶఆ
    %0.ཁૉͳͲ౉ͤͳ͍ΦϒδΣΫτ͕͋Δ

    View full-size slide

  22. ΤϯτϦϙΠϯτ͕૿͑Δ
    ϫʔΧʔ༻ʹKTϑΝΠϧΛผʹ࡞Δ
    ඞཁ͕͋Δɻ
    ΠϯϥΠϯϫʔΧʔͱ͍͏ςΫχο
    ΫͰΠϯϥΠϯԽ΋ҰԠͰ͖Δ͕ͦ
    Μͳʹ࢖͍΍͍͢Θ͚Ͱ͸ͳ͍

    View full-size slide

  23. // ΠϯϥΠϯϫʔΧʔͷྫ
    var bb = new BlobBuilder();
    bb.append("onmessage = function(e)
    { postMessage('msg from worker'); }");
    var blobURL =
    window.URL.createObjectURL(bb.getBlob());
    var worker = new Worker(blobURL);

    View full-size slide

  24. ϝΠϯεϨουͱಡΈࠐΜͩίʔ
    υͷڞ༗͕Ͱ͖ͳ͍
    ίϯςΩετ͕ผͳͷͰɺϝΠϯεϨο
    υͰಡΈࠐΜͩίʔυΛڞ༗Ͱ͖ͳ͍ɻ
    ϫʔΧʔͷ+4ϑΝΠϧʹόϯυϧ͠௚͢
    ͔ɺJNQPSU4DSJQUͰಡΈࠐΉඞཁ͕͋Δ

    View full-size slide

  25. SFRVFTU*EMF$BMMCBDLʹ࿩Λ໭͢

    View full-size slide

  26. SFRVFTU*EMF$BMMCBDL
    ͷλΠϛ
    ϯά
    *EMFঢ়ଶͷ࣌ʹݺͼग़͞ΕΔ
    ΠϯλϥΫγϣϯ΍ඳըΛअຐ͢Δ͜ͱ͕ͳ͍
    Layout Paint
    Composite

    Layers
    Idle
    Style
    Frame
    Scripting
    Կ΋΍͍ͬͯͳ͍ঢ়ଶ

    View full-size slide

  27. SFRVFTU*EFM$BMMCBDLʹ࿩Λ໭͢
    8FC8PSLFSͷΦϧλφςΟϒͱͯ͠΋࢖͑Δ
    ϒϥ΢β͕Ջͳͱ͖ʹॲཧͯ͘͠ΕΔ
    6*εϨουͰ࣮ߦ͢ΔͷͰ࢖͍ͮΒ͘ͳ͍
    ίʔυͷڞ༗΍஋ͷड͚౉͠ͷ໰୊΋ղܾ
    %0.ૢ࡞΋Մೳ
    όοΫάϥ΢ϯυॲཧʹ࠷ద

    View full-size slide

  28. ஫ҙ఺ɺܽ఺
    ϚΠΫϩλεΫʹ෼ׂ͢Δඞཁ͋Γ
    %0.ૢ࡞͸SFRVFTU"OJNBUJPO'SBNF
    Λ௨ͯ͡ߦ͏

    View full-size slide

  29. function bgtask(deadline) {
    while (deadline.timeRemaining() > 0) {
    // 10-20msඵఔ౓ҎԼʹ͢Δ
    doMicroTask();
    }
    requestIdelCallback(bgtask);
    });
    requestIdleCallback(bgtask);

    View full-size slide

  30. requestIdleCallback(function(deadline) {
    while (deadline.timeRemaining() > 0) {
    var result = doSomething();
    // ಉظతʹDOMૢ࡞͸͠ͳ͍Α͏ʹ͢Δ
    requestAnimationFrame(function() {
    document.body.querySelector(‘#hoge’) =
    result;
    });
    }
    });

    View full-size slide

  31. (FOFSBUPSͱ૊Έ߹ΘͤΔ
    ϚΠΫϩλεΫʹ෼ׂ͢ΔͷΊΜͲ͍͘͞
    ਓʹ࿕ใ
    (FOFSBUPSΛ࢖͏ͱόοΫάϥ΢ϯυॲཧ
    ΛϚΠΫϩλεΫʹ෼ׂ͠΍͘͢ͳΓ·͢

    View full-size slide

  32. function runInIdle(it) {
    requestIdleCallback(function(deadline) {
    var val = it.next();
    while (!val.done) {
    if (deadline.timeRemaining() <= 0) {
    runInIdle(it);
    return;
    }
    val = it.next();
    }
    });
    }

    View full-size slide

  33. // όοΫάϥ΢ϯυͰfizzbuzz͢Δྫ
    function* fizzbuzz() {
    for (var i = 0;;i++) {
    yield; // ←͜͜ͰॲཧΛ෼ׂ
    if (i % 15 = 0) output(‘FizzBuzz’);
    else if (i % 3 == 0) output(‘Fizz’);
    else if (i % 5 == 0) output(‘Buzz’);
    else output(i);
    }
    };
    runInIdle(fizzbuzz());

    View full-size slide

  34. ·ͱΊ
    +4ͷ࣮ߦ͸γϯάϧεϨουͳͷͰόοΫά
    ϥ΢ϯυॲཧ͕Ͱ͖ͳ͍
    ผεϨουͰॲཧ͢Δ8FC8PSLFS͸࢖͍ͮ
    Β͞ͱ͍͏໰୊͋Γ
    requetIdleCallback()͕8FC8PSLFSͷ
    ΦϧλφςΟϒͱͯ͠࢖͑Δ

    View full-size slide

  35. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View full-size slide