How to fix "Lighthouse returned error: NO_FCP." when running Google Page Speed Test? - lighthouse

I am running the Google Page Speed test for https://www.oceanluxe.com.au and get the following message:
> Lighthouse returned error: NO_FCP. Something went wrong with the recording
> the trace over your page load. Please run the Lighthouse again. (NO_FCP)
> (NO_FCP)
Can anyone help?
Tried on different servers, tried various URLs as well http://oceanluxe.com.au

Try to do a test again in incognito mode. I had the same problem today and clearing the cookies and cached files helped in my case.

I got the same error. It was because the page was not able to print anything on the screen within a stipulated time.I just printed something before time consuming code and that fixed the issue.

You can try this work around, it helped me:
First open "https://www.google.com/" or any good website URL then open you website URL.
This may show two tabs mobile and desktop. The mobile tab may give same error so one should click on Desktop tab, it may show status of that URL.

Many answers online are based on the assumption that lighthouse is detecting the FCP correctly, and so give instructions on how to resolve actual issues with your site, eg: slow load times, incorrect code, javascript errors, etc; or with your browser, eg: cookies, plugins, caching; This is indeed usually the cause.
However, Lighthouse is not infallible, and sometimes has reasons for actually mis-detecting a perfectly functioning page.
In my case, the problem was that Lighthouse appears to sometimes not consider any element which begins life at opacity: 0, even if that beginning-of life is via an animation. For me, this issue was being triggered by a "fade-in" animation which was used to lessen FOUT. I suspect that this might be caused by an over-zealous fix to this issue from 2020, wherein previously any elements with opacity: 0 would be treated as immediately visible.
eg:
/* THIS IS MIS-DETECTED BY LIGHTHOUSE AS NEVER BEING VISIBLE */
body {
/* default opacity of 1, if animation is not supported */
opacity: 1;
animation-name: fadeIn;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.5s;
}
#keyframes fadeIn {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
Lighthouse will return the NO_FCP error due to the first frame starting at an opacity of 0, even though the page does soon afterwards become opaque.
To trick Lighthouse into doing the right thing, ensure the first frame begins with some value other than zero.
eg:
/* THIS IS DETECTED BY LIGHTHOUSE AS EVENTUALLY BEING VISIBLE */
body {
/* default opacity of 1, if animation is not supported */
opacity: 1;
animation-name: fadeIn;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.5s;
}
#keyframes fadeIn {
0% {
opacity: 0.01;
}
1% {
opacity: 0;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}

Two things can interfere when using the lighthouse tool:
Extensions used
Cookies and cached files
Therefore a 'workaround' here should be straightforward:
Clearing browser data:
Windows, Linux, or Chrome OS ➖ Ctrl + Shift + Del
Mac ➖ ⌘ + Shift + Delete
Using an Incognito window:
Windows, Linux, or Chrome OS ➖ Ctrl + Shift + N
Mac ➖ ⌘ + Shift + N

A 15 second timeout has been introduced when considering the start of the page load. If your page doesn’t respond or any content within ~15 seconds, Lighthouse will bail. This will result in the NO_FCP error.
Until you are able to get your page to load within this timeframe, you won’t be able to do a scan. In most cases, if nothing appears on the page for 15 seconds, that means there is an issue on the server or a firewall is blocking access.

Maybe you just have another lighthouse tool already run. Close or stop lighthouse tool on another tab and try again

Related

WebdriverIO: Have waitForDisplayed() not fail a test if it returns false

I'm using WebdriverIO and Appium in Javascript to test Android/iOS apps.
I have a welcome screen that sometimes shows up after a loading screen. The following code is what I'm using at the moment to skip past the welcome screen.
if(welcomeScreenTitle.waitForDisplayed()){
skipWelcomeScreenButton.click();
}
The problem that I'm having is that if the waitForDisplayed() times out (meaning that the screen hasn't showed up this time), it fails the test. Is there a way that I can do this?
I have tried using
browser.wait(10000);
if(welcomeScreenTitle.isDisplayed()){
skipWelcomeScreenButton.click();
}
But the loading screen time is different depending on the speed of the connection (so might be much longer), and if the welcome screen shows up before 10 seconds, I don't want to wait the full 10 seconds (since most of the time it does show up).
One easier way of doing this is adding a try catch block around your code so that you can suppress the error thrown and continue the execution.
try {
browser.waitForDisaplyed(10000);
if(welcomeScreenTitle.isDisplayed()){
skipWelcomeScreenButton.click();
}
} catch (error) {
console.log('Welcomescreen is not displayed.')
}

.play() for audio tags lag on iOS (and possibly other mobile devices)

