Skip to content
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

Chrome: Deprecation - Unload event listeners are deprecated and will be removed #2220

Open
bdbvb opened this issue Dec 13, 2023 · 4 comments

Comments

@bdbvb
Copy link

bdbvb commented Dec 13, 2023

Description/Screenshot
Chrome indicates an issue when using @microsoft/applicationinsights-web version 3.0.6.

"Deprecated feature used"
"Unload event listeners are deprecated and will be removed."

image

Steps to Reproduce

  • OS/Browser:
    22.0.6170.5 (Official Build) dev (64-bit) (cohort: Dev)
    Windows 11 Version 22H2 (Build 22621.2428)
  • SDK Version [e.g. 22]:
    @microsoft/applicationinsights-web version 3.0.6
  • How you initialized the SDK:
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
import { isNullOrWhitespace } from "../data";

let initialized = false;
let appInsights: ApplicationInsights | null;

export function aiInit(
    connectionString: string,
    appName: string,
    userName?: string) {

    if (initialized) {
        console.log("Telemetry already initialized");
        return;
    }

    appInsights = new ApplicationInsights({
        config: {
            connectionString: connectionString,
            maxBatchInterval: 0,
            disableFetchTracking: false
        }
    });
    appInsights.loadAppInsights();

    const userNameProvided = !isNullOrWhitespace(userName);
    if (userNameProvided) {
        appInsights.setAuthenticatedUserContext(userName!, undefined, true);
    }

    appInsights.addTelemetryInitializer(envelope => {
        if (envelope.tags != null) {
            envelope.tags["ai.cloud.role"] = appName;
            if (userNameProvided) {
                envelope.tags["ai.user.id"] = userName!;
            }
        }
    });

    appInsights.trackPageView();

    initialized = true;
}

export function ai(): ApplicationInsights {
    if (!initialized || appInsights == null) {
        throw new Error("Telemetry not initialized");
    }
    return appInsights;
}

Expected behavior
No issue

@MSNev
Copy link
Collaborator

MSNev commented Dec 13, 2023

Hello, as a generic library we will not be removing the backward compatibility support for "hooking" the unload event.

However,
we have a really badly documented (like barely) configuration option that we introduced in v3.0.3 which allows you to tell use which events you "don't" want us to hook. So you can avoid the "warning" by simply adding the configuration option

/**
* [Optional] An array of the page unload events that you would like to be ignored, special note there must be at least one valid unload
* event hooked, if you list all or the runtime environment only supports a listed "disabled" event it will still be hooked, if required by the SDK.
* Unload events include "beforeunload", "unload", "visibilitychange" (with 'hidden' state) and "pagehide"
*/
disablePageUnloadEvents?: string[];

disablePageUnloadEvents: [ "unload" ],

And once the event is no longer present (which we will still attempt to hook it), it just won't be hooked.

I'm going to mark this issue as a documentation issue as we REALLY need to document this better.
Some readme level documentation exists for the @microsoft/1ds-core-js package which is now co-located in this repo and this is the same configuraiton option as the 1ds-core-js is built on-top of applicationinsights-core-js
https://github.com/microsoft/ApplicationInsights-JS/tree/main/shared/1ds-core-js#iextendedconfiguration

@IanIsFluent
Copy link

Hello, as a generic library we will not be removing the backward compatibility support for "hooking" the unload event.

However, we have a really badly documented (like barely) configuration option that we introduced in v3.0.3 which allows you to tell use which events you "don't" want us to hook. So you can avoid the "warning" by simply adding the configuration option

/**
* [Optional] An array of the page unload events that you would like to be ignored, special note there must be at least one valid unload
* event hooked, if you list all or the runtime environment only supports a listed "disabled" event it will still be hooked, if required by the SDK.
* Unload events include "beforeunload", "unload", "visibilitychange" (with 'hidden' state) and "pagehide"
*/
disablePageUnloadEvents?: string[];

disablePageUnloadEvents: [ "unload" ],

And once the event is no longer present (which we will still attempt to hook it), it just won't be hooked.

I'm going to mark this issue as a documentation issue as we REALLY need to document this better. Some readme level documentation exists for the @microsoft/1ds-core-js package which is now co-located in this repo and this is the same configuraiton option as the 1ds-core-js is built on-top of applicationinsights-core-js https://github.com/microsoft/ApplicationInsights-JS/tree/main/shared/1ds-core-js#iextendedconfiguration

I'm injecting the AI JS into our ASP.NET Razor site using @inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet. Can I change that in a similar way? Thanks!

@MSNev
Copy link
Collaborator

MSNev commented May 3, 2024

Our team doesn't directly maintain the NuGet package, however, the "configuration" that is defined in the snippet does support having this included , see https://github.com/Microsoft/ApplicationInsights-JS?tab=readme-ov-file#snippet-setup-ignore-if-using-npm-setup

The cfg section defined here IS the standard configuration used to initialize the SDK, once it's download. So you just need to be able to have that section updated to include the required configuration.

Additionally, my understanding is that the NuGet package is effective just dropping the snippet onto the page, so it would also be possible to have your own version doing the same thing.

We update updated or snippet generation to package this up so that you could injest the snippet via npm https://github.com/microsoft/ApplicationInsights-JS/tree/main/tools/applicationinsights-web-snippet, however, we have not yet added the ability to pass additional configuration via the "helper" functions that we have provided. But this just returns a string where we have the cfg section populated with the necessary values and we have worked hard to make sure that even the minified version has this information emitted near the end of the script.

