Loading custom fonts with webfont.js - css

I'm working on a project where I'm trying to use some 5 custom fonts.
I use webfont.js library so that I can time my initialisation the way I want to.
However, I notice that I have an intermittent issue, whereby webfont.js will fail loading all 5 fonts 75% of the time. If I ignore the error (inactive handler) and just resume loading my site I can see all custom fonts fine.
This is annoying because webfont.js takes around 4 seconds to raise the inactive event and so the user just sees the blank page while this is happening.
How do I fix (or at least debug) this?
This is my setup (util.js):
var mutexFontsLoaded = $.Callbacks("memory once");
WebFontConfig = {
custom: {
families: ['Chennai-Regular', 'Chennai-Light', 'Chennai-Bold', 'Quicksand-Bold', 'Segoe-Print'],
urls: ['css/fonts.css']
},
loading: function () { console.log("Loading fonts.."); },
active: function () { mutexFontsLoaded.fire(); },
fontinactive: function (font, fvd) { console.log("Could'nt load " + font + " font"); },
inactive: function () { console.log("All fonts failed loading..\n\rTrying to load site anyway.."); mutexFontsLoaded.fire(); }
};
Followed by the Web Font Loader library - 1.5.1
Then in my main script:
$(document).ready(function () {
mutexFontsLoaded.add(function()
{
application.init();
});
});

Debugging the webfont.js library from google's CDN made me see the issue.
Webfont.js injects a <span> with a test string into the <body> DOM element. It then sets the custom font on this span and repeatedly calculates width of the <span> to test for any changes. If it captures a change then it assumes the custom font has loaded. If no change is detected within a timeout then it signals failure.
In my case <body> element was hidden with display: none; because I only wanted to show the page once I knew all the elements are downloaded. Because of this the injected <span> never changed its calculated width.
Finally fixed!

Related

No Style/CSS on initial load with SvelteKit and adapter-static

I created a little page with sveltekit and tailwind css. Now I want to use the sveltejsadapter-static to create a complete static html version. This works fine for all subpages like /imprint or /privacy but the the first page / doesn't load the stylesheet.
Here's my svelte.config.js
import adapter from '#sveltejs/adapter-static';
const config = {
kit: {
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: null,
precompress: false
}),
trailingSlash: 'always',
prerender: {
default: true
}
},
};
export default config;
By browsing to /imprint all styles look fine. The link to the stylesheet starts with /_app/…
When I load the base url, I can see the correct styles flashing for some milliseconds, but after that, all styles are gone. If I remove the / of the style and js links in the source code (_app/…), the page looks fine. But I can't find an option to create the first index file without the staring slash.
Also strange: When I click on the logo from /imprint (which links to /), the page looks fine, but never on first load.
Found the solution.
I defined the html tag in a component which is already defined in the app.html.
<svelte:head>
<html lang="de" />
</svelte:head>

Aframe component with dependencies on component with multiple true