I am attempting to rebuild a game that works on itch to be compatible on most major devices and browsers. I have a problem where on iOS (and possibly other mobile devices) a call to play audio tags from click and touch events has quite a significant delay.
I have read about several potential causes, including the 300ms delay, preventDefault for the second click event, stopPropagation for potential parent clicks, different audio formats causing lag in decompression, etc. Nothing seems to work.
Initially my intent was to keep everything in vanilla js without outside libraries to force myself to really learn what's going on under the hood. However, I have been having some success with some outside libraries for other problems, so I tried fastclick.js for this problem. That didn't work for me either. So, if someone knows how to address this issue without a library that would be great, but after looking at the fastclick code, that may be beyond my level of comprehension.
A current build can be found at www.teachersteve.net/assett_loading_with_ian/assett_loading_with_ian.html
Some explanation of my thought process:
I removed anything that is actually game related to try and isolate the problem. I put all the assetts directly in the html to simplify the loading process and wait to start the js after the DOM loaded
document.addEventListener("DOMContentLoaded", doSomething);
I am currently only calling one audio tag to play as I read somewhere that calling multiple tags can overload the decompression process and cause a delay. That seems to not be the issue.
I have 3 different file formats so far for compatibility attempts... I did read that LEI16 (a wav format) might be best because it eliminates compression, although I haven't tried it yet.
This is the rest of the doSomething() function
function doSomething() {
document.body.style.opacity = 1;
document.addEventListener("click", playAudio);
document.addEventListener('click', preventInputDefault);
document.addEventListener('ontouchend', preventInputDefault);
console.log("assetts loaded");
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
function playAudio() {
// backgroundMusic.play();
letterAudio.play();
// correctAnswerAudio.play();
// letterAudio.play();
// correctAnswerAudio.play();
}
function preventInputDefault(evt) {
evt.preventDefault();
console.log("hello preventInputDefault");
evt.stopPropagation();
console.log("hello stopPropagation");
}
}
Thanks!

Web Audio API on iOS Safari do not play even after user interaction

I know that there is a limitation in iOS Safari where the audio is not playing until user triggers an interaction. So I have placed the code inside a touchstart event. But unfortunately, I have tried almost every combination, and I couldn't get it to play on iOS Safari.
Here are the things I have tried:
putting the audio load outside the touchstart callback
try adding a gain node
use 0.01 as the start time
and none of the above works in iOS Safari, but they can all play in desktop Chrome and Safari. Here is the link to the gist, you can see the versions where I made the changes (P.S. the click event is used for testing on desktop)
https://gist.github.com/angelathewebdev/32e0fbd817410db5dea1
Sounds play only when currentTime starts to run, but scheduling sounds exactly at currentTime doesn't seem to work. They need to be a little bit into the future (ex: 10ms). You can use the following createAudioContext function to wait until the context is ready to make noise. User action doesn't seem to be required on iPhone, but no such success on iPad just yet.
function createAudioContext(callback, errback) {
var ac = new webkitAudioContext();
ac.createGainNode(); // .. and discard it. This gets
// the clock running at some point.
var count = 0;
function wait() {
if (ac.currentTime === 0) {
// Not ready yet.
++count;
if (count > 600) {
errback('timeout');
} else {
setTimeout(wait, 100);
}
} else {
// Ready. Pass on the valid audio context.
callback(ac);
}
}
wait();
}
Subsequently, when playing a note, don't call .noteOn(ac.currentTime), but do .noteOn(ac.currentTime + 0.01) instead.

OnBeforePlay .seek doesn't work on iPad

