admin管理员组

文章数量:1428473

I need the browser to update my UI before a long(er) operation is done. Currently the browser is waiting until after everything is plete and then updating the UI, which means UI freezes for 1-2 seconds then updates.

So, user clicks button in UI, then this code executes:

$('#mybutton').click(function(e) {

e.preventDefault();// prevent the default anchor functionality

$('#mainctrldiv').css('display', 'none');
$('#otherctrldiv').css('display', 'block');

var img = $('<img id="spareimg" style="display:none;">');
img.attr('src', canvas.getActiveObject().toDataURL()); // This is causing the delay!
img.appendTo('body');
}

It's the canvas.getActiveObject().toDataURL() (a FabricJS function) that is taking the time. I want this to happen after the 2 divs have been visibly displayed to the user, to they don't notice. Need this to work in all monly used browsers out there! (mobile as well as desktop).

Research suggested that reading the css display properties immediately after setting them would force the browser to repaint so I added in the following code straight after setting these properties but the delay still occurred:

$('#mainctrldiv').css('display');
$('#otherctrldiv').css('display');

Many thanks for any suggestions!

I need the browser to update my UI before a long(er) operation is done. Currently the browser is waiting until after everything is plete and then updating the UI, which means UI freezes for 1-2 seconds then updates.

So, user clicks button in UI, then this code executes:

$('#mybutton').click(function(e) {

e.preventDefault();// prevent the default anchor functionality

$('#mainctrldiv').css('display', 'none');
$('#otherctrldiv').css('display', 'block');

var img = $('<img id="spareimg" style="display:none;">');
img.attr('src', canvas.getActiveObject().toDataURL()); // This is causing the delay!
img.appendTo('body');
}

It's the canvas.getActiveObject().toDataURL() (a FabricJS function) that is taking the time. I want this to happen after the 2 divs have been visibly displayed to the user, to they don't notice. Need this to work in all monly used browsers out there! (mobile as well as desktop).

Research suggested that reading the css display properties immediately after setting them would force the browser to repaint so I added in the following code straight after setting these properties but the delay still occurred:

$('#mainctrldiv').css('display');
$('#otherctrldiv').css('display');

Many thanks for any suggestions!

Share Improve this question asked Apr 11, 2016 at 16:44 Alex KerrAlex Kerr 1,0901 gold badge20 silver badges53 bronze badges 5
  • What do you mean by delay? If the canvas is too large, converting it to a data URL might block the main thread for a noticeable amount of time. How exactly does the delay manifest? – XCS Commented Apr 11, 2016 at 16:47
  • Could toss a hidden, disabled checkbox at some point in the dom that can see both #mainctrldiv and #otherctrldiv and have css rules that toggle which gets display:none and display:block based on that checkbox being :checked. However, I have a feeling this has something to do with how jQuery is managing things, rather than strictly what it's trying to do. – abluejelly Commented Apr 11, 2016 at 16:53
  • $('#mainctrldiv').css('display'); is inplete. Did you mean $('#mainctrldiv').css('display', 'block'); ? – XCS Commented Apr 11, 2016 at 17:04
  • @Cristy Thanks. As mentioned the delay is 1 - 2 seconds. The user clicks the button in the UI with ID '#mybutton' and the div swap over (one div being hidden the other shown) should be instant, but instead everything freezes - even the button being deselected freezes - until the canvas.getActiveObject().toDataURL() is plete. I know that's responsible because menting it out fixes the problem. – Alex Kerr Commented Apr 11, 2016 at 19:29
  • @Cristy you wrote " If the canvas is too large, converting it to a data URL might block the main thread for a noticeable amount of time" - yes I know, that's why I'm posting here :) I need to delay the data URL conversion until after the divs have been updated (as per the flow of the code) but the browsers is bining all operations before it repaints, so I need a workaround! – Alex Kerr Commented Apr 11, 2016 at 19:31
Add a ment  | 

1 Answer 1

Reset to default 6

Try using setTimeout with zero delay, it will push these to the end of the thread. You can also try adding some delay if zero delay doesn't work for you. But I am not sure if that exact line is causing the issue, if it is post another question on how to optimise and decrease the time.

$('#mybutton').click(function(e) {
  e.preventDefault(); // prevent the default anchor functionality
  $('#mainctrldiv').css('display', 'none');
  $('#otherctrldiv').css('display', 'block');
  setTimeout(function() {
    var img = $('<img id="spareimg" style="display:none;">');
    img.attr('src', canvas.getActiveObject().toDataURL()); // This is causing the delay!
    img.appendTo('body');
  }, 0);
}

It's important to note that the function or code snippet cannot be executed until the thread that called setTimeout() has terminated.

本文标签: javascriptHow to force browser repaint and avoid UI update delayStack Overflow