@IanIsFluent
Copy link

@MSNev I've tried to set this config value but no luck - still getting a warning in the Chrome Lighthouse report: Uses deprecated APIs (UnloadHandler).

!function(T,l,y){var S=T.location,k="script",D="instrumentationKey",C="ingestionendpoint",I="disableExceptionTracking",E="ai.device.",b="toLowerCase",w="crossOrigin",N="POST",e="appInsightsSDK",t=y.name||"appInsights";(y.name||T[e])&&(T[e]=t);var n=T[t]||function(d){var g=!1,f=!1,m={initialize:!0,queue:[],sv:"5",version:2,config:d};function v(e,t){var n={},a="Browser";return n[E+"id"]=a[b](),n[E+"type"]=a,n["ai.operation.name"]=S&&S.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(m.sv||m.version),{time:function(){var e=new Date;function t(e){var t=""+e;return 1===t.length&&(t="0"+t),t}return e.getUTCFullYear()+"-"+t(1+e.getUTCMonth())+"-"+t(e.getUTCDate())+"T"+t(e.getUTCHours())+":"+t(e.getUTCMinutes())+":"+t(e.getUTCSeconds())+"."+((e.getUTCMilliseconds()/1e3).toFixed(3)+"").slice(2,5)+"Z"}(),iKey:e,name:"Microsoft.ApplicationInsights."+e.replace(/-/g,"")+"."+t,sampleRate:100,tags:n,data:{baseData:{ver:2}}}}var h=d.url||y.src;if(h){function a(e){var t,n,a,i,r,o,s,c,u,p,l;g=!0,m.queue=[],f||(f=!0,t=h,s=function(){var e={},t=d.connectionString;if(t)for(var n=t.split(";"),a=0;a<n.length;a++){var i=n[a].split("=");2===i.length&&(e[i[0][b]()]=i[1])}if(!e[C]){var r=e.endpointsuffix,o=r?e.location:null;e[C]="https://"+(o?o+".":"")+"dc."+(r||"services.visualstudio.com")}return e}(),c=s[D]||d[D]||"",u=s[C],p=u?u+"/v2/track":d.endpointUrl,(l=[]).push((n="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",a=t,i=p,(o=(r=v(c,"Exception")).data).baseType="ExceptionData",o.baseData.exceptions=[{typeName:"SDKLoadFailed",message:n.replace(/\./g,"-"),hasFullStack:!1,stack:n+"\nSnippet failed to load ["+a+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(S&&S.pathname||"_unknown_")+"\nEndpoint: "+i,parsedStack:[]}],r)),l.push(function(e,t,n,a){var i=v(c,"Message"),r=i.data;r.baseType="MessageData";var o=r.baseData;return o.message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+n+")").replace(/\"/g,"")+'"',o.properties={endpoint:a},i}(0,0,t,p)),function(e,t){if(JSON){var n=T.fetch;if(n&&!y.useXhr)n(t,{method:N,body:JSON.stringify(e),mode:"cors"});else if(XMLHttpRequest){var a=new XMLHttpRequest;a.open(N,t),a.setRequestHeader("Content-type","application/json"),a.send(JSON.stringify(e))}}}(l,p))}function i(e,t){f||setTimeout(function(){!t&&m.core||a()},500)}var e=function(){var n=l.createElement(k);n.src=h;var e=y[w];return!e&&""!==e||"undefined"==n[w]||(n[w]=e),n.onload=i,n.onerror=a,n.onreadystatechange=function(e,t){"loaded"!==n.readyState&&"complete"!==n.readyState||i(0,t)},n}();y.ld<0?l.getElementsByTagName("head")[0].appendChild(e):setTimeout(function(){l.getElementsByTagName(k)[0].parentNode.appendChild(e)},y.ld||0)}try{m.cookie=l.cookie}catch(p){}function t(e){for(;e.length;)!function(t){m[t]=function(){var e=arguments;g||m.queue.push(function(){m[t].apply(m,e)})}}(e.pop())}var n="track",r="TrackPage",o="TrackEvent";t([n+"Event",n+"PageView",n+"Exception",n+"Trace",n+"DependencyData",n+"Metric",n+"PageViewPerformance","start"+r,"stop"+r,"start"+o,"stop"+o,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),m.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4};var s=(d.extensionConfig||{}).ApplicationInsightsAnalytics||{};if(!0!==d[I]&&!0!==s[I]){var c="onerror";t(["_"+c]);var u=T[c];T[c]=function(e,t,n,a,i){var r=u&&u(e,t,n,a,i);return!0!==r&&m["_"+c]({message:e,url:t,lineNumber:n,columnNumber:a,error:i}),r},d.autoExceptionInstrumented=!0}return m}(y.cfg);function a(){y.onInit&&y.onInit(n)}(T[t]=n).queue&&0===n.queue.length?(n.queue.push(a),n.trackPageView({})):a()}(window,document,{
src: "https://js.monitor.azure.com/scripts/b/ai.2.min.js", // The SDK URL Source
crossOrigin: "anonymous", 
cfg: { // Application Insights Configuration
    disablePageUnloadEvents: ['unload'], connectionString: 'InstrumentationKey=[GUID];IngestionEndpoint=[EP]'
}});

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

No branches or pull requests

3 participants