I've scoured the web, upgraded the player, rewritten it 5 times, and now completing my 5th day of failing, and still cannot accomplish what the folks at Longtail tell me will work. (Don't get me wrong, I love 'em there, but this has me ready to jump off a bridge).
I'm simply trying to load a video that will play with Flash or iOS, and upon loading it, immediately go to a specific point in the video useing the .seek() method. Longtail tells me to use the onBeforePlay() function because iOS apparently doesn't respect the start value of the playlist. This code works like smoke with Flash, but ignores the seek in iOS.
Can ANYone assist me with this - it has become the most expensive script I've ever worked on and I have made zero progress at all. :( :( :( Also, I removed all the console functions and tried that, but with the same result.
Full code/player can be seen at http://www.tempurl.us/jw6e.html. You can see that with Flash, the video starts at 60 seconds, but on iOS, it starts at 0.
jwp = jwplayer('jwp').setup({
title: 'Single File Player', width: '720', height:'240', autostart: 'false', listbar: {position: "right",size: 400},
sources:[
{ file: 'http://media3.scctv.net/insight/mp4:nursing_4_clips_400.mp4/playlist.m3u8'},
{ file: 'rtmp://fms.scctv.net/insight/nursing_4_clips_400.mp4'}
]
}
);
jwp.onReady(function() {
// Create a playlist item of the video to play
var newItem = [
{ title: 'Title4 ACUTE_ABDO_PAIN_400',
image: 'playlistitem.png',
sources:[
{ file: 'http://media3.scctv.net/insight/mp4:ACUTE_ABDO_PAIN_400.mp4/playlist.m3u8'},
{ file: 'rtmp://fms.scctv.net/insight/ACUTE_ABDO_PAIN_400.mp4'}
]
}
];
jwp.load(newItem);
});
jwp.onBeforePlay(function() {
// This Works on PC/Mac with Flash, but does nothing on iPad/iPhone
jwp.seek(60);
});
Simply to close the question, the bottom line on this problem was that iOS will not allow autostart - period. Knowing that, all the expected events that were not behaving as expected made sense. Once the user initiates the stream with Play, everything works as expected. In our case, this is still a problem because we want to start later in the stream, but knowing that made dealing with it more manageable.
If the problem is iOS will not allow autostart - period. Knowing that,
all the expected events that were not behaving as expected made sense.
Once the user initiates the stream with Play, everything works as
expected
then you can have a play button only for tablet and ios device and on Clicking the play button,
call jwplayer().play(), this could be a work around for your problem, and after you have invoked jwplayer.play, which is only possible with the touch event, after play is triggeredother events will work.
otherwise even if you try jwplayer().play() onReady(), or autostart nothing will work because of iOs will not allow autostart as you said
I've solved this problem on iOS using onBeforePlay with seek() and play(). This work on desktop flash and IOS. Doesn't work on Android using the parameter androidhls:true
jwplayer().onBeforePlay(function() { jwplayer().seek(60); });
jwplayer().play();
As Ethan JWPlayer mentioned in comment use onPlay event. To prevent "loop buffering" as you said just use flag variable:
var isFirstStart = true,
seekValue = 60;
jwplayer().onPlay(function(){
//exit if it's no first playback start
if( !isFirstStart ) {
return;
}
jwplayer().seek(seekValue);
isFirstStart = false;
});

Silverlight 3 IncreaseQuotaTo fails if I call AvailableFreeSpace first

The following code throws an exception...
private void EnsureDiskSpace()
{
using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForSite())
{
const long NEEDED = 1024 * 1024 * 100;
if (file.AvailableFreeSpace < NEEDED)
{
if (!file.IncreaseQuotaTo(NEEDED))
{
throw new Exception();
}
}
}
}
But this code does not (it displays the silverlight "increase quota" dialog)...
private void EnsureDiskSpace()
{
using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForSite())
{
const long NEEDED = 1024 * 1024 * 100;
if (file.Quota < NEEDED)
{
if (!file.IncreaseQuotaTo(NEEDED))
{
throw new Exception();
}
}
}
}
The only difference in the code is that the first one checks file.AvailableFreeSpace and the second checks file.Quota.
Are you not allowed to check the available space before requesting more? It seems like I've seen a few examples on the web that test the available space first. Is this no longer supported in SL3? My application allows users to download files from a server and store them locally. I'd really like to increase the quota by 10% whenever the user runs out of sapce. Is this possible?
I had the same issue. The solution for me was something written in the help files. The increase of disk quota must be initiated from a user interaction such as a button click event. I was requesting increased disk quota from an asynchronous WCF call. By moving the space increase request to a button click the code worked.
In my case, if the WCF detected there was not enough space, the silverlight app informed the user they needed to increase space by clicking a button. When the button was clicked, and the space was increased, I called the WCF service again knowing I now had more space. Not as good a user experience, but it got me past this issue.
There is a subtle bug in your first example.
There may not be enough free space to add your new storage, triggering the request - but the amount you're asking for may be less than the existing quota. This throws the exception and doesn't show the dialog.
The correct line would be
file.IncreaseQuotaTo(file.Quota + NEEDED);
I believe that there were some changes to the behavior in Silverlight 3, but not having worked directly on these features, I'm not completely sure.
I did take a look at this MSDN page on the feature and the recommended approach is definitely the first example you have; they're suggesting:
Get the user store
Check the AvailableFreeSpace property on the store
If needed, call IncreaseQuotaTo
It isn't ideal, since you can't implement your own growth algorithm (grow by 10%, etc.), but you should be able to at least unblock your scenario using the AvailableFreeSpace property, like you say.
I believe reading the amount of total space available (the Quota) to the user store could be in theory an issue, imagine a "rogue" control or app that simply wants to fill every last byte it can in the isolated storage space, forcing the user eventually to request more space, even when not available.
It turns out that both code blocks work... unless you set a break point. For that matter, both code blocks fail if you do set a break point.

Resources