Created
June 19, 2023 13:40
-
-
Save gagan0123/67afee495c292b92ea978040c8c43e98 to your computer and use it in GitHub Desktop.
Sitemap PageSpeed Analyzer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Importing required libraries and modules | |
| const axios = require('axios'); | |
| const xml2js = require('xml2js'); | |
| const psi = require('psi'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const fastcsv = require('fast-csv'); | |
| /** | |
| * Fetch and parse the sitemap located at the given URL. | |
| * If it's a sitemap index, recursively fetch and parse nested sitemaps. | |
| * @param {string} sitemapUrl - The URL of the sitemap to parse. | |
| * @returns {Promise<Array<string>>} - An array of URLs parsed from the sitemap. | |
| */ | |
| const parseSitemap = async (sitemapUrl) => { | |
| try { | |
| // Fetching the sitemap from the given URL | |
| const response = await axios.get(sitemapUrl); | |
| // Parsing the XML sitemap | |
| const parser = new xml2js.Parser(); | |
| const parsedXml = await parser.parseStringPromise(response.data); | |
| // Handling sitemap index files by recursively parsing nested sitemaps | |
| if (parsedXml?.sitemapindex?.sitemap) { | |
| let urls = []; | |
| for (const sitemap of parsedXml.sitemapindex.sitemap) { | |
| if (sitemap.loc) { | |
| const nestedUrls = await parseSitemap(sitemap.loc[0]); | |
| urls = urls.concat(nestedUrls); | |
| } | |
| } | |
| return urls; | |
| } | |
| // Handling single sitemaps and extracting URLs | |
| if (parsedXml?.urlset?.url) { | |
| return parsedXml.urlset.url | |
| .slice(0, 10) | |
| .map(url => url.loc && url.loc[0]) | |
| .filter(Boolean); | |
| } | |
| return []; | |
| } catch (error) { | |
| console.error('Error parsing sitemap:', error); | |
| return []; | |
| } | |
| }; | |
| /** | |
| * Analyze the page speed insights of a given URL for the specified strategy. | |
| * @param {string} url - The URL to analyze. | |
| * @param {string} strategy - The strategy to use ('mobile' or 'desktop'). | |
| * @returns {Promise<Object>} - The page speed insights data. | |
| */ | |
| const analyzePageSpeed = async (url, strategy) => { | |
| try { | |
| // Fetching PageSpeed Insights for the given URL | |
| const result = await psi(url, {nokey: 'true', strategy}); | |
| const fieldData = result.data.loadingExperience.metrics; | |
| const labData = result.data.lighthouseResult.audits; | |
| // Extracting and returning relevant page speed insights data | |
| return { | |
| url, | |
| strategy, | |
| lcp_field: fieldData?.LARGEST_CONTENTFUL_PAINT_MS?.percentile || '', | |
| cls_field: fieldData?.CUMULATIVE_LAYOUT_SHIFT_SCORE?.percentile || '', | |
| fcp_field: fieldData?.FIRST_CONTENTFUL_PAINT_MS?.percentile || '', | |
| ttfb_field: fieldData?.EXPERIMENTAL_TIME_TO_FIRST_BYTE?.percentile || '', | |
| lcp_lab: labData?.['largest-contentful-paint']?.numericValue || '', | |
| cls_lab: labData?.['cumulative-layout-shift']?.numericValue || '', | |
| fcp_lab: labData?.['first-contentful-paint']?.numericValue || '', | |
| speed_index_lab: labData?.['speed-index']?.numericValue || '', | |
| tbt_lab: labData?.['total-blocking-time']?.numericValue || '' | |
| }; | |
| } catch (error) { | |
| console.error('Error fetching PageSpeed Insights:', error); | |
| return {url, strategy, error: error.message}; | |
| } | |
| }; | |
| /** | |
| * Main function to run the sitemap parsing and page speed analysis. | |
| */ | |
| const run = async () => { | |
| // Get sitemap URL and output file name from command line arguments | |
| const [sitemapUrl, outputFileName] = process.argv.slice(2); | |
| // Validation | |
| if (!sitemapUrl || !outputFileName) { | |
| console.error('Please provide a sitemap URL and an output file name as command line arguments.'); | |
| return; | |
| } | |
| // Fetch and parse URLs from the sitemap | |
| const urls = await parseSitemap(sitemapUrl); | |
| // Create CSV stream to write results | |
| const csvStream = fastcsv.format({headers: true}); | |
| const writableStream = fs.createWriteStream(path.join(__dirname, outputFileName)); | |
| csvStream.pipe(writableStream); | |
| // Loop through URLs and analyze page speed insights for desktop and mobile | |
| for (const url of urls) { | |
| console.log(`Analyzing ${url} for desktop`); | |
| const desktopResult = await analyzePageSpeed(url, 'desktop'); | |
| csvStream.write(desktopResult); | |
| console.log(`Analyzing ${url} for mobile`); | |
| const mobileResult = await analyzePageSpeed(url, 'mobile'); | |
| csvStream.write(mobileResult); | |
| } | |
| // End the CSV stream | |
| csvStream.end(); | |
| console.log(`Analysis complete. Results written to ${outputFileName}`); | |
| }; | |
| // Running the main function | |
| run(); | |
| // Run it using command line: | |
| // node sitemapPageSpeedAnalyzer.js https://www.example.com/sitemap.xml output.csv |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment