there are two events related to web page load - ondomcontentloaded and onload.
At which point will the user will be able to see the web page?
That really depends on the browser. Chrome and Firefox progressively render the webpage as it loads, even if HTML hasn't been completely sent. This will be happening before either of those events are triggered.
onload will always fire after DOMContentLoaded, so if you want the earliest event, use DOMContentLoaded.
Related
I am able to calculate page load times in selenium with the following code:
Code: Selenium C#
using OpenQA.Selenium;
double requestStart = (long)((IJavaScriptExecutor)CTest.Driver).ExecuteScript("return window.performance.timing.requestStart");
double domComplete = (long)((IJavaScriptExecutor)CTest.Driver).ExecuteScript("return window.performance.timing.domComplete");
var totaltime = domComplete - requestStart;
Through trail and error, I was able to determine that totaltime the above code corresponds to the value Load in the below picture. Load in image always seems to be the same as the value of DOMContentLoaded variable.
Question:
Why is value for Finish not the same time? What is Finish and how do you calculate this using javascript's window.performance.timing object?
How do you calculate the time between typing a url into a web browser (and hitting enter) and the time when all content on the page is finally loaded?
The following document was pretty good at describing what each timing variable was measuring
mozilla-developer timestamp variables, but the Finish value in chrome devtools is muddying the water.
Figure: Extracting Performance information from Chrome's Devtool (F12) Network tab
Edit:
Thanks #wOxxOm. I noticed that the Finish time kept increasing as I interacted with the website (went to different pages in the website) whereas DOMContentLoaded and Load never changed after the initial load event. This corresponds to what you say in your response.
I switched to using the following code as you suggested:
double connectStart = (long)((IJavaScriptExecutor)CTest.Driver).ExecuteScript("return window.performance.timing.connectStart");
double loadEventEnd = (long)((IJavaScriptExecutor)CTest.Driver).ExecuteScript("return window.performance.timing.loadEventEnd");
double newMeasure = (loadEventEnd - connectStart) / 1000.0;
Also started looking into LCP feature in Chrome 77.
I did have one more question
Question 2:
I initially thought the values within the window.performance object would be repopulated with new values (times) as I clicked on a link (on the website) which would take me to a different page within the same website. However, all the window.performance values never change after the initial load of the website (DOMContentLoaded and Load values within Chrome’s devtool network window also never changed when maneuvering around in the website).
Question: Why did the values from window.performance never change? Was it because this is a SPA (Single Page Application)? I observed chrome devtool’s DOMContentLoaded and Load values when clicking around in a different website (older) and each time I went to a new page within that website, the DOMContentLoaded and Load times changed to show load time for every page within the website (went to different pages by clicking a link in the main menu of that website).
Why is finished not equal domComplete - requestStart?
DOMContentLoaded means all the DOM content is loaded, but javascript and images are still loading.
Load means all the content including javascript and images are loaded. If you start lazy loading images and javascript before this event has been fired, it will delay this event and slow down your page load event. This will have a negative effect on your google lighthouse score.
Finished in chrome dev tools include asynchronously loading assets, which may continue downloading way after the onload event has been fired. As soon as one of your scripts start loading more content via ajax, the finished time will increase. This number should generally help you to see how long it takes to load all the content, including lazy loaded images, scripts ect. which can and should be loaded after the load event to improve your page for SEO.
How to calculate the time between typing a url into a web browser and page being loaded?
The real important event, which search engines look at, is the load event. So you do not really care about the finish time. You want to move all content, which is not needed for the first interaction with your app, to be lazy loaded after this event has been fired.
Furthermore you are looking for navigationStart rather than requestStart. There will be some time between user pressing enter (navigationStart) and the request actually being executed (requestStart).
W3C spec:
navigationStart
This attribute must return the time immediately after the user agent
finishes prompting to unload the previous document. If there is no
previous document, this attribute must return the time the current
document is created.
MDN quote
performance.timing.navigationStart + performance.now() will be
approximately equal to Date.now()
Firing performance.now() onload tells you how long it took to get there.
However it is not supported by IE9 and some browsers round the results. Using Date.now() - window.performance.timing.navigationStart gives more consistent results and is supported by IE9.
JS for logging the time of load event.
window.addEventListener('load', (event) => {
console.log('All assets are loaded')
console.log(Date.now() - window.performance.timing.navigationStart);
});
Why window.performance values never change after the initial load?
This is related to SPA pages. Once the DOM and initial assets are loaded, everything else is loaded async. Routing for SPAs is handled in the frontend and does not trigger a new page load in chrome dev tools. Even when manually reloading the page, you have to disable the 'preserve log' option in the network tab to get fresh performance values.
I am starting with chrome extension development and have a couple of questions regarding extension install/update flow and testing during the development :
What happens with the background script after extension update, does chrome perform background script reload ?
Are content scripts detached from background script after extension update ?
If there's an onInstalled event handler in background script, what happens with that event handler when chrome updates extension(is this event handler detached, and when update finishes, the new handler is attached and then executed or some other flow is exercised) ?
Is there a way to simulate update process during development in order to debug events that happen during the update process, for example to host extension on some local server and update from there ?
where to search for documentation on topics like this and similar, is the chromium source code the right place or at least the starting point ?
Thanks!
What happens with the background script after extension update, does Chrome perform background script reload?
The behavior depends on whether you have a handler to chrome.runtime.onUpdateAvailable event registered and whether your extension has a persistent background page or event page.
If you have a persistent background page:
If you handle this event and call chrome.runtime.reload(), the extension is unloaded and then updated before being loaded again.
If you handle this event and do not call chrome.runtime.reload(), then the update will only apply when the extension is next reloaded - likely the next full browser restart.
If you do not handle this event at all, the extension will be unloaded immediately to be updated.
If you have a non-persistent Event page:
If you handle this event and call chrome.runtime.reload(), the extension is updated before being loaded again.
If you do not call chrome.runtime.reload(), or do not handle the event at all, Chrome will update the extension when the Event page next gets unloaded.
There is no way to programmatically prevent the update once the background page gets unloaded for whatever reason.
Are content scripts detached from background script after extension update?
Yes, and it's not pretty. They enter an "orphaned" state when using Chrome API gives inconsistent errors (some do nothing, some trigger exceptions), but are still running — for example, any DOM event listeners will still trigger.
As such, if you want the content scripts to work immediately again, your job is to:
Inject scripts programmatically in existing tabs, without making an assumption that it did not execute before: cleanup first if necessary.
Make sure orphaned copies stop executing: either by noticing in the old copy that it's orphaned, or by broadcasting a DOM event from the new copy.
Important note about WebExtensions: Firefox, unlike Chrome, always reinjects content scripts on load into pages that match manifest entries. Make sure to take that into account.
There are a few question that cover this; for example:
Sending message from a background script to a content script, then to a injected script (See addendum to the answer)
How to properly handle chrome extension updates from content scripts
Chrome extension content script re-injection after upgrade or install
If there's an onInstalled event handler in background script, what happens with that event handler when chrome updates extension (is this event handler detached, and when update finishes, the new handler is attached and then executed or some other flow is exercised)?
Since an update can only happen while the background page is unloaded, there is no complex logic; it will simply fire on first load of the extension afterwards with details.reason == "update". Be sure to register the handler synchronously on script load (e.g. in top level code), or else you may miss the event — normally this only concerns Event pages, but I suspect it's also important here.
Is there a way to simulate update process during development in order to debug events that happen during the update process, for example to host extension on some local server and update from there?
Sadly, this is no longer possible to the best of my knowledge, unless you can use Enterprise Policy install. Your best bet is to have an extension in CWS that's published as Private.
To a certain extent, pressing "Reload" after making some changes to an unpacked extension simulates what happens during the update - with the exception of onInstalled event.
Where to search for documentation on topics like this and similar, is the chromium source code the right place or at least the starting point?
Well.. For detailed questions Chromium code is, of course, the authoritative source. You should search StackOverflow as well, as there's quite a body of knowledge amassed here already. Finally, the official docs provide a lot of information, even if it's not immediately evident - the chrome.runtime API docs, for example.
In my Firefox extension I am using DOMContentLoaded to detect page load and insert my HTML. Is there an event which triggers before this and still the document is available at that time?
Note: This answer refers to XUL-based extensions. As of Firefox 57, this technology is obsolete. The functionality mentioned here is no longer available to extensions.
There is content-document-global-created notification that is sent out when a document is created, before any content is added to it (to be precise, it happens when the browser receives the HTTP headers of the response and knows that it isn't a redirect or such). That's the earliest point where you can get the document. The DOMContentLoaded event is fired once Gecko finishes downloading the contents of the document, that's the earlies point where you can access the complete DOM. In between there is a bunch of other events, e.g. lots of progress listener events - which one you use depends on what you are trying to do, there is no general answer.
Currently I am developing a web application for which I am using a pre-loader icon. What I want is that the pre-loader becomes visible every time the user navigates to another page or refreshes the page. So far I have the following solution:
window.onbeforeunload = function() { $("applicationdisabler").show(); };
For Safari and Firefox it works fine when the user clicks a link or refreshes the page. However in IE7 the div only becomes visible when the user clicks a link and NOT when the user refreshes the page.
The user can refresh the page by hitting F5 (on Windows) or any other possible way the browser provided.
Of course I have been looking for some workarounds already. The following code shows the alert in IE7, but the div still doesn't become visible.
window.onbeforeunload = function() { $("applicationdisabler").show(); alert("come on!"); };
The code of my div:
<div id="applicationdisabler"><img src="images/preloader.gif" /></div>
Hopefully someone can help me out.
You need to put the # before the id on the jQuery selector:
$("#applicationdisabler").show();
Why not use just use the onLoad listener instead? Although it would be slightly slower it should be more reliable.
Actually after a bit of looking around I'm not sure modifying the DOM makes any sense unless the onBeforeUnload handler returns false first - i.e. forces the user to stay on the same page.
As I understand it the onBeforeUnload event is fired just before the page is unloaded, so if you don't return false the browser will unload the page and DOM, and any JavaScript executed after that will be pointless.
That doesn't quite explain why JavaScript isn't executed properly in the onBeforeUnload function, but from what I've seen sites only use the window.alert or window.prompt dialogs to ask the user if they want to leave the site, and then often executing JavaScript if the user decides to stay.
Hence I'm guessing that some browsers may not allow DOM manipulation when this event is fired - since if the page is unloaded any DOM manipulation done is completely pointless.
So either:
Return false in your onBeforeUnload method, and then show your preloader (although this will stop navigation to the next page)
Use the onLoad event of the next page to show the preloader image instead
Also note: Opera versions 9.5 and below do not support this event (I'm unsure about later versions) but GMail does manage to catch the back button in Opera.
Possibly related is this security warning for IE7's implementation of the onBeforeUnload event - it's possible Microsoft patched it in a way that prevents the things you're trying to do. And I know IE6 and below don't allow commands like document.location='' in the onBeforeUnload handler for security reasons.
I'm attaching some functionality to javascript by doing a firefox addon. However when coding in chrome and listening to the load event in the chrome overlay triggers for every loaded tab, but the "content" variable only points to the tab currently in the foreground.
How can I get the content of every tab upon document load from a firefox addon?
Assuming you are using code like this to be told every time a new page loads (which is what you really want to use if you aren't), aEvent.originalTarget is a reference to the document that the event was for.