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.
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?
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.
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()
andturbolinks:before-render
since it provides access to the body element prior to rendering? https://github.com/turbolinks/turbolinks#full-list-of-events
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">
Here's a dirty, hacky way to get zero flicker with turbolinks
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.
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({
.
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)
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.
- Include Turbolinks
- Include svg-with-js library for FA5
- 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!
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.
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.
We've changed the default watch target to document
now. So this should be fixed.
Thanks, @robmadole! Is this included in v5.7.2?
EDIT: Nevermind, I see it was changed in 5.7.0. 馃槃
I tried updating to v5.7.2 and I still experience the same issue.
Can somebody else confirm whether this is indeed fixed?
@juampi same here.
I think this issue is not the same as the one fixed in 5.7.0, for turbolinks compatibility out of the box
However, I do not know if there is a solution for the flicker
How to replicate:
@tagliala There is a solution. When you remove this piece of code WINDOW.requestAnimationFrame ||
from all.js
, flicker with turbolinks will disappear. I'm using this solution in my gem with no visible side effects.
Maybe someone from FortAwesome could explain us what's the purpose of this code in all.js
and help with turbolinks flickering problem to get fixed out of the box.
When you remove this piece of code WINDOW.requestAnimationFrame || from all.js, flicker with turbolinks will disappear.
Thanks!
what's the purpose of this code in all.js
I'm pretty confident that there is a reason, but I do not know what it is 馃槄
Let's wait for some other feedback from @robmadole
Meanwhile, I'm reopening here
The requestAnimationFrame
code is there to improve performance. (Or to schedule the changes for icon replacements when it's convenient for the browser). It separates the changes that are needed from the changes occurring. This keeps the "jank" at a minimum as we render icons.
While this works pretty well in most cases I can understand this asynchronous operation creates a flash of changing content for Turbolinks. So, the best way to address this is add a configuration option that forces these operations (the mutations to the DOM) to be performed immediately.
Let me take a look at how much effort this is going to be.
Alright, this wasn't difficult to implement and we'll have a new config option that can control how the engine replaces icons. This will be included in 5.8.0.
I think this has been solved in version 5.8.0
Relevant configuration line:
config.mutateApproach = 'sync'
I'm going to close here, feel free to comment if something is still wrong
Most helpful comment
Awesome!! Thanks so much @pomartel. Now I don't have to declare this in every case statement.