New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using FA5 with Turbolinks, fixing flicker? #11924

Open
excid3 opened this Issue Dec 13, 2017 · 9 comments

Comments

Projects
None yet
9 participants
@excid3

excid3 commented Dec 13, 2017

Turbolinks compatibility is something I'd love to have with the SVG version of FA5. Right now, I have hacked together a solution that works alright, but each new pageview flickers with the icons being rendered and I was curious if there'd be a smoother way for handling this.

  1. Include Turbolinks
  2. Include svg-with-js library for FA5
  3. Add the following to re-run FA5 each new Turbolinks pageview
document.addEventListener("turbolinks:load", function() {
  FontAwesome.dom.i2svg();
});

This works well, but produces a noticeable flicker going back and forth between pages while the Javascript replaces tags on the page with their SVG equivalents.

Is there any better way we can do this?

@tagliala tagliala added the question label Dec 13, 2017

ledermann added a commit to ledermann/docker-rails that referenced this issue Jan 26, 2018

⬆️ Upgrade icons to FontAwesome 5 (using SVG)
Page loading flickering with Turbolinks, see:
FortAwesome/Font-Awesome#11924
@robmadole

This comment has been minimized.

Collaborator

robmadole commented Feb 8, 2018

Ok, folks. This has come up enough that I'll see if I can help out.

The flicker can be controlled best through CSS. Here are some docs: https://fontawesome.com/how-to-use/performance-and-security#async-loading-indicators

Another option is to leverage the callback that i2svg() has. https://fontawesome.com/how-to-use/font-awesome-api#dom-i2svg

You could do something like:

document.addEventListener("turbolinks:load", function() {
  // do something to hide everything
  FontAwesome.dom.i2svg({
    callback: function () {
      // do something to show everything
    }
  });
});

Do either of those options help? I will add something to our docs if it does.

@johnclittle

This comment has been minimized.

johnclittle commented Feb 8, 2018

body {
  display: none;
}

.fontawesome-i2svg-active body {
  display: block;
}

Unfortunately for me the above as suggested at https://fontawesome.com/how-to-use/performance-and-security#async-loading-indicators makes the whole page flicker.

My understanding is that turbolinks:load fires after it renders the page. Is there anyway to leverage i2svg() and turbolinks:before-render since it provides access to the body element prior to rendering? https://github.com/turbolinks/turbolinks#full-list-of-events

@fuchsberger

This comment has been minimized.

fuchsberger commented Feb 9, 2018

to avoid flickering you can just use the Webfonts with CSS version for now:

In <head> add:

<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet">

@pelted pelted referenced this issue Feb 16, 2018

Open

Update to FA5 #2

@glebtv

This comment has been minimized.

glebtv commented Mar 8, 2018

Here's a dirty, hacky way to get zero flicker with turbolinks

  1. Patch fontawesome.js to disable async/requestAnimationFrame here
    var frame = WINDOW.requestAnimationFrame || function (op) {
  2. Use this code
document.addEventListener("turbolinks:before-render", function(event) {
  FontAwesome.dom.i2svg({
    node: event.data.newBody
  });
});

Works for me, no flicker.

Proper way to solve this would be for fontawesome.js to provide a synchronius alternative\option for dom.i2svg for use cases like this.

@thimo

This comment has been minimized.

thimo commented Mar 8, 2018

That's great, works for me as well. The patch on fontawesome.js involves removing WINDOW.requestAnimationFrame || (right?) and I had to proper-case fontawesome.dom.i2svg({ to FontAwesome.dom.i2svg({.

@glebtv

This comment has been minimized.

glebtv commented Mar 9, 2018

yes, just comment out frame(function () { and });, not what's inside it
This is probably not a perfect (or even good) solution since this is also called in DOM mutation observers, so any dynamic changes to the page might be slow
this seems to be possible to disable, like so

FontAwesome.config = {
  observeMutations: false,
}

(fixed case - this was my import name)

@jdmb77

This comment has been minimized.

jdmb77 commented Sep 28, 2018

Turbolinks compatibility is something I'd love to have with the SVG version of FA5. Right now, I have hacked together a solution that works alright, but each new pageview flickers with the icons being rendered and I was curious if there'd be a smoother way for handling this.

  1. Include Turbolinks
  2. Include svg-with-js library for FA5
  3. Add the following to re-run FA5 each new Turbolinks pageview
document.addEventListener("turbolinks:load", function() {
  FontAwesome.dom.i2svg();
});

This works well, but produces a noticeable flicker going back and forth between pages while the Javascript replaces tags on the page with their SVG equivalents.

Is there any better way we can do this?

This worked like a charm when using jQuery load() to dynamically load a Rails 5 view into a section of the page. Icons would load fine on plain HTML pages, but when loading a html.erb view it would not load the icons. Placed the FontAwesome.dom.i2svg(); in the jQuery load complete and works every time. Thanks for the post @excid3!

@pomartel

This comment has been minimized.

pomartel commented Oct 1, 2018

This can easily be fixed through a config that attaches the mutation observer to the document instead of the body.

FontAwesome.dom.watch({observeMutationsRoot: document})

https://fontawesome.com/how-to-use/with-the-api/methods/dom-watch

Then there's no need to use turbolinks events or trigger the i2svg method.

@jdmb77

This comment has been minimized.

jdmb77 commented Oct 1, 2018

This can easily be fixed through a config that attaches the mutation observer to the document instead of the body.

FontAwesome.dom.watch({observeMutationsRoot: document})

https://fontawesome.com/how-to-use/with-the-api/methods/dom-watch

Then there's no need to use turbolinks events or trigger the i2svg method.

Awesome!! Thanks so much @pomartel. Now I don't have to declare this in every case statement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment