added orai
This commit is contained in:
parent
24a1542fff
commit
bc5e7d251a
BIN
24_12_09/24_12_09.pptx
Normal file
BIN
24_12_09/24_12_09.pptx
Normal file
Binary file not shown.
23
24_12_09/komponensek/.gitignore
vendored
Normal file
23
24_12_09/komponensek/.gitignore
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
70
24_12_09/komponensek/README.md
Normal file
70
24_12_09/komponensek/README.md
Normal file
|
@ -0,0 +1,70 @@
|
|||
# Getting Started with Create React App
|
||||
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.\
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
||||
|
||||
The page will reload when you make changes.\
|
||||
You may also see any lint errors in the console.
|
||||
|
||||
### `npm test`
|
||||
|
||||
Launches the test runner in the interactive watch mode.\
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.\
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.\
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `npm run eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
|
||||
|
||||
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
|
||||
|
||||
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
|
15828
24_12_09/komponensek/package-lock.json
generated
Normal file
15828
24_12_09/komponensek/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
35
24_12_09/komponensek/package.json
Normal file
35
24_12_09/komponensek/package.json
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "komponensek",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"cra-template": "1.2.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-scripts": "5.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
BIN
24_12_09/komponensek/public/favicon.ico
Normal file
BIN
24_12_09/komponensek/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
43
24_12_09/komponensek/public/index.html
Normal file
43
24_12_09/komponensek/public/index.html
Normal file
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
BIN
24_12_09/komponensek/public/logo192.png
Normal file
BIN
24_12_09/komponensek/public/logo192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
BIN
24_12_09/komponensek/public/logo512.png
Normal file
BIN
24_12_09/komponensek/public/logo512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
25
24_12_09/komponensek/public/manifest.json
Normal file
25
24_12_09/komponensek/public/manifest.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
3
24_12_09/komponensek/public/robots.txt
Normal file
3
24_12_09/komponensek/public/robots.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
16
24_12_09/komponensek/src/Alma.js
Normal file
16
24_12_09/komponensek/src/Alma.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import React from "react";
|
||||
|
||||
function Alma(){
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
Ez alma!
|
||||
</p>
|
||||
<p>
|
||||
Ugye?
|
||||
</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Alma;
|
38
24_12_09/komponensek/src/App.css
Normal file
38
24_12_09/komponensek/src/App.css
Normal file
|
@ -0,0 +1,38 @@
|
|||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
25
24_12_09/komponensek/src/App.js
Normal file
25
24_12_09/komponensek/src/App.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
import logo from './logo.svg';
|
||||
import './App.css';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<img src={logo} className="App-logo" alt="logo" />
|
||||
<p>
|
||||
Edit <code>src/App.js</code> and save to reload.
|
||||
</p>
|
||||
<a
|
||||
className="App-link"
|
||||
href="https://reactjs.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Learn React
|
||||
</a>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
8
24_12_09/komponensek/src/App.test.js
Normal file
8
24_12_09/komponensek/src/App.test.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
18
24_12_09/komponensek/src/Button.js
Normal file
18
24_12_09/komponensek/src/Button.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import React from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
function Counter(){
|
||||
const [count, setCount] = useState(0);
|
||||
|
||||
function handleClick(){
|
||||
setCount(count + 1);
|
||||
}
|
||||
|
||||
return (
|
||||
<button onClick={handleClick}>
|
||||
Ennyiszer nyomtál meg: {count}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
export default Counter;
|
45
24_12_09/komponensek/src/Gyumolcsok.js
Normal file
45
24_12_09/komponensek/src/Gyumolcsok.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
import React from 'react';
|
||||
import Alma from './Alma';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
/*
|
||||
class Gyumolcs extends React.Component {
|
||||
render(){
|
||||
return (
|
||||
<>
|
||||
<p>Első bekezdés</p>
|
||||
<p>Második bekezdés</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
function Gyumolcs(props){
|
||||
return (
|
||||
<>
|
||||
<p>Első bekezdés</p>
|
||||
<p>Második bekezdés</p>
|
||||
<p>
|
||||
Alma komponens felhasználása
|
||||
</p>
|
||||
<Alma></Alma>
|
||||
<p>A választott gyümölcs: {props.gyumolcs.nev}, ami {props.gyumolcs.iz} ízű</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
*/
|
||||
function Gyumolcs(props){
|
||||
let [nev, setNev] = useState(props.gyumolcs.nev);
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
A létrehozott gyümölcs: {nev}, ami {props.gyumolcs.iz} ízű
|
||||
</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default Gyumolcs;
|
13
24_12_09/komponensek/src/index.css
Normal file
13
24_12_09/komponensek/src/index.css
Normal file
|
@ -0,0 +1,13 @@
|
|||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
23
24_12_09/komponensek/src/index.js
Normal file
23
24_12_09/komponensek/src/index.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
|
||||
import Gyumolcs from './Gyumolcsok';
|
||||
import Counter from './Button';
|
||||
|
||||
let gyumi = {nev: "Banán", iz: "Édes"};
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(
|
||||
<>
|
||||
<Gyumolcs gyumolcs={gyumi}/>
|
||||
<Counter></Counter>
|
||||
</>
|
||||
);
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
1
24_12_09/komponensek/src/logo.svg
Normal file
1
24_12_09/komponensek/src/logo.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
|
After Width: | Height: | Size: 2.6 KiB |
13
24_12_09/komponensek/src/reportWebVitals.js
Normal file
13
24_12_09/komponensek/src/reportWebVitals.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
const reportWebVitals = onPerfEntry => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
5
24_12_09/komponensek/src/setupTests.js
Normal file
5
24_12_09/komponensek/src/setupTests.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
12
24_12_09/node_modules/.package-lock.json
generated
vendored
Normal file
12
24_12_09/node_modules/.package-lock.json
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "24_12_09",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/web-vitals": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz",
|
||||
"integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw=="
|
||||
}
|
||||
}
|
||||
}
|
202
24_12_09/node_modules/web-vitals/LICENSE
generated
vendored
Normal file
202
24_12_09/node_modules/web-vitals/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2020 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
1156
24_12_09/node_modules/web-vitals/README.md
generated
vendored
Normal file
1156
24_12_09/node_modules/web-vitals/README.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
16
24_12_09/node_modules/web-vitals/attribution.d.ts
generated
vendored
Normal file
16
24_12_09/node_modules/web-vitals/attribution.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
Copyright 2022 Google LLC
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './dist/modules/attribution/index.js';
|
18
24_12_09/node_modules/web-vitals/attribution.js
generated
vendored
Normal file
18
24_12_09/node_modules/web-vitals/attribution.js
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2022 Google LLC
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Creates the `web-vitals/attribution` import in node-based bundlers.
|
||||
// This will not be needed when export maps are widely supported.
|
||||
export * from './dist/web-vitals.attribution.js';
|
7
24_12_09/node_modules/web-vitals/dist/modules/attribution/deprecated.d.ts
generated
vendored
Normal file
7
24_12_09/node_modules/web-vitals/dist/modules/attribution/deprecated.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
export {
|
||||
/**
|
||||
* @deprecated Use `onINP()` instead.
|
||||
*/
|
||||
onFID, } from './onFID.js';
|
||||
export { FIDThresholds } from '../onFID.js';
|
||||
export * from '../types.js';
|
22
24_12_09/node_modules/web-vitals/dist/modules/attribution/deprecated.js
generated
vendored
Normal file
22
24_12_09/node_modules/web-vitals/dist/modules/attribution/deprecated.js
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export {
|
||||
/**
|
||||
* @deprecated Use `onINP()` instead.
|
||||
*/
|
||||
onFID, } from './onFID.js';
|
||||
export { FIDThresholds } from '../onFID.js';
|
||||
export * from '../types.js';
|
12
24_12_09/node_modules/web-vitals/dist/modules/attribution/index.d.ts
generated
vendored
Normal file
12
24_12_09/node_modules/web-vitals/dist/modules/attribution/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
export { onCLS } from './onCLS.js';
|
||||
export { onFCP } from './onFCP.js';
|
||||
export { onINP } from './onINP.js';
|
||||
export { onLCP } from './onLCP.js';
|
||||
export { onTTFB } from './onTTFB.js';
|
||||
export { CLSThresholds } from '../onCLS.js';
|
||||
export { FCPThresholds } from '../onFCP.js';
|
||||
export { INPThresholds } from '../onINP.js';
|
||||
export { LCPThresholds } from '../onLCP.js';
|
||||
export { TTFBThresholds } from '../onTTFB.js';
|
||||
export * from './deprecated.js';
|
||||
export * from '../types.js';
|
27
24_12_09/node_modules/web-vitals/dist/modules/attribution/index.js
generated
vendored
Normal file
27
24_12_09/node_modules/web-vitals/dist/modules/attribution/index.js
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { onCLS } from './onCLS.js';
|
||||
export { onFCP } from './onFCP.js';
|
||||
export { onINP } from './onINP.js';
|
||||
export { onLCP } from './onLCP.js';
|
||||
export { onTTFB } from './onTTFB.js';
|
||||
export { CLSThresholds } from '../onCLS.js';
|
||||
export { FCPThresholds } from '../onFCP.js';
|
||||
export { INPThresholds } from '../onINP.js';
|
||||
export { LCPThresholds } from '../onLCP.js';
|
||||
export { TTFBThresholds } from '../onTTFB.js';
|
||||
export * from './deprecated.js';
|
||||
export * from '../types.js';
|
23
24_12_09/node_modules/web-vitals/dist/modules/attribution/onCLS.d.ts
generated
vendored
Normal file
23
24_12_09/node_modules/web-vitals/dist/modules/attribution/onCLS.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { CLSMetricWithAttribution, ReportOpts } from '../types.js';
|
||||
/**
|
||||
* Calculates the [CLS](https://web.dev/articles/cls) value for the current page and
|
||||
* calls the `callback` function once the value is ready to be reported, along
|
||||
* with all `layout-shift` performance entries that were used in the metric
|
||||
* value calculation. The reported value is a `double` (corresponding to a
|
||||
* [layout shift score](https://web.dev/articles/cls#layout_shift_score)).
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called as soon as the value is initially
|
||||
* determined as well as any time the value changes throughout the page
|
||||
* lifespan.
|
||||
*
|
||||
* _**Important:** CLS should be continually monitored for changes throughout
|
||||
* the entire lifespan of a page—including if the user returns to the page after
|
||||
* it's been hidden/backgrounded. However, since browsers often [will not fire
|
||||
* additional callbacks once the user has backgrounded a
|
||||
* page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
|
||||
* `callback` is always called when the page's visibility state changes to
|
||||
* hidden. As a result, the `callback` function might be called multiple times
|
||||
* during the same page load._
|
||||
*/
|
||||
export declare const onCLS: (onReport: (metric: CLSMetricWithAttribution) => void, opts?: ReportOpts) => void;
|
74
24_12_09/node_modules/web-vitals/dist/modules/attribution/onCLS.js
generated
vendored
Normal file
74
24_12_09/node_modules/web-vitals/dist/modules/attribution/onCLS.js
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { getLoadState } from '../lib/getLoadState.js';
|
||||
import { getSelector } from '../lib/getSelector.js';
|
||||
import { onCLS as unattributedOnCLS } from '../onCLS.js';
|
||||
const getLargestLayoutShiftEntry = (entries) => {
|
||||
return entries.reduce((a, b) => (a && a.value > b.value ? a : b));
|
||||
};
|
||||
const getLargestLayoutShiftSource = (sources) => {
|
||||
return sources.find((s) => s.node && s.node.nodeType === 1) || sources[0];
|
||||
};
|
||||
const attributeCLS = (metric) => {
|
||||
// Use an empty object if no other attribution has been set.
|
||||
let attribution = {};
|
||||
if (metric.entries.length) {
|
||||
const largestEntry = getLargestLayoutShiftEntry(metric.entries);
|
||||
if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
|
||||
const largestSource = getLargestLayoutShiftSource(largestEntry.sources);
|
||||
if (largestSource) {
|
||||
attribution = {
|
||||
largestShiftTarget: getSelector(largestSource.node),
|
||||
largestShiftTime: largestEntry.startTime,
|
||||
largestShiftValue: largestEntry.value,
|
||||
largestShiftSource: largestSource,
|
||||
largestShiftEntry: largestEntry,
|
||||
loadState: getLoadState(largestEntry.startTime),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use Object.assign to set property to keep tsc happy.
|
||||
const metricWithAttribution = Object.assign(metric, { attribution });
|
||||
return metricWithAttribution;
|
||||
};
|
||||
/**
|
||||
* Calculates the [CLS](https://web.dev/articles/cls) value for the current page and
|
||||
* calls the `callback` function once the value is ready to be reported, along
|
||||
* with all `layout-shift` performance entries that were used in the metric
|
||||
* value calculation. The reported value is a `double` (corresponding to a
|
||||
* [layout shift score](https://web.dev/articles/cls#layout_shift_score)).
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called as soon as the value is initially
|
||||
* determined as well as any time the value changes throughout the page
|
||||
* lifespan.
|
||||
*
|
||||
* _**Important:** CLS should be continually monitored for changes throughout
|
||||
* the entire lifespan of a page—including if the user returns to the page after
|
||||
* it's been hidden/backgrounded. However, since browsers often [will not fire
|
||||
* additional callbacks once the user has backgrounded a
|
||||
* page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
|
||||
* `callback` is always called when the page's visibility state changes to
|
||||
* hidden. As a result, the `callback` function might be called multiple times
|
||||
* during the same page load._
|
||||
*/
|
||||
export const onCLS = (onReport, opts) => {
|
||||
unattributedOnCLS((metric) => {
|
||||
const metricWithAttribution = attributeCLS(metric);
|
||||
onReport(metricWithAttribution);
|
||||
}, opts);
|
||||
};
|
8
24_12_09/node_modules/web-vitals/dist/modules/attribution/onFCP.d.ts
generated
vendored
Normal file
8
24_12_09/node_modules/web-vitals/dist/modules/attribution/onFCP.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { FCPMetricWithAttribution, ReportOpts } from '../types.js';
|
||||
/**
|
||||
* Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and
|
||||
* calls the `callback` function once the value is ready, along with the
|
||||
* relevant `paint` performance entry used to determine the value. The reported
|
||||
* value is a `DOMHighResTimeStamp`.
|
||||
*/
|
||||
export declare const onFCP: (onReport: (metric: FCPMetricWithAttribution) => void, opts?: ReportOpts) => void;
|
57
24_12_09/node_modules/web-vitals/dist/modules/attribution/onFCP.js
generated
vendored
Normal file
57
24_12_09/node_modules/web-vitals/dist/modules/attribution/onFCP.js
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { getBFCacheRestoreTime } from '../lib/bfcache.js';
|
||||
import { getLoadState } from '../lib/getLoadState.js';
|
||||
import { getNavigationEntry } from '../lib/getNavigationEntry.js';
|
||||
import { onFCP as unattributedOnFCP } from '../onFCP.js';
|
||||
const attributeFCP = (metric) => {
|
||||
// Use a default object if no other attribution has been set.
|
||||
let attribution = {
|
||||
timeToFirstByte: 0,
|
||||
firstByteToFCP: metric.value,
|
||||
loadState: getLoadState(getBFCacheRestoreTime()),
|
||||
};
|
||||
if (metric.entries.length) {
|
||||
const navigationEntry = getNavigationEntry();
|
||||
const fcpEntry = metric.entries[metric.entries.length - 1];
|
||||
if (navigationEntry) {
|
||||
const activationStart = navigationEntry.activationStart || 0;
|
||||
const ttfb = Math.max(0, navigationEntry.responseStart - activationStart);
|
||||
attribution = {
|
||||
timeToFirstByte: ttfb,
|
||||
firstByteToFCP: metric.value - ttfb,
|
||||
loadState: getLoadState(metric.entries[0].startTime),
|
||||
navigationEntry,
|
||||
fcpEntry,
|
||||
};
|
||||
}
|
||||
}
|
||||
// Use Object.assign to set property to keep tsc happy.
|
||||
const metricWithAttribution = Object.assign(metric, { attribution });
|
||||
return metricWithAttribution;
|
||||
};
|
||||
/**
|
||||
* Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and
|
||||
* calls the `callback` function once the value is ready, along with the
|
||||
* relevant `paint` performance entry used to determine the value. The reported
|
||||
* value is a `DOMHighResTimeStamp`.
|
||||
*/
|
||||
export const onFCP = (onReport, opts) => {
|
||||
unattributedOnFCP((metric) => {
|
||||
const metricWithAttribution = attributeFCP(metric);
|
||||
onReport(metricWithAttribution);
|
||||
}, opts);
|
||||
};
|
11
24_12_09/node_modules/web-vitals/dist/modules/attribution/onFID.d.ts
generated
vendored
Normal file
11
24_12_09/node_modules/web-vitals/dist/modules/attribution/onFID.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { FIDMetricWithAttribution, ReportOpts } from '../types.js';
|
||||
/**
|
||||
* Calculates the [FID](https://web.dev/articles/fid) value for the current page and
|
||||
* calls the `callback` function once the value is ready, along with the
|
||||
* relevant `first-input` performance entry used to determine the value. The
|
||||
* reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* _**Important:** since FID is only reported after the user interacts with the
|
||||
* page, it's possible that it will not be reported for some page loads._
|
||||
*/
|
||||
export declare const onFID: (onReport: (metric: FIDMetricWithAttribution) => void, opts?: ReportOpts) => void;
|
46
24_12_09/node_modules/web-vitals/dist/modules/attribution/onFID.js
generated
vendored
Normal file
46
24_12_09/node_modules/web-vitals/dist/modules/attribution/onFID.js
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { getLoadState } from '../lib/getLoadState.js';
|
||||
import { getSelector } from '../lib/getSelector.js';
|
||||
import { onFID as unattributedOnFID } from '../onFID.js';
|
||||
const attributeFID = (metric) => {
|
||||
const fidEntry = metric.entries[0];
|
||||
const attribution = {
|
||||
eventTarget: getSelector(fidEntry.target),
|
||||
eventType: fidEntry.name,
|
||||
eventTime: fidEntry.startTime,
|
||||
eventEntry: fidEntry,
|
||||
loadState: getLoadState(fidEntry.startTime),
|
||||
};
|
||||
// Use Object.assign to set property to keep tsc happy.
|
||||
const metricWithAttribution = Object.assign(metric, { attribution });
|
||||
return metricWithAttribution;
|
||||
};
|
||||
/**
|
||||
* Calculates the [FID](https://web.dev/articles/fid) value for the current page and
|
||||
* calls the `callback` function once the value is ready, along with the
|
||||
* relevant `first-input` performance entry used to determine the value. The
|
||||
* reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* _**Important:** since FID is only reported after the user interacts with the
|
||||
* page, it's possible that it will not be reported for some page loads._
|
||||
*/
|
||||
export const onFID = (onReport, opts) => {
|
||||
unattributedOnFID((metric) => {
|
||||
const metricWithAttribution = attributeFID(metric);
|
||||
onReport(metricWithAttribution);
|
||||
}, opts);
|
||||
};
|
30
24_12_09/node_modules/web-vitals/dist/modules/attribution/onINP.d.ts
generated
vendored
Normal file
30
24_12_09/node_modules/web-vitals/dist/modules/attribution/onINP.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { INPMetricWithAttribution, ReportOpts } from '../types.js';
|
||||
export declare const interactionTargetMap: Map<number, Node>;
|
||||
/**
|
||||
* Calculates the [INP](https://web.dev/articles/inp) value for the current
|
||||
* page and calls the `callback` function once the value is ready, along with
|
||||
* the `event` performance entries reported for that interaction. The reported
|
||||
* value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* A custom `durationThreshold` configuration option can optionally be passed to
|
||||
* control what `event-timing` entries are considered for INP reporting. The
|
||||
* default threshold is `40`, which means INP scores of less than 40 are
|
||||
* reported as 0. Note that this will not affect your 75th percentile INP value
|
||||
* unless that value is also less than 40 (well below the recommended
|
||||
* [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called as soon as the value is initially
|
||||
* determined as well as any time the value changes throughout the page
|
||||
* lifespan.
|
||||
*
|
||||
* _**Important:** INP should be continually monitored for changes throughout
|
||||
* the entire lifespan of a page—including if the user returns to the page after
|
||||
* it's been hidden/backgrounded. However, since browsers often [will not fire
|
||||
* additional callbacks once the user has backgrounded a
|
||||
* page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
|
||||
* `callback` is always called when the page's visibility state changes to
|
||||
* hidden. As a result, the `callback` function might be called multiple times
|
||||
* during the same page load._
|
||||
*/
|
||||
export declare const onINP: (onReport: (metric: INPMetricWithAttribution) => void, opts?: ReportOpts) => void;
|
256
24_12_09/node_modules/web-vitals/dist/modules/attribution/onINP.js
generated
vendored
Normal file
256
24_12_09/node_modules/web-vitals/dist/modules/attribution/onINP.js
generated
vendored
Normal file
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { getLoadState } from '../lib/getLoadState.js';
|
||||
import { getSelector } from '../lib/getSelector.js';
|
||||
import { longestInteractionList, entryPreProcessingCallbacks, longestInteractionMap, } from '../lib/interactions.js';
|
||||
import { observe } from '../lib/observe.js';
|
||||
import { whenIdle } from '../lib/whenIdle.js';
|
||||
import { onINP as unattributedOnINP } from '../onINP.js';
|
||||
// The maximum number of previous frames for which data is kept.
|
||||
// Storing data about previous frames is necessary to handle cases where event
|
||||
// and LoAF entries are dispatched out of order, and so a buffer of previous
|
||||
// frame data is needed to determine various bits of INP attribution once all
|
||||
// the frame-related data has come in.
|
||||
// In most cases this out-of-order data is only off by a frame or two, so
|
||||
// keeping the most recent 50 should be more than sufficient.
|
||||
const MAX_PREVIOUS_FRAMES = 50;
|
||||
// A PerformanceObserver, observing new `long-animation-frame` entries.
|
||||
// If this variable is defined it means the browser supports LoAF.
|
||||
let loafObserver;
|
||||
// A list of LoAF entries that have been dispatched and could potentially
|
||||
// intersect with the INP candidate interaction. Note that periodically this
|
||||
// list is cleaned up and entries that are known to not match INP are removed.
|
||||
let pendingLoAFs = [];
|
||||
// An array of groups of all the event timing entries that occurred within a
|
||||
// particular frame. Note that periodically this array is cleaned up and entries
|
||||
// that are known to not match INP are removed.
|
||||
let pendingEntriesGroups = [];
|
||||
// The `processingEnd` time of most recently-processed event, chronologically.
|
||||
let latestProcessingEnd = 0;
|
||||
// A WeakMap to look up the event-timing-entries group of a given entry.
|
||||
// Note that this only maps from "important" entries: either the first input or
|
||||
// those with an `interactionId`.
|
||||
const entryToEntriesGroupMap = new WeakMap();
|
||||
// A mapping of interactionIds to the target Node.
|
||||
export const interactionTargetMap = new Map();
|
||||
// A reference to the idle task used to clean up entries from the above
|
||||
// variables. If the value is -1 it means no task is queue, and if it's
|
||||
// greater than -1 the value corresponds to the idle callback handle.
|
||||
let idleHandle = -1;
|
||||
/**
|
||||
* Adds new LoAF entries to the `pendingLoAFs` list.
|
||||
*/
|
||||
const handleLoAFEntries = (entries) => {
|
||||
pendingLoAFs = pendingLoAFs.concat(entries);
|
||||
queueCleanup();
|
||||
};
|
||||
// Get a reference to the interaction target element in case it's removed
|
||||
// from the DOM later.
|
||||
const saveInteractionTarget = (entry) => {
|
||||
if (entry.interactionId &&
|
||||
entry.target &&
|
||||
!interactionTargetMap.has(entry.interactionId)) {
|
||||
interactionTargetMap.set(entry.interactionId, entry.target);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Groups entries that were presented within the same animation frame by
|
||||
* a common `renderTime`. This function works by referencing
|
||||
* `pendingEntriesGroups` and using an existing render time if one is found
|
||||
* (otherwise creating a new one). This function also adds all interaction
|
||||
* entries to an `entryToRenderTimeMap` WeakMap so that the "grouped" entries
|
||||
* can be looked up later.
|
||||
*/
|
||||
const groupEntriesByRenderTime = (entry) => {
|
||||
const renderTime = entry.startTime + entry.duration;
|
||||
let group;
|
||||
latestProcessingEnd = Math.max(latestProcessingEnd, entry.processingEnd);
|
||||
// Iterate over all previous render times in reverse order to find a match.
|
||||
// Go in reverse since the most likely match will be at the end.
|
||||
for (let i = pendingEntriesGroups.length - 1; i >= 0; i--) {
|
||||
const potentialGroup = pendingEntriesGroups[i];
|
||||
// If a group's render time is within 8ms of the entry's render time,
|
||||
// assume they were part of the same frame and add it to the group.
|
||||
if (Math.abs(renderTime - potentialGroup.renderTime) <= 8) {
|
||||
group = potentialGroup;
|
||||
group.startTime = Math.min(entry.startTime, group.startTime);
|
||||
group.processingStart = Math.min(entry.processingStart, group.processingStart);
|
||||
group.processingEnd = Math.max(entry.processingEnd, group.processingEnd);
|
||||
group.entries.push(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If there was no matching group, assume this is a new frame.
|
||||
if (!group) {
|
||||
group = {
|
||||
startTime: entry.startTime,
|
||||
processingStart: entry.processingStart,
|
||||
processingEnd: entry.processingEnd,
|
||||
renderTime,
|
||||
entries: [entry],
|
||||
};
|
||||
pendingEntriesGroups.push(group);
|
||||
}
|
||||
// Store the grouped render time for this entry for reference later.
|
||||
if (entry.interactionId || entry.entryType === 'first-input') {
|
||||
entryToEntriesGroupMap.set(entry, group);
|
||||
}
|
||||
queueCleanup();
|
||||
};
|
||||
const queueCleanup = () => {
|
||||
// Queue cleanup of entries that are not part of any INP candidates.
|
||||
if (idleHandle < 0) {
|
||||
idleHandle = whenIdle(cleanupEntries);
|
||||
}
|
||||
};
|
||||
const cleanupEntries = () => {
|
||||
// Delete any stored interaction target elements if they're not part of one
|
||||
// of the 10 longest interactions.
|
||||
if (interactionTargetMap.size > 10) {
|
||||
interactionTargetMap.forEach((_, key) => {
|
||||
if (!longestInteractionMap.has(key)) {
|
||||
interactionTargetMap.delete(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Keep all render times that are part of a pending INP candidate or
|
||||
// that occurred within the 50 most recently-dispatched groups of events.
|
||||
const longestInteractionGroups = longestInteractionList.map((i) => {
|
||||
return entryToEntriesGroupMap.get(i.entries[0]);
|
||||
});
|
||||
const minIndex = pendingEntriesGroups.length - MAX_PREVIOUS_FRAMES;
|
||||
pendingEntriesGroups = pendingEntriesGroups.filter((group, index) => {
|
||||
if (index >= minIndex)
|
||||
return true;
|
||||
return longestInteractionGroups.includes(group);
|
||||
});
|
||||
// Keep all pending LoAF entries that either:
|
||||
// 1) intersect with entries in the newly cleaned up `pendingEntriesGroups`
|
||||
// 2) occur after the most recently-processed event entry (for up to MAX_PREVIOUS_FRAMES)
|
||||
const loafsToKeep = new Set();
|
||||
for (let i = 0; i < pendingEntriesGroups.length; i++) {
|
||||
const group = pendingEntriesGroups[i];
|
||||
getIntersectingLoAFs(group.startTime, group.processingEnd).forEach((loaf) => {
|
||||
loafsToKeep.add(loaf);
|
||||
});
|
||||
}
|
||||
const prevFrameIndexCutoff = pendingLoAFs.length - 1 - MAX_PREVIOUS_FRAMES;
|
||||
// Filter `pendingLoAFs` to preserve LoAF order.
|
||||
pendingLoAFs = pendingLoAFs.filter((loaf, index) => {
|
||||
if (loaf.startTime > latestProcessingEnd && index > prevFrameIndexCutoff) {
|
||||
return true;
|
||||
}
|
||||
return loafsToKeep.has(loaf);
|
||||
});
|
||||
// Reset the idle callback handle so it can be queued again.
|
||||
idleHandle = -1;
|
||||
};
|
||||
entryPreProcessingCallbacks.push(saveInteractionTarget, groupEntriesByRenderTime);
|
||||
const getIntersectingLoAFs = (start, end) => {
|
||||
const intersectingLoAFs = [];
|
||||
for (let i = 0, loaf; (loaf = pendingLoAFs[i]); i++) {
|
||||
// If the LoAF ends before the given start time, ignore it.
|
||||
if (loaf.startTime + loaf.duration < start)
|
||||
continue;
|
||||
// If the LoAF starts after the given end time, ignore it and all
|
||||
// subsequent pending LoAFs (because they're in time order).
|
||||
if (loaf.startTime > end)
|
||||
break;
|
||||
// Still here? If so this LoAF intersects with the interaction.
|
||||
intersectingLoAFs.push(loaf);
|
||||
}
|
||||
return intersectingLoAFs;
|
||||
};
|
||||
const attributeINP = (metric) => {
|
||||
const firstEntry = metric.entries[0];
|
||||
const group = entryToEntriesGroupMap.get(firstEntry);
|
||||
const processingStart = firstEntry.processingStart;
|
||||
const processingEnd = group.processingEnd;
|
||||
// Sort the entries in processing time order.
|
||||
const processedEventEntries = group.entries.sort((a, b) => {
|
||||
return a.processingStart - b.processingStart;
|
||||
});
|
||||
const longAnimationFrameEntries = getIntersectingLoAFs(firstEntry.startTime, processingEnd);
|
||||
// The first interaction entry may not have a target defined, so use the
|
||||
// first one found in the entry list.
|
||||
// TODO: when the following bug is fixed just use `firstInteractionEntry`.
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=1367329
|
||||
// As a fallback, also check the interactionTargetMap (to account for
|
||||
// cases where the element is removed from the DOM before reporting happens).
|
||||
const firstEntryWithTarget = metric.entries.find((entry) => entry.target);
|
||||
const interactionTargetElement = (firstEntryWithTarget && firstEntryWithTarget.target) ||
|
||||
interactionTargetMap.get(firstEntry.interactionId);
|
||||
// Since entry durations are rounded to the nearest 8ms, we need to clamp
|
||||
// the `nextPaintTime` value to be higher than the `processingEnd` or
|
||||
// end time of any LoAF entry.
|
||||
const nextPaintTimeCandidates = [
|
||||
firstEntry.startTime + firstEntry.duration,
|
||||
processingEnd,
|
||||
].concat(longAnimationFrameEntries.map((loaf) => loaf.startTime + loaf.duration));
|
||||
const nextPaintTime = Math.max.apply(Math, nextPaintTimeCandidates);
|
||||
const attribution = {
|
||||
interactionTarget: getSelector(interactionTargetElement),
|
||||
interactionTargetElement: interactionTargetElement,
|
||||
interactionType: firstEntry.name.startsWith('key') ? 'keyboard' : 'pointer',
|
||||
interactionTime: firstEntry.startTime,
|
||||
nextPaintTime: nextPaintTime,
|
||||
processedEventEntries: processedEventEntries,
|
||||
longAnimationFrameEntries: longAnimationFrameEntries,
|
||||
inputDelay: processingStart - firstEntry.startTime,
|
||||
processingDuration: processingEnd - processingStart,
|
||||
presentationDelay: Math.max(nextPaintTime - processingEnd, 0),
|
||||
loadState: getLoadState(firstEntry.startTime),
|
||||
};
|
||||
// Use Object.assign to set property to keep tsc happy.
|
||||
const metricWithAttribution = Object.assign(metric, { attribution });
|
||||
return metricWithAttribution;
|
||||
};
|
||||
/**
|
||||
* Calculates the [INP](https://web.dev/articles/inp) value for the current
|
||||
* page and calls the `callback` function once the value is ready, along with
|
||||
* the `event` performance entries reported for that interaction. The reported
|
||||
* value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* A custom `durationThreshold` configuration option can optionally be passed to
|
||||
* control what `event-timing` entries are considered for INP reporting. The
|
||||
* default threshold is `40`, which means INP scores of less than 40 are
|
||||
* reported as 0. Note that this will not affect your 75th percentile INP value
|
||||
* unless that value is also less than 40 (well below the recommended
|
||||
* [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called as soon as the value is initially
|
||||
* determined as well as any time the value changes throughout the page
|
||||
* lifespan.
|
||||
*
|
||||
* _**Important:** INP should be continually monitored for changes throughout
|
||||
* the entire lifespan of a page—including if the user returns to the page after
|
||||
* it's been hidden/backgrounded. However, since browsers often [will not fire
|
||||
* additional callbacks once the user has backgrounded a
|
||||
* page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
|
||||
* `callback` is always called when the page's visibility state changes to
|
||||
* hidden. As a result, the `callback` function might be called multiple times
|
||||
* during the same page load._
|
||||
*/
|
||||
export const onINP = (onReport, opts) => {
|
||||
if (!loafObserver) {
|
||||
loafObserver = observe('long-animation-frame', handleLoAFEntries);
|
||||
}
|
||||
unattributedOnINP((metric) => {
|
||||
const metricWithAttribution = attributeINP(metric);
|
||||
onReport(metricWithAttribution);
|
||||
}, opts);
|
||||
};
|
13
24_12_09/node_modules/web-vitals/dist/modules/attribution/onLCP.d.ts
generated
vendored
Normal file
13
24_12_09/node_modules/web-vitals/dist/modules/attribution/onLCP.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { LCPMetricWithAttribution, ReportOpts } from '../types.js';
|
||||
/**
|
||||
* Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and
|
||||
* calls the `callback` function once the value is ready (along with the
|
||||
* relevant `largest-contentful-paint` performance entry used to determine the
|
||||
* value). The reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called any time a new `largest-contentful-paint`
|
||||
* performance entry is dispatched, or once the final value of the metric has
|
||||
* been determined.
|
||||
*/
|
||||
export declare const onLCP: (onReport: (metric: LCPMetricWithAttribution) => void, opts?: ReportOpts) => void;
|
83
24_12_09/node_modules/web-vitals/dist/modules/attribution/onLCP.js
generated
vendored
Normal file
83
24_12_09/node_modules/web-vitals/dist/modules/attribution/onLCP.js
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { getNavigationEntry } from '../lib/getNavigationEntry.js';
|
||||
import { getSelector } from '../lib/getSelector.js';
|
||||
import { onLCP as unattributedOnLCP } from '../onLCP.js';
|
||||
const attributeLCP = (metric) => {
|
||||
// Use a default object if no other attribution has been set.
|
||||
let attribution = {
|
||||
timeToFirstByte: 0,
|
||||
resourceLoadDelay: 0,
|
||||
resourceLoadDuration: 0,
|
||||
elementRenderDelay: metric.value,
|
||||
};
|
||||
if (metric.entries.length) {
|
||||
const navigationEntry = getNavigationEntry();
|
||||
if (navigationEntry) {
|
||||
const activationStart = navigationEntry.activationStart || 0;
|
||||
const lcpEntry = metric.entries[metric.entries.length - 1];
|
||||
const lcpResourceEntry = lcpEntry.url &&
|
||||
performance
|
||||
.getEntriesByType('resource')
|
||||
.filter((e) => e.name === lcpEntry.url)[0];
|
||||
const ttfb = Math.max(0, navigationEntry.responseStart - activationStart);
|
||||
const lcpRequestStart = Math.max(ttfb,
|
||||
// Prefer `requestStart` (if TOA is set), otherwise use `startTime`.
|
||||
lcpResourceEntry
|
||||
? (lcpResourceEntry.requestStart || lcpResourceEntry.startTime) -
|
||||
activationStart
|
||||
: 0);
|
||||
const lcpResponseEnd = Math.max(lcpRequestStart, lcpResourceEntry ? lcpResourceEntry.responseEnd - activationStart : 0);
|
||||
const lcpRenderTime = Math.max(lcpResponseEnd, lcpEntry.startTime - activationStart);
|
||||
attribution = {
|
||||
element: getSelector(lcpEntry.element),
|
||||
timeToFirstByte: ttfb,
|
||||
resourceLoadDelay: lcpRequestStart - ttfb,
|
||||
resourceLoadDuration: lcpResponseEnd - lcpRequestStart,
|
||||
elementRenderDelay: lcpRenderTime - lcpResponseEnd,
|
||||
navigationEntry,
|
||||
lcpEntry,
|
||||
};
|
||||
// Only attribution the URL and resource entry if they exist.
|
||||
if (lcpEntry.url) {
|
||||
attribution.url = lcpEntry.url;
|
||||
}
|
||||
if (lcpResourceEntry) {
|
||||
attribution.lcpResourceEntry = lcpResourceEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use Object.assign to set property to keep tsc happy.
|
||||
const metricWithAttribution = Object.assign(metric, { attribution });
|
||||
return metricWithAttribution;
|
||||
};
|
||||
/**
|
||||
* Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and
|
||||
* calls the `callback` function once the value is ready (along with the
|
||||
* relevant `largest-contentful-paint` performance entry used to determine the
|
||||
* value). The reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called any time a new `largest-contentful-paint`
|
||||
* performance entry is dispatched, or once the final value of the metric has
|
||||
* been determined.
|
||||
*/
|
||||
export const onLCP = (onReport, opts) => {
|
||||
unattributedOnLCP((metric) => {
|
||||
const metricWithAttribution = attributeLCP(metric);
|
||||
onReport(metricWithAttribution);
|
||||
}, opts);
|
||||
};
|
17
24_12_09/node_modules/web-vitals/dist/modules/attribution/onTTFB.d.ts
generated
vendored
Normal file
17
24_12_09/node_modules/web-vitals/dist/modules/attribution/onTTFB.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { TTFBMetricWithAttribution, ReportOpts } from '../types.js';
|
||||
/**
|
||||
* Calculates the [TTFB](https://web.dev/articles/ttfb) value for the
|
||||
* current page and calls the `callback` function once the page has loaded,
|
||||
* along with the relevant `navigation` performance entry used to determine the
|
||||
* value. The reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* Note, this function waits until after the page is loaded to call `callback`
|
||||
* in order to ensure all properties of the `navigation` entry are populated.
|
||||
* This is useful if you want to report on other metrics exposed by the
|
||||
* [Navigation Timing API](https://w3c.github.io/navigation-timing/). For
|
||||
* example, the TTFB metric starts from the page's [time
|
||||
* origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it
|
||||
* includes time spent on DNS lookup, connection negotiation, network latency,
|
||||
* and server processing time.
|
||||
*/
|
||||
export declare const onTTFB: (onReport: (metric: TTFBMetricWithAttribution) => void, opts?: ReportOpts) => void;
|
76
24_12_09/node_modules/web-vitals/dist/modules/attribution/onTTFB.js
generated
vendored
Normal file
76
24_12_09/node_modules/web-vitals/dist/modules/attribution/onTTFB.js
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { onTTFB as unattributedOnTTFB } from '../onTTFB.js';
|
||||
const attributeTTFB = (metric) => {
|
||||
// Use a default object if no other attribution has been set.
|
||||
let attribution = {
|
||||
waitingDuration: 0,
|
||||
cacheDuration: 0,
|
||||
dnsDuration: 0,
|
||||
connectionDuration: 0,
|
||||
requestDuration: 0,
|
||||
};
|
||||
if (metric.entries.length) {
|
||||
const navigationEntry = metric.entries[0];
|
||||
const activationStart = navigationEntry.activationStart || 0;
|
||||
// Measure from workerStart or fetchStart so any service worker startup
|
||||
// time is included in cacheDuration (which also includes other sw time
|
||||
// anyway, that cannot be accurately split out cross-browser).
|
||||
const waitEnd = Math.max((navigationEntry.workerStart || navigationEntry.fetchStart) -
|
||||
activationStart, 0);
|
||||
const dnsStart = Math.max(navigationEntry.domainLookupStart - activationStart, 0);
|
||||
const connectStart = Math.max(navigationEntry.connectStart - activationStart, 0);
|
||||
const connectEnd = Math.max(navigationEntry.connectEnd - activationStart, 0);
|
||||
attribution = {
|
||||
waitingDuration: waitEnd,
|
||||
cacheDuration: dnsStart - waitEnd,
|
||||
// dnsEnd usually equals connectStart but use connectStart over dnsEnd
|
||||
// for dnsDuration in case there ever is a gap.
|
||||
dnsDuration: connectStart - dnsStart,
|
||||
connectionDuration: connectEnd - connectStart,
|
||||
// There is often a gap between connectEnd and requestStart. Attribute
|
||||
// that to requestDuration so connectionDuration remains 0 for
|
||||
// service worker controlled requests were connectStart and connectEnd
|
||||
// are the same.
|
||||
requestDuration: metric.value - connectEnd,
|
||||
navigationEntry: navigationEntry,
|
||||
};
|
||||
}
|
||||
// Use Object.assign to set property to keep tsc happy.
|
||||
const metricWithAttribution = Object.assign(metric, { attribution });
|
||||
return metricWithAttribution;
|
||||
};
|
||||
/**
|
||||
* Calculates the [TTFB](https://web.dev/articles/ttfb) value for the
|
||||
* current page and calls the `callback` function once the page has loaded,
|
||||
* along with the relevant `navigation` performance entry used to determine the
|
||||
* value. The reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* Note, this function waits until after the page is loaded to call `callback`
|
||||
* in order to ensure all properties of the `navigation` entry are populated.
|
||||
* This is useful if you want to report on other metrics exposed by the
|
||||
* [Navigation Timing API](https://w3c.github.io/navigation-timing/). For
|
||||
* example, the TTFB metric starts from the page's [time
|
||||
* origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it
|
||||
* includes time spent on DNS lookup, connection negotiation, network latency,
|
||||
* and server processing time.
|
||||
*/
|
||||
export const onTTFB = (onReport, opts) => {
|
||||
unattributedOnTTFB((metric) => {
|
||||
const metricWithAttribution = attributeTTFB(metric);
|
||||
onReport(metricWithAttribution);
|
||||
}, opts);
|
||||
};
|
5
24_12_09/node_modules/web-vitals/dist/modules/deprecated.d.ts
generated
vendored
Normal file
5
24_12_09/node_modules/web-vitals/dist/modules/deprecated.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
export {
|
||||
/**
|
||||
* @deprecated Use `onINP()` instead.
|
||||
*/
|
||||
onFID, FIDThresholds, } from './onFID.js';
|
20
24_12_09/node_modules/web-vitals/dist/modules/deprecated.js
generated
vendored
Normal file
20
24_12_09/node_modules/web-vitals/dist/modules/deprecated.js
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export {
|
||||
/**
|
||||
* @deprecated Use `onINP()` instead.
|
||||
*/
|
||||
onFID, FIDThresholds, } from './onFID.js';
|
7
24_12_09/node_modules/web-vitals/dist/modules/index.d.ts
generated
vendored
Normal file
7
24_12_09/node_modules/web-vitals/dist/modules/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
export { onCLS, CLSThresholds } from './onCLS.js';
|
||||
export { onFCP, FCPThresholds } from './onFCP.js';
|
||||
export { onINP, INPThresholds } from './onINP.js';
|
||||
export { onLCP, LCPThresholds } from './onLCP.js';
|
||||
export { onTTFB, TTFBThresholds } from './onTTFB.js';
|
||||
export * from './deprecated.js';
|
||||
export * from './types.js';
|
22
24_12_09/node_modules/web-vitals/dist/modules/index.js
generated
vendored
Normal file
22
24_12_09/node_modules/web-vitals/dist/modules/index.js
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { onCLS, CLSThresholds } from './onCLS.js';
|
||||
export { onFCP, FCPThresholds } from './onFCP.js';
|
||||
export { onINP, INPThresholds } from './onINP.js';
|
||||
export { onLCP, LCPThresholds } from './onLCP.js';
|
||||
export { onTTFB, TTFBThresholds } from './onTTFB.js';
|
||||
export * from './deprecated.js';
|
||||
export * from './types.js';
|
6
24_12_09/node_modules/web-vitals/dist/modules/lib/bfcache.d.ts
generated
vendored
Normal file
6
24_12_09/node_modules/web-vitals/dist/modules/lib/bfcache.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
interface onBFCacheRestoreCallback {
|
||||
(event: PageTransitionEvent): void;
|
||||
}
|
||||
export declare const getBFCacheRestoreTime: () => number;
|
||||
export declare const onBFCacheRestore: (cb: onBFCacheRestoreCallback) => void;
|
||||
export {};
|
25
24_12_09/node_modules/web-vitals/dist/modules/lib/bfcache.js
generated
vendored
Normal file
25
24_12_09/node_modules/web-vitals/dist/modules/lib/bfcache.js
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
let bfcacheRestoreTime = -1;
|
||||
export const getBFCacheRestoreTime = () => bfcacheRestoreTime;
|
||||
export const onBFCacheRestore = (cb) => {
|
||||
addEventListener('pageshow', (event) => {
|
||||
if (event.persisted) {
|
||||
bfcacheRestoreTime = event.timeStamp;
|
||||
cb(event);
|
||||
}
|
||||
}, true);
|
||||
};
|
26
24_12_09/node_modules/web-vitals/dist/modules/lib/bindReporter.d.ts
generated
vendored
Normal file
26
24_12_09/node_modules/web-vitals/dist/modules/lib/bindReporter.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { MetricType, MetricRatingThresholds } from '../types.js';
|
||||
export declare const bindReporter: <MetricName extends "CLS" | "FCP" | "FID" | "INP" | "LCP" | "TTFB">(callback: (metric: Extract<import("../types.js").CLSMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").FCPMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").FIDMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").INPMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").LCPMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").TTFBMetric, {
|
||||
name: MetricName;
|
||||
}>) => void, metric: Extract<import("../types.js").CLSMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").FCPMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").FIDMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").INPMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").LCPMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").TTFBMetric, {
|
||||
name: MetricName;
|
||||
}>, thresholds: MetricRatingThresholds, reportAllChanges?: boolean) => (forceReport?: boolean) => void;
|
45
24_12_09/node_modules/web-vitals/dist/modules/lib/bindReporter.js
generated
vendored
Normal file
45
24_12_09/node_modules/web-vitals/dist/modules/lib/bindReporter.js
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const getRating = (value, thresholds) => {
|
||||
if (value > thresholds[1]) {
|
||||
return 'poor';
|
||||
}
|
||||
if (value > thresholds[0]) {
|
||||
return 'needs-improvement';
|
||||
}
|
||||
return 'good';
|
||||
};
|
||||
export const bindReporter = (callback, metric, thresholds, reportAllChanges) => {
|
||||
let prevValue;
|
||||
let delta;
|
||||
return (forceReport) => {
|
||||
if (metric.value >= 0) {
|
||||
if (forceReport || reportAllChanges) {
|
||||
delta = metric.value - (prevValue || 0);
|
||||
// Report the metric if there's a non-zero delta or if no previous
|
||||
// value exists (which can happen in the case of the document becoming
|
||||
// hidden when the metric value is 0).
|
||||
// See: https://github.com/GoogleChrome/web-vitals/issues/14
|
||||
if (delta || prevValue === undefined) {
|
||||
prevValue = metric.value;
|
||||
metric.delta = delta;
|
||||
metric.rating = getRating(metric.value, thresholds);
|
||||
callback(metric);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
1
24_12_09/node_modules/web-vitals/dist/modules/lib/doubleRAF.d.ts
generated
vendored
Normal file
1
24_12_09/node_modules/web-vitals/dist/modules/lib/doubleRAF.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export declare const doubleRAF: (cb: () => unknown) => void;
|
18
24_12_09/node_modules/web-vitals/dist/modules/lib/doubleRAF.js
generated
vendored
Normal file
18
24_12_09/node_modules/web-vitals/dist/modules/lib/doubleRAF.js
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export const doubleRAF = (cb) => {
|
||||
requestAnimationFrame(() => requestAnimationFrame(() => cb()));
|
||||
};
|
6
24_12_09/node_modules/web-vitals/dist/modules/lib/generateUniqueID.d.ts
generated
vendored
Normal file
6
24_12_09/node_modules/web-vitals/dist/modules/lib/generateUniqueID.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
/**
|
||||
* Performantly generate a unique, 30-char string by combining a version
|
||||
* number, the current timestamp with a 13-digit number integer.
|
||||
* @return {string}
|
||||
*/
|
||||
export declare const generateUniqueID: () => string;
|
23
24_12_09/node_modules/web-vitals/dist/modules/lib/generateUniqueID.js
generated
vendored
Normal file
23
24_12_09/node_modules/web-vitals/dist/modules/lib/generateUniqueID.js
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Performantly generate a unique, 30-char string by combining a version
|
||||
* number, the current timestamp with a 13-digit number integer.
|
||||
* @return {string}
|
||||
*/
|
||||
export const generateUniqueID = () => {
|
||||
return `v4-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`;
|
||||
};
|
1
24_12_09/node_modules/web-vitals/dist/modules/lib/getActivationStart.d.ts
generated
vendored
Normal file
1
24_12_09/node_modules/web-vitals/dist/modules/lib/getActivationStart.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export declare const getActivationStart: () => number;
|
20
24_12_09/node_modules/web-vitals/dist/modules/lib/getActivationStart.js
generated
vendored
Normal file
20
24_12_09/node_modules/web-vitals/dist/modules/lib/getActivationStart.js
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { getNavigationEntry } from './getNavigationEntry.js';
|
||||
export const getActivationStart = () => {
|
||||
const navEntry = getNavigationEntry();
|
||||
return (navEntry && navEntry.activationStart) || 0;
|
||||
};
|
2
24_12_09/node_modules/web-vitals/dist/modules/lib/getLoadState.d.ts
generated
vendored
Normal file
2
24_12_09/node_modules/web-vitals/dist/modules/lib/getLoadState.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
import { LoadState } from '../types.js';
|
||||
export declare const getLoadState: (timestamp: number) => LoadState;
|
47
24_12_09/node_modules/web-vitals/dist/modules/lib/getLoadState.js
generated
vendored
Normal file
47
24_12_09/node_modules/web-vitals/dist/modules/lib/getLoadState.js
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { getNavigationEntry } from './getNavigationEntry.js';
|
||||
export const getLoadState = (timestamp) => {
|
||||
if (document.readyState === 'loading') {
|
||||
// If the `readyState` is 'loading' there's no need to look at timestamps
|
||||
// since the timestamp has to be the current time or earlier.
|
||||
return 'loading';
|
||||
}
|
||||
else {
|
||||
const navigationEntry = getNavigationEntry();
|
||||
if (navigationEntry) {
|
||||
if (timestamp < navigationEntry.domInteractive) {
|
||||
return 'loading';
|
||||
}
|
||||
else if (navigationEntry.domContentLoadedEventStart === 0 ||
|
||||
timestamp < navigationEntry.domContentLoadedEventStart) {
|
||||
// If the `domContentLoadedEventStart` timestamp has not yet been
|
||||
// set, or if the given timestamp is less than that value.
|
||||
return 'dom-interactive';
|
||||
}
|
||||
else if (navigationEntry.domComplete === 0 ||
|
||||
timestamp < navigationEntry.domComplete) {
|
||||
// If the `domComplete` timestamp has not yet been
|
||||
// set, or if the given timestamp is less than that value.
|
||||
return 'dom-content-loaded';
|
||||
}
|
||||
}
|
||||
}
|
||||
// If any of the above fail, default to loaded. This could really only
|
||||
// happy if the browser doesn't support the performance timeline, which
|
||||
// most likely means this code would never run anyway.
|
||||
return 'complete';
|
||||
};
|
1
24_12_09/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.d.ts
generated
vendored
Normal file
1
24_12_09/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export declare const getNavigationEntry: () => PerformanceNavigationTiming | void;
|
32
24_12_09/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.js
generated
vendored
Normal file
32
24_12_09/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.js
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export const getNavigationEntry = () => {
|
||||
const navigationEntry = self.performance &&
|
||||
performance.getEntriesByType &&
|
||||
performance.getEntriesByType('navigation')[0];
|
||||
// Check to ensure the `responseStart` property is present and valid.
|
||||
// In some cases no value is reported by the browser (for
|
||||
// privacy/security reasons), and in other cases (bugs) the value is
|
||||
// negative or is larger than the current page time. Ignore these cases:
|
||||
// https://github.com/GoogleChrome/web-vitals/issues/137
|
||||
// https://github.com/GoogleChrome/web-vitals/issues/162
|
||||
// https://github.com/GoogleChrome/web-vitals/issues/275
|
||||
if (navigationEntry &&
|
||||
navigationEntry.responseStart > 0 &&
|
||||
navigationEntry.responseStart < performance.now()) {
|
||||
return navigationEntry;
|
||||
}
|
||||
};
|
1
24_12_09/node_modules/web-vitals/dist/modules/lib/getSelector.d.ts
generated
vendored
Normal file
1
24_12_09/node_modules/web-vitals/dist/modules/lib/getSelector.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export declare const getSelector: (node: Node | null | undefined, maxLen?: number) => string;
|
48
24_12_09/node_modules/web-vitals/dist/modules/lib/getSelector.js
generated
vendored
Normal file
48
24_12_09/node_modules/web-vitals/dist/modules/lib/getSelector.js
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const getName = (node) => {
|
||||
const name = node.nodeName;
|
||||
return node.nodeType === 1
|
||||
? name.toLowerCase()
|
||||
: name.toUpperCase().replace(/^#/, '');
|
||||
};
|
||||
export const getSelector = (node, maxLen) => {
|
||||
let sel = '';
|
||||
try {
|
||||
while (node && node.nodeType !== 9) {
|
||||
const el = node;
|
||||
const part = el.id
|
||||
? '#' + el.id
|
||||
: getName(el) +
|
||||
(el.classList &&
|
||||
el.classList.value &&
|
||||
el.classList.value.trim() &&
|
||||
el.classList.value.trim().length
|
||||
? '.' + el.classList.value.trim().replace(/\s+/g, '.')
|
||||
: '');
|
||||
if (sel.length + part.length > (maxLen || 100) - 1)
|
||||
return sel || part;
|
||||
sel = sel ? part + '>' + sel : part;
|
||||
if (el.id)
|
||||
break;
|
||||
node = el.parentNode;
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
// Do nothing...
|
||||
}
|
||||
return sel;
|
||||
};
|
3
24_12_09/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.d.ts
generated
vendored
Normal file
3
24_12_09/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
export declare const getVisibilityWatcher: () => {
|
||||
readonly firstHiddenTime: number;
|
||||
};
|
80
24_12_09/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.js
generated
vendored
Normal file
80
24_12_09/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.js
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { onBFCacheRestore } from './bfcache.js';
|
||||
let firstHiddenTime = -1;
|
||||
const initHiddenTime = () => {
|
||||
// If the document is hidden when this code runs, assume it was always
|
||||
// hidden and the page was loaded in the background, with the one exception
|
||||
// that visibility state is always 'hidden' during prerendering, so we have
|
||||
// to ignore that case until prerendering finishes (see: `prerenderingchange`
|
||||
// event logic below).
|
||||
return document.visibilityState === 'hidden' && !document.prerendering
|
||||
? 0
|
||||
: Infinity;
|
||||
};
|
||||
const onVisibilityUpdate = (event) => {
|
||||
// If the document is 'hidden' and no previous hidden timestamp has been
|
||||
// set, update it based on the current event data.
|
||||
if (document.visibilityState === 'hidden' && firstHiddenTime > -1) {
|
||||
// If the event is a 'visibilitychange' event, it means the page was
|
||||
// visible prior to this change, so the event timestamp is the first
|
||||
// hidden time.
|
||||
// However, if the event is not a 'visibilitychange' event, then it must
|
||||
// be a 'prerenderingchange' event, and the fact that the document is
|
||||
// still 'hidden' from the above check means the tab was activated
|
||||
// in a background state and so has always been hidden.
|
||||
firstHiddenTime = event.type === 'visibilitychange' ? event.timeStamp : 0;
|
||||
// Remove all listeners now that a `firstHiddenTime` value has been set.
|
||||
removeChangeListeners();
|
||||
}
|
||||
};
|
||||
const addChangeListeners = () => {
|
||||
addEventListener('visibilitychange', onVisibilityUpdate, true);
|
||||
// IMPORTANT: when a page is prerendering, its `visibilityState` is
|
||||
// 'hidden', so in order to account for cases where this module checks for
|
||||
// visibility during prerendering, an additional check after prerendering
|
||||
// completes is also required.
|
||||
addEventListener('prerenderingchange', onVisibilityUpdate, true);
|
||||
};
|
||||
const removeChangeListeners = () => {
|
||||
removeEventListener('visibilitychange', onVisibilityUpdate, true);
|
||||
removeEventListener('prerenderingchange', onVisibilityUpdate, true);
|
||||
};
|
||||
export const getVisibilityWatcher = () => {
|
||||
if (firstHiddenTime < 0) {
|
||||
// If the document is hidden when this code runs, assume it was hidden
|
||||
// since navigation start. This isn't a perfect heuristic, but it's the
|
||||
// best we can do until an API is available to support querying past
|
||||
// visibilityState.
|
||||
firstHiddenTime = initHiddenTime();
|
||||
addChangeListeners();
|
||||
// Reset the time on bfcache restores.
|
||||
onBFCacheRestore(() => {
|
||||
// Schedule a task in order to track the `visibilityState` once it's
|
||||
// had an opportunity to change to visible in all browsers.
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=1133363
|
||||
setTimeout(() => {
|
||||
firstHiddenTime = initHiddenTime();
|
||||
addChangeListeners();
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
return {
|
||||
get firstHiddenTime() {
|
||||
return firstHiddenTime;
|
||||
},
|
||||
};
|
||||
};
|
21
24_12_09/node_modules/web-vitals/dist/modules/lib/initMetric.d.ts
generated
vendored
Normal file
21
24_12_09/node_modules/web-vitals/dist/modules/lib/initMetric.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
export declare const initMetric: <MetricName extends "CLS" | "FCP" | "FID" | "INP" | "LCP" | "TTFB">(name: MetricName, value?: number) => {
|
||||
name: MetricName;
|
||||
value: number;
|
||||
rating: "good";
|
||||
delta: number;
|
||||
entries: (Extract<import("../types.js").CLSMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").FCPMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").FIDMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").INPMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").LCPMetric, {
|
||||
name: MetricName;
|
||||
}> | Extract<import("../types.js").TTFBMetric, {
|
||||
name: MetricName;
|
||||
}>)["entries"];
|
||||
id: string;
|
||||
navigationType: "navigate" | "reload" | "back-forward" | "back-forward-cache" | "prerender" | "restore";
|
||||
};
|
48
24_12_09/node_modules/web-vitals/dist/modules/lib/initMetric.js
generated
vendored
Normal file
48
24_12_09/node_modules/web-vitals/dist/modules/lib/initMetric.js
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { getBFCacheRestoreTime } from './bfcache.js';
|
||||
import { generateUniqueID } from './generateUniqueID.js';
|
||||
import { getActivationStart } from './getActivationStart.js';
|
||||
import { getNavigationEntry } from './getNavigationEntry.js';
|
||||
export const initMetric = (name, value) => {
|
||||
const navEntry = getNavigationEntry();
|
||||
let navigationType = 'navigate';
|
||||
if (getBFCacheRestoreTime() >= 0) {
|
||||
navigationType = 'back-forward-cache';
|
||||
}
|
||||
else if (navEntry) {
|
||||
if (document.prerendering || getActivationStart() > 0) {
|
||||
navigationType = 'prerender';
|
||||
}
|
||||
else if (document.wasDiscarded) {
|
||||
navigationType = 'restore';
|
||||
}
|
||||
else if (navEntry.type) {
|
||||
navigationType = navEntry.type.replace(/_/g, '-');
|
||||
}
|
||||
}
|
||||
// Use `entries` type specific for the metric.
|
||||
const entries = [];
|
||||
return {
|
||||
name,
|
||||
value: typeof value === 'undefined' ? -1 : value,
|
||||
rating: 'good', // If needed, will be updated when reported. `const` to keep the type from widening to `string`.
|
||||
delta: 0,
|
||||
entries,
|
||||
id: generateUniqueID(),
|
||||
navigationType,
|
||||
};
|
||||
};
|
31
24_12_09/node_modules/web-vitals/dist/modules/lib/interactions.d.ts
generated
vendored
Normal file
31
24_12_09/node_modules/web-vitals/dist/modules/lib/interactions.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
interface Interaction {
|
||||
id: number;
|
||||
latency: number;
|
||||
entries: PerformanceEventTiming[];
|
||||
}
|
||||
interface EntryPreProcessingHook {
|
||||
(entry: PerformanceEventTiming): void;
|
||||
}
|
||||
export declare const longestInteractionList: Interaction[];
|
||||
export declare const longestInteractionMap: Map<number, Interaction>;
|
||||
export declare const DEFAULT_DURATION_THRESHOLD = 40;
|
||||
export declare const resetInteractions: () => void;
|
||||
/**
|
||||
* Returns the estimated p98 longest interaction based on the stored
|
||||
* interaction candidates and the interaction count for the current page.
|
||||
*/
|
||||
export declare const estimateP98LongestInteraction: () => Interaction;
|
||||
/**
|
||||
* A list of callback functions to run before each entry is processed.
|
||||
* Exposing this list allows the attribution build to hook into the
|
||||
* entry processing pipeline.
|
||||
*/
|
||||
export declare const entryPreProcessingCallbacks: EntryPreProcessingHook[];
|
||||
/**
|
||||
* Takes a performance entry and adds it to the list of worst interactions
|
||||
* if its duration is long enough to make it among the worst. If the
|
||||
* entry is part of an existing interaction, it is merged and the latency
|
||||
* and entries list is updated as needed.
|
||||
*/
|
||||
export declare const processInteractionEntry: (entry: PerformanceEventTiming) => void;
|
||||
export {};
|
107
24_12_09/node_modules/web-vitals/dist/modules/lib/interactions.js
generated
vendored
Normal file
107
24_12_09/node_modules/web-vitals/dist/modules/lib/interactions.js
generated
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { getInteractionCount } from './polyfills/interactionCountPolyfill.js';
|
||||
// A list of longest interactions on the page (by latency) sorted so the
|
||||
// longest one is first. The list is at most MAX_INTERACTIONS_TO_CONSIDER long.
|
||||
export const longestInteractionList = [];
|
||||
// A mapping of longest interactions by their interaction ID.
|
||||
// This is used for faster lookup.
|
||||
export const longestInteractionMap = new Map();
|
||||
// The default `durationThreshold` used across this library for observing
|
||||
// `event` entries via PerformanceObserver.
|
||||
export const DEFAULT_DURATION_THRESHOLD = 40;
|
||||
// Used to store the interaction count after a bfcache restore, since p98
|
||||
// interaction latencies should only consider the current navigation.
|
||||
let prevInteractionCount = 0;
|
||||
/**
|
||||
* Returns the interaction count since the last bfcache restore (or for the
|
||||
* full page lifecycle if there were no bfcache restores).
|
||||
*/
|
||||
const getInteractionCountForNavigation = () => {
|
||||
return getInteractionCount() - prevInteractionCount;
|
||||
};
|
||||
export const resetInteractions = () => {
|
||||
prevInteractionCount = getInteractionCount();
|
||||
longestInteractionList.length = 0;
|
||||
longestInteractionMap.clear();
|
||||
};
|
||||
/**
|
||||
* Returns the estimated p98 longest interaction based on the stored
|
||||
* interaction candidates and the interaction count for the current page.
|
||||
*/
|
||||
export const estimateP98LongestInteraction = () => {
|
||||
const candidateInteractionIndex = Math.min(longestInteractionList.length - 1, Math.floor(getInteractionCountForNavigation() / 50));
|
||||
return longestInteractionList[candidateInteractionIndex];
|
||||
};
|
||||
// To prevent unnecessary memory usage on pages with lots of interactions,
|
||||
// store at most 10 of the longest interactions to consider as INP candidates.
|
||||
const MAX_INTERACTIONS_TO_CONSIDER = 10;
|
||||
/**
|
||||
* A list of callback functions to run before each entry is processed.
|
||||
* Exposing this list allows the attribution build to hook into the
|
||||
* entry processing pipeline.
|
||||
*/
|
||||
export const entryPreProcessingCallbacks = [];
|
||||
/**
|
||||
* Takes a performance entry and adds it to the list of worst interactions
|
||||
* if its duration is long enough to make it among the worst. If the
|
||||
* entry is part of an existing interaction, it is merged and the latency
|
||||
* and entries list is updated as needed.
|
||||
*/
|
||||
export const processInteractionEntry = (entry) => {
|
||||
entryPreProcessingCallbacks.forEach((cb) => cb(entry));
|
||||
// Skip further processing for entries that cannot be INP candidates.
|
||||
if (!(entry.interactionId || entry.entryType === 'first-input'))
|
||||
return;
|
||||
// The least-long of the 10 longest interactions.
|
||||
const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1];
|
||||
const existingInteraction = longestInteractionMap.get(entry.interactionId);
|
||||
// Only process the entry if it's possibly one of the ten longest,
|
||||
// or if it's part of an existing interaction.
|
||||
if (existingInteraction ||
|
||||
longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER ||
|
||||
entry.duration > minLongestInteraction.latency) {
|
||||
// If the interaction already exists, update it. Otherwise create one.
|
||||
if (existingInteraction) {
|
||||
// If the new entry has a longer duration, replace the old entries,
|
||||
// otherwise add to the array.
|
||||
if (entry.duration > existingInteraction.latency) {
|
||||
existingInteraction.entries = [entry];
|
||||
existingInteraction.latency = entry.duration;
|
||||
}
|
||||
else if (entry.duration === existingInteraction.latency &&
|
||||
entry.startTime === existingInteraction.entries[0].startTime) {
|
||||
existingInteraction.entries.push(entry);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const interaction = {
|
||||
id: entry.interactionId,
|
||||
latency: entry.duration,
|
||||
entries: [entry],
|
||||
};
|
||||
longestInteractionMap.set(interaction.id, interaction);
|
||||
longestInteractionList.push(interaction);
|
||||
}
|
||||
// Sort the entries by latency (descending) and keep only the top ten.
|
||||
longestInteractionList.sort((a, b) => b.latency - a.latency);
|
||||
if (longestInteractionList.length > MAX_INTERACTIONS_TO_CONSIDER) {
|
||||
longestInteractionList
|
||||
.splice(MAX_INTERACTIONS_TO_CONSIDER)
|
||||
.forEach((i) => longestInteractionMap.delete(i.id));
|
||||
}
|
||||
}
|
||||
};
|
20
24_12_09/node_modules/web-vitals/dist/modules/lib/observe.d.ts
generated
vendored
Normal file
20
24_12_09/node_modules/web-vitals/dist/modules/lib/observe.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
interface PerformanceEntryMap {
|
||||
'event': PerformanceEventTiming[];
|
||||
'first-input': PerformanceEventTiming[];
|
||||
'layout-shift': LayoutShift[];
|
||||
'largest-contentful-paint': LargestContentfulPaint[];
|
||||
'long-animation-frame': PerformanceLongAnimationFrameTiming[];
|
||||
'paint': PerformancePaintTiming[];
|
||||
'navigation': PerformanceNavigationTiming[];
|
||||
'resource': PerformanceResourceTiming[];
|
||||
}
|
||||
/**
|
||||
* Takes a performance entry type and a callback function, and creates a
|
||||
* `PerformanceObserver` instance that will observe the specified entry type
|
||||
* with buffering enabled and call the callback _for each entry_.
|
||||
*
|
||||
* This function also feature-detects entry support and wraps the logic in a
|
||||
* try/catch to avoid errors in unsupporting browsers.
|
||||
*/
|
||||
export declare const observe: <K extends keyof PerformanceEntryMap>(type: K, callback: (entries: PerformanceEntryMap[K]) => void, opts?: PerformanceObserverInit) => PerformanceObserver | undefined;
|
||||
export {};
|
46
24_12_09/node_modules/web-vitals/dist/modules/lib/observe.js
generated
vendored
Normal file
46
24_12_09/node_modules/web-vitals/dist/modules/lib/observe.js
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Takes a performance entry type and a callback function, and creates a
|
||||
* `PerformanceObserver` instance that will observe the specified entry type
|
||||
* with buffering enabled and call the callback _for each entry_.
|
||||
*
|
||||
* This function also feature-detects entry support and wraps the logic in a
|
||||
* try/catch to avoid errors in unsupporting browsers.
|
||||
*/
|
||||
export const observe = (type, callback, opts) => {
|
||||
try {
|
||||
if (PerformanceObserver.supportedEntryTypes.includes(type)) {
|
||||
const po = new PerformanceObserver((list) => {
|
||||
// Delay by a microtask to workaround a bug in Safari where the
|
||||
// callback is invoked immediately, rather than in a separate task.
|
||||
// See: https://github.com/GoogleChrome/web-vitals/issues/277
|
||||
Promise.resolve().then(() => {
|
||||
callback(list.getEntries());
|
||||
});
|
||||
});
|
||||
po.observe(Object.assign({
|
||||
type,
|
||||
buffered: true,
|
||||
}, opts || {}));
|
||||
return po;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
// Do nothing.
|
||||
}
|
||||
return;
|
||||
};
|
1
24_12_09/node_modules/web-vitals/dist/modules/lib/onHidden.d.ts
generated
vendored
Normal file
1
24_12_09/node_modules/web-vitals/dist/modules/lib/onHidden.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export declare const onHidden: (cb: () => void) => void;
|
22
24_12_09/node_modules/web-vitals/dist/modules/lib/onHidden.js
generated
vendored
Normal file
22
24_12_09/node_modules/web-vitals/dist/modules/lib/onHidden.js
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export const onHidden = (cb) => {
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
};
|
7
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.d.ts
generated
vendored
Normal file
7
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { FirstInputPolyfillCallback } from '../../types.js';
|
||||
/**
|
||||
* Accepts a callback to be invoked once the first input delay and event
|
||||
* are known.
|
||||
*/
|
||||
export declare const firstInputPolyfill: (onFirstInput: FirstInputPolyfillCallback) => void;
|
||||
export declare const resetFirstInputPolyfill: () => void;
|
147
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.js
generated
vendored
Normal file
147
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.js
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
let firstInputEvent;
|
||||
let firstInputDelay;
|
||||
let firstInputTimeStamp;
|
||||
let callbacks;
|
||||
const listenerOpts = { passive: true, capture: true };
|
||||
const startTimeStamp = new Date();
|
||||
/**
|
||||
* Accepts a callback to be invoked once the first input delay and event
|
||||
* are known.
|
||||
*/
|
||||
export const firstInputPolyfill = (onFirstInput) => {
|
||||
callbacks.push(onFirstInput);
|
||||
reportFirstInputDelayIfRecordedAndValid();
|
||||
};
|
||||
export const resetFirstInputPolyfill = () => {
|
||||
callbacks = [];
|
||||
firstInputDelay = -1;
|
||||
firstInputEvent = null;
|
||||
eachEventType(addEventListener);
|
||||
};
|
||||
/**
|
||||
* Records the first input delay and event, so subsequent events can be
|
||||
* ignored. All added event listeners are then removed.
|
||||
*/
|
||||
const recordFirstInputDelay = (delay, event) => {
|
||||
if (!firstInputEvent) {
|
||||
firstInputEvent = event;
|
||||
firstInputDelay = delay;
|
||||
firstInputTimeStamp = new Date();
|
||||
eachEventType(removeEventListener);
|
||||
reportFirstInputDelayIfRecordedAndValid();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Reports the first input delay and event (if they're recorded and valid)
|
||||
* by running the array of callback functions.
|
||||
*/
|
||||
const reportFirstInputDelayIfRecordedAndValid = () => {
|
||||
// In some cases the recorded delay is clearly wrong, e.g. it's negative
|
||||
// or it's larger than the delta between now and initialization.
|
||||
// - https://github.com/GoogleChromeLabs/first-input-delay/issues/4
|
||||
// - https://github.com/GoogleChromeLabs/first-input-delay/issues/6
|
||||
// - https://github.com/GoogleChromeLabs/first-input-delay/issues/7
|
||||
if (firstInputDelay >= 0 &&
|
||||
// @ts-ignore (subtracting two dates always returns a number)
|
||||
firstInputDelay < firstInputTimeStamp - startTimeStamp) {
|
||||
const entry = {
|
||||
entryType: 'first-input',
|
||||
name: firstInputEvent.type,
|
||||
target: firstInputEvent.target,
|
||||
cancelable: firstInputEvent.cancelable,
|
||||
startTime: firstInputEvent.timeStamp,
|
||||
processingStart: firstInputEvent.timeStamp + firstInputDelay,
|
||||
};
|
||||
callbacks.forEach(function (callback) {
|
||||
callback(entry);
|
||||
});
|
||||
callbacks = [];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Handles pointer down events, which are a special case.
|
||||
* Pointer events can trigger main or compositor thread behavior.
|
||||
* We differentiate these cases based on whether or not we see a
|
||||
* 'pointercancel' event, which are fired when we scroll. If we're scrolling
|
||||
* we don't need to report input delay since FID excludes scrolling and
|
||||
* pinch/zooming.
|
||||
*/
|
||||
const onPointerDown = (delay, event) => {
|
||||
/**
|
||||
* Responds to 'pointerup' events and records a delay. If a pointer up event
|
||||
* is the next event after a pointerdown event, then it's not a scroll or
|
||||
* a pinch/zoom.
|
||||
*/
|
||||
const onPointerUp = () => {
|
||||
recordFirstInputDelay(delay, event);
|
||||
removePointerEventListeners();
|
||||
};
|
||||
/**
|
||||
* Responds to 'pointercancel' events and removes pointer listeners.
|
||||
* If a 'pointercancel' is the next event to fire after a pointerdown event,
|
||||
* it means this is a scroll or pinch/zoom interaction.
|
||||
*/
|
||||
const onPointerCancel = () => {
|
||||
removePointerEventListeners();
|
||||
};
|
||||
/**
|
||||
* Removes added pointer event listeners.
|
||||
*/
|
||||
const removePointerEventListeners = () => {
|
||||
removeEventListener('pointerup', onPointerUp, listenerOpts);
|
||||
removeEventListener('pointercancel', onPointerCancel, listenerOpts);
|
||||
};
|
||||
addEventListener('pointerup', onPointerUp, listenerOpts);
|
||||
addEventListener('pointercancel', onPointerCancel, listenerOpts);
|
||||
};
|
||||
/**
|
||||
* Handles all input events and records the time between when the event
|
||||
* was received by the operating system and when it's JavaScript listeners
|
||||
* were able to run.
|
||||
*/
|
||||
const onInput = (event) => {
|
||||
// Only count cancelable events, which should trigger behavior
|
||||
// important to the user.
|
||||
if (event.cancelable) {
|
||||
// In some browsers `event.timeStamp` returns a `DOMTimeStamp` value
|
||||
// (epoch time) instead of the newer `DOMHighResTimeStamp`
|
||||
// (document-origin time). To check for that we assume any timestamp
|
||||
// greater than 1 trillion is a `DOMTimeStamp`, and compare it using
|
||||
// the `Date` object rather than `performance.now()`.
|
||||
// - https://github.com/GoogleChromeLabs/first-input-delay/issues/4
|
||||
const isEpochTime = event.timeStamp > 1e12;
|
||||
const now = isEpochTime ? new Date() : performance.now();
|
||||
// Input delay is the delta between when the system received the event
|
||||
// (e.g. event.timeStamp) and when it could run the callback (e.g. `now`).
|
||||
const delay = now - event.timeStamp;
|
||||
if (event.type == 'pointerdown') {
|
||||
onPointerDown(delay, event);
|
||||
}
|
||||
else {
|
||||
recordFirstInputDelay(delay, event);
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Invokes the passed callback const for = each event type with t =>he
|
||||
* `onInput` const and = `listenerOpts =>`.
|
||||
*/
|
||||
const eachEventType = (callback) => {
|
||||
const eventTypes = ['mousedown', 'keydown', 'touchstart', 'pointerdown'];
|
||||
eventTypes.forEach((type) => callback(type, onInput, listenerOpts));
|
||||
};
|
1
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.d.ts
generated
vendored
Normal file
1
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export declare const getFirstHiddenTime: () => number;
|
25
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.js
generated
vendored
Normal file
25
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.js
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
let firstHiddenTime = document.visibilityState === 'hidden' ? 0 : Infinity;
|
||||
const onVisibilityChange = (event) => {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
firstHiddenTime = event.timeStamp;
|
||||
removeEventListener('visibilitychange', onVisibilityChange, true);
|
||||
}
|
||||
};
|
||||
// Note: do not add event listeners unconditionally (outside of polyfills).
|
||||
addEventListener('visibilitychange', onVisibilityChange, true);
|
||||
export const getFirstHiddenTime = () => firstHiddenTime;
|
14
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.d.ts
generated
vendored
Normal file
14
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
declare global {
|
||||
interface Performance {
|
||||
interactionCount: number;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the `interactionCount` value using the native API (if available)
|
||||
* or the polyfill estimate in this module.
|
||||
*/
|
||||
export declare const getInteractionCount: () => number;
|
||||
/**
|
||||
* Feature detects native support or initializes the polyfill if needed.
|
||||
*/
|
||||
export declare const initInteractionCountPolyfill: () => void;
|
50
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.js
generated
vendored
Normal file
50
24_12_09/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.js
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { observe } from '../observe.js';
|
||||
let interactionCountEstimate = 0;
|
||||
let minKnownInteractionId = Infinity;
|
||||
let maxKnownInteractionId = 0;
|
||||
const updateEstimate = (entries) => {
|
||||
entries.forEach((e) => {
|
||||
if (e.interactionId) {
|
||||
minKnownInteractionId = Math.min(minKnownInteractionId, e.interactionId);
|
||||
maxKnownInteractionId = Math.max(maxKnownInteractionId, e.interactionId);
|
||||
interactionCountEstimate = maxKnownInteractionId
|
||||
? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1
|
||||
: 0;
|
||||
}
|
||||
});
|
||||
};
|
||||
let po;
|
||||
/**
|
||||
* Returns the `interactionCount` value using the native API (if available)
|
||||
* or the polyfill estimate in this module.
|
||||
*/
|
||||
export const getInteractionCount = () => {
|
||||
return po ? interactionCountEstimate : performance.interactionCount || 0;
|
||||
};
|
||||
/**
|
||||
* Feature detects native support or initializes the polyfill if needed.
|
||||
*/
|
||||
export const initInteractionCountPolyfill = () => {
|
||||
if ('interactionCount' in performance || po)
|
||||
return;
|
||||
po = observe('event', updateEstimate, {
|
||||
type: 'event',
|
||||
buffered: true,
|
||||
durationThreshold: 0,
|
||||
});
|
||||
};
|
1
24_12_09/node_modules/web-vitals/dist/modules/lib/runOnce.d.ts
generated
vendored
Normal file
1
24_12_09/node_modules/web-vitals/dist/modules/lib/runOnce.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export declare const runOnce: (cb: () => void) => () => void;
|
24
24_12_09/node_modules/web-vitals/dist/modules/lib/runOnce.js
generated
vendored
Normal file
24
24_12_09/node_modules/web-vitals/dist/modules/lib/runOnce.js
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export const runOnce = (cb) => {
|
||||
let called = false;
|
||||
return () => {
|
||||
if (!called) {
|
||||
cb();
|
||||
called = true;
|
||||
}
|
||||
};
|
||||
};
|
1
24_12_09/node_modules/web-vitals/dist/modules/lib/whenActivated.d.ts
generated
vendored
Normal file
1
24_12_09/node_modules/web-vitals/dist/modules/lib/whenActivated.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export declare const whenActivated: (callback: () => void) => void;
|
23
24_12_09/node_modules/web-vitals/dist/modules/lib/whenActivated.js
generated
vendored
Normal file
23
24_12_09/node_modules/web-vitals/dist/modules/lib/whenActivated.js
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export const whenActivated = (callback) => {
|
||||
if (document.prerendering) {
|
||||
addEventListener('prerenderingchange', () => callback(), true);
|
||||
}
|
||||
else {
|
||||
callback();
|
||||
}
|
||||
};
|
5
24_12_09/node_modules/web-vitals/dist/modules/lib/whenIdle.d.ts
generated
vendored
Normal file
5
24_12_09/node_modules/web-vitals/dist/modules/lib/whenIdle.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
/**
|
||||
* Runs the passed callback during the next idle period, or immediately
|
||||
* if the browser's visibility state is (or becomes) hidden.
|
||||
*/
|
||||
export declare const whenIdle: (cb: () => void) => number;
|
36
24_12_09/node_modules/web-vitals/dist/modules/lib/whenIdle.js
generated
vendored
Normal file
36
24_12_09/node_modules/web-vitals/dist/modules/lib/whenIdle.js
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { onHidden } from './onHidden.js';
|
||||
import { runOnce } from './runOnce.js';
|
||||
/**
|
||||
* Runs the passed callback during the next idle period, or immediately
|
||||
* if the browser's visibility state is (or becomes) hidden.
|
||||
*/
|
||||
export const whenIdle = (cb) => {
|
||||
const rIC = self.requestIdleCallback || self.setTimeout;
|
||||
let handle = -1;
|
||||
cb = runOnce(cb);
|
||||
// If the document is hidden, run the callback immediately, otherwise
|
||||
// race an idle callback with the next `visibilitychange` event.
|
||||
if (document.visibilityState === 'hidden') {
|
||||
cb();
|
||||
}
|
||||
else {
|
||||
handle = rIC(cb);
|
||||
onHidden(cb);
|
||||
}
|
||||
return handle;
|
||||
};
|
25
24_12_09/node_modules/web-vitals/dist/modules/onCLS.d.ts
generated
vendored
Normal file
25
24_12_09/node_modules/web-vitals/dist/modules/onCLS.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { CLSMetric, MetricRatingThresholds, ReportOpts } from './types.js';
|
||||
/** Thresholds for CLS. See https://web.dev/articles/cls#what_is_a_good_cls_score */
|
||||
export declare const CLSThresholds: MetricRatingThresholds;
|
||||
/**
|
||||
* Calculates the [CLS](https://web.dev/articles/cls) value for the current page and
|
||||
* calls the `callback` function once the value is ready to be reported, along
|
||||
* with all `layout-shift` performance entries that were used in the metric
|
||||
* value calculation. The reported value is a `double` (corresponding to a
|
||||
* [layout shift score](https://web.dev/articles/cls#layout_shift_score)).
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called as soon as the value is initially
|
||||
* determined as well as any time the value changes throughout the page
|
||||
* lifespan.
|
||||
*
|
||||
* _**Important:** CLS should be continually monitored for changes throughout
|
||||
* the entire lifespan of a page—including if the user returns to the page after
|
||||
* it's been hidden/backgrounded. However, since browsers often [will not fire
|
||||
* additional callbacks once the user has backgrounded a
|
||||
* page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
|
||||
* `callback` is always called when the page's visibility state changes to
|
||||
* hidden. As a result, the `callback` function might be called multiple times
|
||||
* during the same page load._
|
||||
*/
|
||||
export declare const onCLS: (onReport: (metric: CLSMetric) => void, opts?: ReportOpts) => void;
|
108
24_12_09/node_modules/web-vitals/dist/modules/onCLS.js
generated
vendored
Normal file
108
24_12_09/node_modules/web-vitals/dist/modules/onCLS.js
generated
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { onBFCacheRestore } from './lib/bfcache.js';
|
||||
import { initMetric } from './lib/initMetric.js';
|
||||
import { observe } from './lib/observe.js';
|
||||
import { bindReporter } from './lib/bindReporter.js';
|
||||
import { doubleRAF } from './lib/doubleRAF.js';
|
||||
import { onHidden } from './lib/onHidden.js';
|
||||
import { runOnce } from './lib/runOnce.js';
|
||||
import { onFCP } from './onFCP.js';
|
||||
/** Thresholds for CLS. See https://web.dev/articles/cls#what_is_a_good_cls_score */
|
||||
export const CLSThresholds = [0.1, 0.25];
|
||||
/**
|
||||
* Calculates the [CLS](https://web.dev/articles/cls) value for the current page and
|
||||
* calls the `callback` function once the value is ready to be reported, along
|
||||
* with all `layout-shift` performance entries that were used in the metric
|
||||
* value calculation. The reported value is a `double` (corresponding to a
|
||||
* [layout shift score](https://web.dev/articles/cls#layout_shift_score)).
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called as soon as the value is initially
|
||||
* determined as well as any time the value changes throughout the page
|
||||
* lifespan.
|
||||
*
|
||||
* _**Important:** CLS should be continually monitored for changes throughout
|
||||
* the entire lifespan of a page—including if the user returns to the page after
|
||||
* it's been hidden/backgrounded. However, since browsers often [will not fire
|
||||
* additional callbacks once the user has backgrounded a
|
||||
* page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
|
||||
* `callback` is always called when the page's visibility state changes to
|
||||
* hidden. As a result, the `callback` function might be called multiple times
|
||||
* during the same page load._
|
||||
*/
|
||||
export const onCLS = (onReport, opts) => {
|
||||
// Set defaults
|
||||
opts = opts || {};
|
||||
// Start monitoring FCP so we can only report CLS if FCP is also reported.
|
||||
// Note: this is done to match the current behavior of CrUX.
|
||||
onFCP(runOnce(() => {
|
||||
let metric = initMetric('CLS', 0);
|
||||
let report;
|
||||
let sessionValue = 0;
|
||||
let sessionEntries = [];
|
||||
const handleEntries = (entries) => {
|
||||
entries.forEach((entry) => {
|
||||
// Only count layout shifts without recent user input.
|
||||
if (!entry.hadRecentInput) {
|
||||
const firstSessionEntry = sessionEntries[0];
|
||||
const lastSessionEntry = sessionEntries[sessionEntries.length - 1];
|
||||
// If the entry occurred less than 1 second after the previous entry
|
||||
// and less than 5 seconds after the first entry in the session,
|
||||
// include the entry in the current session. Otherwise, start a new
|
||||
// session.
|
||||
if (sessionValue &&
|
||||
entry.startTime - lastSessionEntry.startTime < 1000 &&
|
||||
entry.startTime - firstSessionEntry.startTime < 5000) {
|
||||
sessionValue += entry.value;
|
||||
sessionEntries.push(entry);
|
||||
}
|
||||
else {
|
||||
sessionValue = entry.value;
|
||||
sessionEntries = [entry];
|
||||
}
|
||||
}
|
||||
});
|
||||
// If the current session value is larger than the current CLS value,
|
||||
// update CLS and the entries contributing to it.
|
||||
if (sessionValue > metric.value) {
|
||||
metric.value = sessionValue;
|
||||
metric.entries = sessionEntries;
|
||||
report();
|
||||
}
|
||||
};
|
||||
const po = observe('layout-shift', handleEntries);
|
||||
if (po) {
|
||||
report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges);
|
||||
onHidden(() => {
|
||||
handleEntries(po.takeRecords());
|
||||
report(true);
|
||||
});
|
||||
// Only report after a bfcache restore if the `PerformanceObserver`
|
||||
// successfully registered.
|
||||
onBFCacheRestore(() => {
|
||||
sessionValue = 0;
|
||||
metric = initMetric('CLS', 0);
|
||||
report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges);
|
||||
doubleRAF(() => report());
|
||||
});
|
||||
// Queue a task to report (if nothing else triggers a report first).
|
||||
// This allows CLS to be reported as soon as FCP fires when
|
||||
// `reportAllChanges` is true.
|
||||
setTimeout(report, 0);
|
||||
}
|
||||
}));
|
||||
};
|
10
24_12_09/node_modules/web-vitals/dist/modules/onFCP.d.ts
generated
vendored
Normal file
10
24_12_09/node_modules/web-vitals/dist/modules/onFCP.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { FCPMetric, MetricRatingThresholds, ReportOpts } from './types.js';
|
||||
/** Thresholds for FCP. See https://web.dev/articles/fcp#what_is_a_good_fcp_score */
|
||||
export declare const FCPThresholds: MetricRatingThresholds;
|
||||
/**
|
||||
* Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and
|
||||
* calls the `callback` function once the value is ready, along with the
|
||||
* relevant `paint` performance entry used to determine the value. The reported
|
||||
* value is a `DOMHighResTimeStamp`.
|
||||
*/
|
||||
export declare const onFCP: (onReport: (metric: FCPMetric) => void, opts?: ReportOpts) => void;
|
71
24_12_09/node_modules/web-vitals/dist/modules/onFCP.js
generated
vendored
Normal file
71
24_12_09/node_modules/web-vitals/dist/modules/onFCP.js
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { onBFCacheRestore } from './lib/bfcache.js';
|
||||
import { bindReporter } from './lib/bindReporter.js';
|
||||
import { doubleRAF } from './lib/doubleRAF.js';
|
||||
import { getActivationStart } from './lib/getActivationStart.js';
|
||||
import { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';
|
||||
import { initMetric } from './lib/initMetric.js';
|
||||
import { observe } from './lib/observe.js';
|
||||
import { whenActivated } from './lib/whenActivated.js';
|
||||
/** Thresholds for FCP. See https://web.dev/articles/fcp#what_is_a_good_fcp_score */
|
||||
export const FCPThresholds = [1800, 3000];
|
||||
/**
|
||||
* Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and
|
||||
* calls the `callback` function once the value is ready, along with the
|
||||
* relevant `paint` performance entry used to determine the value. The reported
|
||||
* value is a `DOMHighResTimeStamp`.
|
||||
*/
|
||||
export const onFCP = (onReport, opts) => {
|
||||
// Set defaults
|
||||
opts = opts || {};
|
||||
whenActivated(() => {
|
||||
const visibilityWatcher = getVisibilityWatcher();
|
||||
let metric = initMetric('FCP');
|
||||
let report;
|
||||
const handleEntries = (entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.name === 'first-contentful-paint') {
|
||||
po.disconnect();
|
||||
// Only report if the page wasn't hidden prior to the first paint.
|
||||
if (entry.startTime < visibilityWatcher.firstHiddenTime) {
|
||||
// The activationStart reference is used because FCP should be
|
||||
// relative to page activation rather than navigation start if the
|
||||
// page was prerendered. But in cases where `activationStart` occurs
|
||||
// after the FCP, this time should be clamped at 0.
|
||||
metric.value = Math.max(entry.startTime - getActivationStart(), 0);
|
||||
metric.entries.push(entry);
|
||||
report(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
const po = observe('paint', handleEntries);
|
||||
if (po) {
|
||||
report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges);
|
||||
// Only report after a bfcache restore if the `PerformanceObserver`
|
||||
// successfully registered or the `paint` entry exists.
|
||||
onBFCacheRestore((event) => {
|
||||
metric = initMetric('FCP');
|
||||
report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges);
|
||||
doubleRAF(() => {
|
||||
metric.value = performance.now() - event.timeStamp;
|
||||
report(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
13
24_12_09/node_modules/web-vitals/dist/modules/onFID.d.ts
generated
vendored
Normal file
13
24_12_09/node_modules/web-vitals/dist/modules/onFID.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { FIDMetric, MetricRatingThresholds, ReportOpts } from './types.js';
|
||||
/** Thresholds for FID. See https://web.dev/articles/fid#what_is_a_good_fid_score */
|
||||
export declare const FIDThresholds: MetricRatingThresholds;
|
||||
/**
|
||||
* Calculates the [FID](https://web.dev/articles/fid) value for the current page and
|
||||
* calls the `callback` function once the value is ready, along with the
|
||||
* relevant `first-input` performance entry used to determine the value. The
|
||||
* reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* _**Important:** since FID is only reported after the user interacts with the
|
||||
* page, it's possible that it will not be reported for some page loads._
|
||||
*/
|
||||
export declare const onFID: (onReport: (metric: FIDMetric) => void, opts?: ReportOpts) => void;
|
70
24_12_09/node_modules/web-vitals/dist/modules/onFID.js
generated
vendored
Normal file
70
24_12_09/node_modules/web-vitals/dist/modules/onFID.js
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { onBFCacheRestore } from './lib/bfcache.js';
|
||||
import { bindReporter } from './lib/bindReporter.js';
|
||||
import { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';
|
||||
import { initMetric } from './lib/initMetric.js';
|
||||
import { observe } from './lib/observe.js';
|
||||
import { onHidden } from './lib/onHidden.js';
|
||||
import { firstInputPolyfill, resetFirstInputPolyfill, } from './lib/polyfills/firstInputPolyfill.js';
|
||||
import { runOnce } from './lib/runOnce.js';
|
||||
import { whenActivated } from './lib/whenActivated.js';
|
||||
/** Thresholds for FID. See https://web.dev/articles/fid#what_is_a_good_fid_score */
|
||||
export const FIDThresholds = [100, 300];
|
||||
/**
|
||||
* Calculates the [FID](https://web.dev/articles/fid) value for the current page and
|
||||
* calls the `callback` function once the value is ready, along with the
|
||||
* relevant `first-input` performance entry used to determine the value. The
|
||||
* reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* _**Important:** since FID is only reported after the user interacts with the
|
||||
* page, it's possible that it will not be reported for some page loads._
|
||||
*/
|
||||
export const onFID = (onReport, opts) => {
|
||||
// Set defaults
|
||||
opts = opts || {};
|
||||
whenActivated(() => {
|
||||
const visibilityWatcher = getVisibilityWatcher();
|
||||
let metric = initMetric('FID');
|
||||
let report;
|
||||
const handleEntry = (entry) => {
|
||||
// Only report if the page wasn't hidden prior to the first input.
|
||||
if (entry.startTime < visibilityWatcher.firstHiddenTime) {
|
||||
metric.value = entry.processingStart - entry.startTime;
|
||||
metric.entries.push(entry);
|
||||
report(true);
|
||||
}
|
||||
};
|
||||
const handleEntries = (entries) => {
|
||||
entries.forEach(handleEntry);
|
||||
};
|
||||
const po = observe('first-input', handleEntries);
|
||||
report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges);
|
||||
if (po) {
|
||||
onHidden(runOnce(() => {
|
||||
handleEntries(po.takeRecords());
|
||||
po.disconnect();
|
||||
}));
|
||||
onBFCacheRestore(() => {
|
||||
metric = initMetric('FID');
|
||||
report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges);
|
||||
// Browsers don't re-emit FID on bfcache restore so fake it until you make it
|
||||
resetFirstInputPolyfill();
|
||||
firstInputPolyfill(handleEntry);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
31
24_12_09/node_modules/web-vitals/dist/modules/onINP.d.ts
generated
vendored
Normal file
31
24_12_09/node_modules/web-vitals/dist/modules/onINP.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { INPMetric, MetricRatingThresholds, ReportOpts } from './types.js';
|
||||
/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */
|
||||
export declare const INPThresholds: MetricRatingThresholds;
|
||||
/**
|
||||
* Calculates the [INP](https://web.dev/articles/inp) value for the current
|
||||
* page and calls the `callback` function once the value is ready, along with
|
||||
* the `event` performance entries reported for that interaction. The reported
|
||||
* value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* A custom `durationThreshold` configuration option can optionally be passed to
|
||||
* control what `event-timing` entries are considered for INP reporting. The
|
||||
* default threshold is `40`, which means INP scores of less than 40 are
|
||||
* reported as 0. Note that this will not affect your 75th percentile INP value
|
||||
* unless that value is also less than 40 (well below the recommended
|
||||
* [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called as soon as the value is initially
|
||||
* determined as well as any time the value changes throughout the page
|
||||
* lifespan.
|
||||
*
|
||||
* _**Important:** INP should be continually monitored for changes throughout
|
||||
* the entire lifespan of a page—including if the user returns to the page after
|
||||
* it's been hidden/backgrounded. However, since browsers often [will not fire
|
||||
* additional callbacks once the user has backgrounded a
|
||||
* page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
|
||||
* `callback` is always called when the page's visibility state changes to
|
||||
* hidden. As a result, the `callback` function might be called multiple times
|
||||
* during the same page load._
|
||||
*/
|
||||
export declare const onINP: (onReport: (metric: INPMetric) => void, opts?: ReportOpts) => void;
|
111
24_12_09/node_modules/web-vitals/dist/modules/onINP.js
generated
vendored
Normal file
111
24_12_09/node_modules/web-vitals/dist/modules/onINP.js
generated
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { onBFCacheRestore } from './lib/bfcache.js';
|
||||
import { bindReporter } from './lib/bindReporter.js';
|
||||
import { initMetric } from './lib/initMetric.js';
|
||||
import { DEFAULT_DURATION_THRESHOLD, processInteractionEntry, estimateP98LongestInteraction, resetInteractions, } from './lib/interactions.js';
|
||||
import { observe } from './lib/observe.js';
|
||||
import { onHidden } from './lib/onHidden.js';
|
||||
import { initInteractionCountPolyfill } from './lib/polyfills/interactionCountPolyfill.js';
|
||||
import { whenActivated } from './lib/whenActivated.js';
|
||||
import { whenIdle } from './lib/whenIdle.js';
|
||||
/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */
|
||||
export const INPThresholds = [200, 500];
|
||||
/**
|
||||
* Calculates the [INP](https://web.dev/articles/inp) value for the current
|
||||
* page and calls the `callback` function once the value is ready, along with
|
||||
* the `event` performance entries reported for that interaction. The reported
|
||||
* value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* A custom `durationThreshold` configuration option can optionally be passed to
|
||||
* control what `event-timing` entries are considered for INP reporting. The
|
||||
* default threshold is `40`, which means INP scores of less than 40 are
|
||||
* reported as 0. Note that this will not affect your 75th percentile INP value
|
||||
* unless that value is also less than 40 (well below the recommended
|
||||
* [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called as soon as the value is initially
|
||||
* determined as well as any time the value changes throughout the page
|
||||
* lifespan.
|
||||
*
|
||||
* _**Important:** INP should be continually monitored for changes throughout
|
||||
* the entire lifespan of a page—including if the user returns to the page after
|
||||
* it's been hidden/backgrounded. However, since browsers often [will not fire
|
||||
* additional callbacks once the user has backgrounded a
|
||||
* page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
|
||||
* `callback` is always called when the page's visibility state changes to
|
||||
* hidden. As a result, the `callback` function might be called multiple times
|
||||
* during the same page load._
|
||||
*/
|
||||
export const onINP = (onReport, opts) => {
|
||||
// Return if the browser doesn't support all APIs needed to measure INP.
|
||||
if (!('PerformanceEventTiming' in self &&
|
||||
'interactionId' in PerformanceEventTiming.prototype)) {
|
||||
return;
|
||||
}
|
||||
// Set defaults
|
||||
opts = opts || {};
|
||||
whenActivated(() => {
|
||||
// TODO(philipwalton): remove once the polyfill is no longer needed.
|
||||
initInteractionCountPolyfill();
|
||||
let metric = initMetric('INP');
|
||||
let report;
|
||||
const handleEntries = (entries) => {
|
||||
// Queue the `handleEntries()` callback in the next idle task.
|
||||
// This is needed to increase the chances that all event entries that
|
||||
// occurred between the user interaction and the next paint
|
||||
// have been dispatched. Note: there is currently an experiment
|
||||
// running in Chrome (EventTimingKeypressAndCompositionInteractionId)
|
||||
// 123+ that if rolled out fully may make this no longer necessary.
|
||||
whenIdle(() => {
|
||||
entries.forEach(processInteractionEntry);
|
||||
const inp = estimateP98LongestInteraction();
|
||||
if (inp && inp.latency !== metric.value) {
|
||||
metric.value = inp.latency;
|
||||
metric.entries = inp.entries;
|
||||
report();
|
||||
}
|
||||
});
|
||||
};
|
||||
const po = observe('event', handleEntries, {
|
||||
// Event Timing entries have their durations rounded to the nearest 8ms,
|
||||
// so a duration of 40ms would be any event that spans 2.5 or more frames
|
||||
// at 60Hz. This threshold is chosen to strike a balance between usefulness
|
||||
// and performance. Running this callback for any interaction that spans
|
||||
// just one or two frames is likely not worth the insight that could be
|
||||
// gained.
|
||||
durationThreshold: opts.durationThreshold ?? DEFAULT_DURATION_THRESHOLD,
|
||||
});
|
||||
report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);
|
||||
if (po) {
|
||||
// Also observe entries of type `first-input`. This is useful in cases
|
||||
// where the first interaction is less than the `durationThreshold`.
|
||||
po.observe({ type: 'first-input', buffered: true });
|
||||
onHidden(() => {
|
||||
handleEntries(po.takeRecords());
|
||||
report(true);
|
||||
});
|
||||
// Only report after a bfcache restore if the `PerformanceObserver`
|
||||
// successfully registered.
|
||||
onBFCacheRestore(() => {
|
||||
resetInteractions();
|
||||
metric = initMetric('INP');
|
||||
report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
15
24_12_09/node_modules/web-vitals/dist/modules/onLCP.d.ts
generated
vendored
Normal file
15
24_12_09/node_modules/web-vitals/dist/modules/onLCP.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { LCPMetric, MetricRatingThresholds, ReportOpts } from './types.js';
|
||||
/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */
|
||||
export declare const LCPThresholds: MetricRatingThresholds;
|
||||
/**
|
||||
* Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and
|
||||
* calls the `callback` function once the value is ready (along with the
|
||||
* relevant `largest-contentful-paint` performance entry used to determine the
|
||||
* value). The reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called any time a new `largest-contentful-paint`
|
||||
* performance entry is dispatched, or once the final value of the metric has
|
||||
* been determined.
|
||||
*/
|
||||
export declare const onLCP: (onReport: (metric: LCPMetric) => void, opts?: ReportOpts) => void;
|
106
24_12_09/node_modules/web-vitals/dist/modules/onLCP.js
generated
vendored
Normal file
106
24_12_09/node_modules/web-vitals/dist/modules/onLCP.js
generated
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { onBFCacheRestore } from './lib/bfcache.js';
|
||||
import { bindReporter } from './lib/bindReporter.js';
|
||||
import { doubleRAF } from './lib/doubleRAF.js';
|
||||
import { getActivationStart } from './lib/getActivationStart.js';
|
||||
import { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';
|
||||
import { initMetric } from './lib/initMetric.js';
|
||||
import { observe } from './lib/observe.js';
|
||||
import { onHidden } from './lib/onHidden.js';
|
||||
import { runOnce } from './lib/runOnce.js';
|
||||
import { whenActivated } from './lib/whenActivated.js';
|
||||
import { whenIdle } from './lib/whenIdle.js';
|
||||
/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */
|
||||
export const LCPThresholds = [2500, 4000];
|
||||
const reportedMetricIDs = {};
|
||||
/**
|
||||
* Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and
|
||||
* calls the `callback` function once the value is ready (along with the
|
||||
* relevant `largest-contentful-paint` performance entry used to determine the
|
||||
* value). The reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* If the `reportAllChanges` configuration option is set to `true`, the
|
||||
* `callback` function will be called any time a new `largest-contentful-paint`
|
||||
* performance entry is dispatched, or once the final value of the metric has
|
||||
* been determined.
|
||||
*/
|
||||
export const onLCP = (onReport, opts) => {
|
||||
// Set defaults
|
||||
opts = opts || {};
|
||||
whenActivated(() => {
|
||||
const visibilityWatcher = getVisibilityWatcher();
|
||||
let metric = initMetric('LCP');
|
||||
let report;
|
||||
const handleEntries = (entries) => {
|
||||
// If reportAllChanges is set then call this function for each entry,
|
||||
// otherwise only consider the last one.
|
||||
if (!opts.reportAllChanges) {
|
||||
entries = entries.slice(-1);
|
||||
}
|
||||
entries.forEach((entry) => {
|
||||
// Only report if the page wasn't hidden prior to LCP.
|
||||
if (entry.startTime < visibilityWatcher.firstHiddenTime) {
|
||||
// The startTime attribute returns the value of the renderTime if it is
|
||||
// not 0, and the value of the loadTime otherwise. The activationStart
|
||||
// reference is used because LCP should be relative to page activation
|
||||
// rather than navigation start if the page was prerendered. But in cases
|
||||
// where `activationStart` occurs after the LCP, this time should be
|
||||
// clamped at 0.
|
||||
metric.value = Math.max(entry.startTime - getActivationStart(), 0);
|
||||
metric.entries = [entry];
|
||||
report();
|
||||
}
|
||||
});
|
||||
};
|
||||
const po = observe('largest-contentful-paint', handleEntries);
|
||||
if (po) {
|
||||
report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);
|
||||
const stopListening = runOnce(() => {
|
||||
if (!reportedMetricIDs[metric.id]) {
|
||||
handleEntries(po.takeRecords());
|
||||
po.disconnect();
|
||||
reportedMetricIDs[metric.id] = true;
|
||||
report(true);
|
||||
}
|
||||
});
|
||||
// Stop listening after input. Note: while scrolling is an input that
|
||||
// stops LCP observation, it's unreliable since it can be programmatically
|
||||
// generated. See: https://github.com/GoogleChrome/web-vitals/issues/75
|
||||
['keydown', 'click'].forEach((type) => {
|
||||
// Wrap in a setTimeout so the callback is run in a separate task
|
||||
// to avoid extending the keyboard/click handler to reduce INP impact
|
||||
// https://github.com/GoogleChrome/web-vitals/issues/383
|
||||
addEventListener(type, () => whenIdle(stopListening), {
|
||||
once: true,
|
||||
capture: true,
|
||||
});
|
||||
});
|
||||
onHidden(stopListening);
|
||||
// Only report after a bfcache restore if the `PerformanceObserver`
|
||||
// successfully registered.
|
||||
onBFCacheRestore((event) => {
|
||||
metric = initMetric('LCP');
|
||||
report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);
|
||||
doubleRAF(() => {
|
||||
metric.value = performance.now() - event.timeStamp;
|
||||
reportedMetricIDs[metric.id] = true;
|
||||
report(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
19
24_12_09/node_modules/web-vitals/dist/modules/onTTFB.d.ts
generated
vendored
Normal file
19
24_12_09/node_modules/web-vitals/dist/modules/onTTFB.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { MetricRatingThresholds, ReportOpts, TTFBMetric } from './types.js';
|
||||
/** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */
|
||||
export declare const TTFBThresholds: MetricRatingThresholds;
|
||||
/**
|
||||
* Calculates the [TTFB](https://web.dev/articles/ttfb) value for the
|
||||
* current page and calls the `callback` function once the page has loaded,
|
||||
* along with the relevant `navigation` performance entry used to determine the
|
||||
* value. The reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* Note, this function waits until after the page is loaded to call `callback`
|
||||
* in order to ensure all properties of the `navigation` entry are populated.
|
||||
* This is useful if you want to report on other metrics exposed by the
|
||||
* [Navigation Timing API](https://w3c.github.io/navigation-timing/). For
|
||||
* example, the TTFB metric starts from the page's [time
|
||||
* origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it
|
||||
* includes time spent on DNS lookup, connection negotiation, network latency,
|
||||
* and server processing time.
|
||||
*/
|
||||
export declare const onTTFB: (onReport: (metric: TTFBMetric) => void, opts?: ReportOpts) => void;
|
79
24_12_09/node_modules/web-vitals/dist/modules/onTTFB.js
generated
vendored
Normal file
79
24_12_09/node_modules/web-vitals/dist/modules/onTTFB.js
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { bindReporter } from './lib/bindReporter.js';
|
||||
import { initMetric } from './lib/initMetric.js';
|
||||
import { onBFCacheRestore } from './lib/bfcache.js';
|
||||
import { getNavigationEntry } from './lib/getNavigationEntry.js';
|
||||
import { getActivationStart } from './lib/getActivationStart.js';
|
||||
import { whenActivated } from './lib/whenActivated.js';
|
||||
/** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */
|
||||
export const TTFBThresholds = [800, 1800];
|
||||
/**
|
||||
* Runs in the next task after the page is done loading and/or prerendering.
|
||||
* @param callback
|
||||
*/
|
||||
const whenReady = (callback) => {
|
||||
if (document.prerendering) {
|
||||
whenActivated(() => whenReady(callback));
|
||||
}
|
||||
else if (document.readyState !== 'complete') {
|
||||
addEventListener('load', () => whenReady(callback), true);
|
||||
}
|
||||
else {
|
||||
// Queue a task so the callback runs after `loadEventEnd`.
|
||||
setTimeout(callback, 0);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Calculates the [TTFB](https://web.dev/articles/ttfb) value for the
|
||||
* current page and calls the `callback` function once the page has loaded,
|
||||
* along with the relevant `navigation` performance entry used to determine the
|
||||
* value. The reported value is a `DOMHighResTimeStamp`.
|
||||
*
|
||||
* Note, this function waits until after the page is loaded to call `callback`
|
||||
* in order to ensure all properties of the `navigation` entry are populated.
|
||||
* This is useful if you want to report on other metrics exposed by the
|
||||
* [Navigation Timing API](https://w3c.github.io/navigation-timing/). For
|
||||
* example, the TTFB metric starts from the page's [time
|
||||
* origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it
|
||||
* includes time spent on DNS lookup, connection negotiation, network latency,
|
||||
* and server processing time.
|
||||
*/
|
||||
export const onTTFB = (onReport, opts) => {
|
||||
// Set defaults
|
||||
opts = opts || {};
|
||||
let metric = initMetric('TTFB');
|
||||
let report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);
|
||||
whenReady(() => {
|
||||
const navigationEntry = getNavigationEntry();
|
||||
if (navigationEntry) {
|
||||
// The activationStart reference is used because TTFB should be
|
||||
// relative to page activation rather than navigation start if the
|
||||
// page was prerendered. But in cases where `activationStart` occurs
|
||||
// after the first byte is received, this time should be clamped at 0.
|
||||
metric.value = Math.max(navigationEntry.responseStart - getActivationStart(), 0);
|
||||
metric.entries = [navigationEntry];
|
||||
report(true);
|
||||
// Only report TTFB after bfcache restores if a `navigation` entry
|
||||
// was reported for the initial load.
|
||||
onBFCacheRestore(() => {
|
||||
metric = initMetric('TTFB', 0);
|
||||
report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);
|
||||
report(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
54
24_12_09/node_modules/web-vitals/dist/modules/types.d.ts
generated
vendored
Normal file
54
24_12_09/node_modules/web-vitals/dist/modules/types.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
export * from './types/base.js';
|
||||
export * from './types/polyfills.js';
|
||||
export * from './types/cls.js';
|
||||
export * from './types/fcp.js';
|
||||
export * from './types/fid.js';
|
||||
export * from './types/inp.js';
|
||||
export * from './types/lcp.js';
|
||||
export * from './types/ttfb.js';
|
||||
interface PerformanceEntryMap {
|
||||
navigation: PerformanceNavigationTiming;
|
||||
resource: PerformanceResourceTiming;
|
||||
paint: PerformancePaintTiming;
|
||||
}
|
||||
declare global {
|
||||
interface Document {
|
||||
prerendering?: boolean;
|
||||
wasDiscarded?: boolean;
|
||||
}
|
||||
interface Performance {
|
||||
getEntriesByType<K extends keyof PerformanceEntryMap>(type: K): PerformanceEntryMap[K][];
|
||||
}
|
||||
interface PerformanceObserverInit {
|
||||
durationThreshold?: number;
|
||||
}
|
||||
interface PerformanceNavigationTiming {
|
||||
activationStart?: number;
|
||||
}
|
||||
interface PerformanceEventTiming extends PerformanceEntry {
|
||||
duration: DOMHighResTimeStamp;
|
||||
interactionId: number;
|
||||
}
|
||||
interface LayoutShiftAttribution {
|
||||
node?: Node;
|
||||
previousRect: DOMRectReadOnly;
|
||||
currentRect: DOMRectReadOnly;
|
||||
}
|
||||
interface LayoutShift extends PerformanceEntry {
|
||||
value: number;
|
||||
sources: LayoutShiftAttribution[];
|
||||
hadRecentInput: boolean;
|
||||
}
|
||||
interface LargestContentfulPaint extends PerformanceEntry {
|
||||
readonly renderTime: DOMHighResTimeStamp;
|
||||
readonly loadTime: DOMHighResTimeStamp;
|
||||
readonly size: number;
|
||||
readonly id: string;
|
||||
readonly url: string;
|
||||
readonly element: Element | null;
|
||||
}
|
||||
interface PerformanceLongAnimationFrameTiming extends PerformanceEntry {
|
||||
renderStart: DOMHighResTimeStamp;
|
||||
duration: DOMHighResTimeStamp;
|
||||
}
|
||||
}
|
23
24_12_09/node_modules/web-vitals/dist/modules/types.js
generated
vendored
Normal file
23
24_12_09/node_modules/web-vitals/dist/modules/types.js
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export * from './types/base.js';
|
||||
export * from './types/polyfills.js';
|
||||
export * from './types/cls.js';
|
||||
export * from './types/fcp.js';
|
||||
export * from './types/fid.js';
|
||||
export * from './types/inp.js';
|
||||
export * from './types/lcp.js';
|
||||
export * from './types/ttfb.js';
|
101
24_12_09/node_modules/web-vitals/dist/modules/types/base.d.ts
generated
vendored
Normal file
101
24_12_09/node_modules/web-vitals/dist/modules/types/base.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
import type { CLSMetric, CLSMetricWithAttribution } from './cls.js';
|
||||
import type { FCPMetric, FCPMetricWithAttribution } from './fcp.js';
|
||||
import type { FIDMetric, FIDMetricWithAttribution } from './fid.js';
|
||||
import type { INPMetric, INPMetricWithAttribution } from './inp.js';
|
||||
import type { LCPMetric, LCPMetricWithAttribution } from './lcp.js';
|
||||
import type { TTFBMetric, TTFBMetricWithAttribution } from './ttfb.js';
|
||||
export interface Metric {
|
||||
/**
|
||||
* The name of the metric (in acronym form).
|
||||
*/
|
||||
name: 'CLS' | 'FCP' | 'FID' | 'INP' | 'LCP' | 'TTFB';
|
||||
/**
|
||||
* The current value of the metric.
|
||||
*/
|
||||
value: number;
|
||||
/**
|
||||
* The rating as to whether the metric value is within the "good",
|
||||
* "needs improvement", or "poor" thresholds of the metric.
|
||||
*/
|
||||
rating: 'good' | 'needs-improvement' | 'poor';
|
||||
/**
|
||||
* The delta between the current value and the last-reported value.
|
||||
* On the first report, `delta` and `value` will always be the same.
|
||||
*/
|
||||
delta: number;
|
||||
/**
|
||||
* A unique ID representing this particular metric instance. This ID can
|
||||
* be used by an analytics tool to dedupe multiple values sent for the same
|
||||
* metric instance, or to group multiple deltas together and calculate a
|
||||
* total. It can also be used to differentiate multiple different metric
|
||||
* instances sent from the same page, which can happen if the page is
|
||||
* restored from the back/forward cache (in that case new metrics object
|
||||
* get created).
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Any performance entries relevant to the metric value calculation.
|
||||
* The array may also be empty if the metric value was not based on any
|
||||
* entries (e.g. a CLS value of 0 given no layout shifts).
|
||||
*/
|
||||
entries: PerformanceEntry[];
|
||||
/**
|
||||
* The type of navigation.
|
||||
*
|
||||
* This will be the value returned by the Navigation Timing API (or
|
||||
* `undefined` if the browser doesn't support that API), with the following
|
||||
* exceptions:
|
||||
* - 'back-forward-cache': for pages that are restored from the bfcache.
|
||||
* - 'back_forward' is renamed to 'back-forward' for consistency.
|
||||
* - 'prerender': for pages that were prerendered.
|
||||
* - 'restore': for pages that were discarded by the browser and then
|
||||
* restored by the user.
|
||||
*/
|
||||
navigationType: 'navigate' | 'reload' | 'back-forward' | 'back-forward-cache' | 'prerender' | 'restore';
|
||||
}
|
||||
/** The union of supported metric types. */
|
||||
export type MetricType = CLSMetric | FCPMetric | FIDMetric | INPMetric | LCPMetric | TTFBMetric;
|
||||
/** The union of supported metric attribution types. */
|
||||
export type MetricWithAttribution = CLSMetricWithAttribution | FCPMetricWithAttribution | FIDMetricWithAttribution | INPMetricWithAttribution | LCPMetricWithAttribution | TTFBMetricWithAttribution;
|
||||
/**
|
||||
* The thresholds of metric's "good", "needs improvement", and "poor" ratings.
|
||||
*
|
||||
* - Metric values up to and including [0] are rated "good"
|
||||
* - Metric values up to and including [1] are rated "needs improvement"
|
||||
* - Metric values above [1] are "poor"
|
||||
*
|
||||
* | Metric value | Rating |
|
||||
* | --------------- | ------------------- |
|
||||
* | ≦ [0] | "good" |
|
||||
* | > [0] and ≦ [1] | "needs improvement" |
|
||||
* | > [1] | "poor" |
|
||||
*/
|
||||
export type MetricRatingThresholds = [number, number];
|
||||
/**
|
||||
* @deprecated Use metric-specific function types instead, such as:
|
||||
* `(metric: LCPMetric) => void`. If a single callback type is needed for
|
||||
* multiple metrics, use `(metric: MetricType) => void`.
|
||||
*/
|
||||
export interface ReportCallback {
|
||||
(metric: MetricType): void;
|
||||
}
|
||||
export interface ReportOpts {
|
||||
reportAllChanges?: boolean;
|
||||
durationThreshold?: number;
|
||||
}
|
||||
/**
|
||||
* The loading state of the document. Note: this value is similar to
|
||||
* `document.readyState` but it subdivides the "interactive" state into the
|
||||
* time before and after the DOMContentLoaded event fires.
|
||||
*
|
||||
* State descriptions:
|
||||
* - `loading`: the initial document response has not yet been fully downloaded
|
||||
* and parsed. This is equivalent to the corresponding `readyState` value.
|
||||
* - `dom-interactive`: the document has been fully loaded and parsed, but
|
||||
* scripts may not have yet finished loading and executing.
|
||||
* - `dom-content-loaded`: the document is fully loaded and parsed, and all
|
||||
* scripts (except `async` scripts) have loaded and finished executing.
|
||||
* - `complete`: the document and all of its sub-resources have finished
|
||||
* loading. This is equivalent to the corresponding `readyState` value.
|
||||
*/
|
||||
export type LoadState = 'loading' | 'dom-interactive' | 'dom-content-loaded' | 'complete';
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user