I am writing a custom component that I would like to define other component dependencies.
The dependencies are different animations types.
Let's say they have the names "animation__x" and "animation__y"
x and y can be any name, so I am looking for something like animation__*
or /animation__\s*/
The only way I have made this work at the moment is either ensuring my component is placed after the animation components on the HTML or alternatively to force update components using this.el.updateComponents()
Neither of these solutions feels right to me.
AFRAME.registerComponent('cool-component', {
dependencies: ['animation'],
update: functions(data){
//detect available animations and do some stuff with them
let animations = Object.keys(components).filter((key) => {
return /(^animation__\w*)/.test(key);
});
//animations results in an empty array
}
});
html that is not working
<a-scene cool-component animation__x="" animation__y="" animation__z=""></a-scene>
html that is working (but its not good as I cant ensure my component is always last in the list
<a-scene animation__x="" animation__y="" animation__z="" cool-component></a-scene>
js that works, but doesnt feel write as I am using the entities internal functions
AFRAME.registerComponent('cool-component', {
dependencies: ['animation'],
update: functions(data){
this.el.updateComponents(); //<-- I DONT LIKE THIS BUT IT WORKS
//detect available animations and do some stuff with them
//now all animations are available as this.el.components
let animations = Object.keys(components).filter((key) => {
return /(^animation__\w*)/.test(key);
});
}
});
Three options:
Depend on the specific component names: dependencies: ['animation__xxx']
Make cool-component set those animations:
AFRAME.registerComponent('cool-component', {
init: functions(data){
this.el.setAttribute('animation__xxx', {...});
}
});
You can also defer cool-component logic until the entity has loaded and all the components have initialized:
init: function () {
this.el.addEvenListener(‘loaded’, this.doStuffAferComponentsLoad.bind(this));
}
More details in what cool-component is trying to accomplish will help to get a more precise answer.

Custom background for Chrome new tab replacement extension

I'm developing a new tab replacement extension for Google Chrome and I'd like to allow the user to customize the background, to do so I'm using the storage.sync API as suggested by this page.
The problem is that the style changes are applied asynchronously, so the default background (white) is briefly used during the page load resulting in unpleasing flashes.
Possible (unsatisfying) solutions are:
do not allow to change the background;
hard code a black background in the CSS (and move the problem to custom light backgrounds);
use a CSS transition (still super-ugly).
What could be an alternative approach?
Follows a minimal example.
manifest.json
{
"manifest_version": 2,
"name": "Dummy",
"version": "0.1.0",
"chrome_url_overrides": {
"newtab": "newtab.html"
},
"permissions": [
"storage"
]
}
newtab.html
<script src="/newtab.js"></script>
newtab.js
chrome.storage.sync.get({background: 'black'}, ({background}) => {
document.body.style.background = background;
});
I come up with a reasonable solution. Basically since the localStorage API is synchronous we can use it as a cache for storage.sync.
Something like this:
newtab.js
// use the value from cache
document.body.style.background = localStorage.getItem('background') || 'black';
// update the cache if the value changes from the outside (will be used the next time)
chrome.storage.sync.get({background: 'black'}, ({background}) => {
localStorage.setItem('background', background);
});
// this represents the user changing the option
function setBackground(background) {
// save to storage.sync
chrome.storage.sync.set({background}, () => {
// TODO handle error
// update the cache
localStorage.setItem('background', background);
});
}
This doesn't work 100% of the times but neither do the simple:
document.body.style.background = 'black';
So it's good enough.¹
¹ In the real extension I change the CSS variables directly and I obtain much better results than setting the element style.

Angular Universal: serving critical CSS and delaying non-critical

This is basically the code I am using and lighthouse says my (almost empty!) css bundle is delaying my initial load.
So how do I put a link to critical.scss in the
<head><style>DONT_WANT_TO_WRITE_STUFF_INLINED</style>...</head>
Is there a better solution than https://www.npmjs.com/package/critical or writing everything inlined?
And how do I delay the load of the main styles.scss until the prerendered Universal content is loaded in the browser? The server-app's config in angular-cli.json does not contain styles or assets, so I don't understand why styles.scss is loaded initially
Regarding delaying the load of the main styles.scss, I rely on two things:
First of all, I build the application with the --extract-css=false flag. That ensures that the styles bundle will be a JavaScript file.
Second, I defer the loading of that file. To do so I rely on a small script that I called defer.styles.js and that runs at the end of the build process. That script simply looks for the script tag that loads the styles, and adds a defer to it.
const path = require('path');
const htmlPath = path.join(__dirname, 'dist', 'browser', 'index.html');
fs.readFile(htmlPath, 'utf8', (err, data) => {
if (err) {
console.log(err);
return;
}
const index = data.search(`src="styles.`);
if (index > -1) {
const output = [data.slice(0, index), 'defer ', data.slice(index)].join('');
console.log(output);
fs.writeFile(htmlPath, output, 'utf8', () => {
console.log('Styles succesfully deferred');
})
}
});
Regarding your other question - how to load the critical css -. I still didn't find a way of comfortably doing it.

Web Font Loader - FontAwesome always reports inactive in IE

My site has some customers that work for organizations who are blocking font downloads in IE, so I need to create fallback options for FontAwesome. I am trying to use web font loader to detect if FontAwesome loaded correctly, but web font loader is always reporting that FontAwesome failed to load even though I can see that the FontAwesome icons loaded. I have tested IE 9/10/11.
You can view this in action at https://vnext.radresponder.net. You will see that in Firefox and Chrome, FontAwesome is correctly loaded and marked as active; however, in IE the font loads but then web font loader fires the failed to load callback and attaches the inactive class to the HTML tag. I have special CSS to load some fallback characters to replace the FontAwesome icons which are then loaded.
From the web font loader GitHub page, I don't see any incompatibilities listed with IE, so I assume this should work.
Here is my WebFont.load statement.
WebFont.load({
custom: {
families: ['FontAwesome'],
urls: ['/local/address/for/fontawesome.css'],
testStrings: {
'FontAwesome': '\uf00c\uf000'
}
},
loading: function () {
console.log("loading");
},
fontloading: function (fontFamily, fontDescription) {
console.log('fontloading: ' + fontFamily);
},
fontactive: function (fontFamily, fontDescription) {
console.log('fontActive: ' + fontFamily);
},
fontinactive: function (fontFamily, fontDescription) {
console.log('fontInActive: ' + fontFamily);
},
active: function () {
console.log("active: loaded all web fonts");
},
inactive: function () {
console.log("inactive: did not load all web fonts");
}
});
Edit - 2015/05/27 9:58 am
I changed the timeout from the default 3 seconds to 10 seconds, and the load is definitely taking all 10s and then timing out. I am not sure what that means. Why is it only timing out on IE?

Resources