Skip to content

Nuxt module to prune html before sending it to the browser (it removes elements matching CSS selector(s)), useful for boosting performance showing a different HTML for bots by removing all the scripts with dynamic rendering

License

Notifications You must be signed in to change notification settings

athulanilthomas/nuxt-prune-html

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸŽ‰ Nuxt Prune HTML

npm version npm downloads Circle CI Dependencies License Donate

Nuxt module to prune html before sending it to the browser (it removes elements matching CSS selector(s)), useful for boosting performance showing a different HTML for bots by removing all the scripts with dynamic rendering.

πŸ’˜ Motivation

Due to the versatility of Nuxt (and of the SSR in general), a website generated (or served) via node, has everything it needs already injected (in the HTML, ex. styles). So, usually, for a bot or for a human, the website its almost visually the same without Javascript.

These library was born to remove the scripts injected in the HTML only if a visitor is a Bot or a "Chrome Lighthouse". This should speed up (blazing fast) your nuxt-website up to a value of ~95 in performance during an Audit because it cheats various scenarios.

Obviously this could cause some unexpected behaviors.

Pro et contra

N.B. : Valid for Bots, PageSpeed Insights, Google Measure and Lighthouse Audits. This is known as Dynamic Rendering

Cons:

  • no SPA navigation;
  • no lazy-load for images (only if native, or with a custom script or with selectorToKeep );
  • no <client-only> html.

Pro:

  • some of these features aren't "used by" a Bot or a Lighthouse Audit, so you don't really need them (ex. Bots doesn't need SPA navigation, client-only tags could lead in a slower TTI);
  • less HTML;
  • BOTS only have the Javascript they need;
  • PageSpeed Insights, Measure and Lighthouse Audit in Chrome are already triggered by the plugin without the needing of change any value;
  • fast TTI, fast FCP, fast FMP, fast all.

Inspired by this rcfs and this issue.


Advices

  • Before setting up the module, try to Disable JavaScript With Chrome DevTools while navigate your website, this is how your website appear to a Bot (with this module activated);
  • If you generate your site it's not possibile to check the user-agent, so i choose to always prune HTML (you can disable this behavior by setting the hookGeneratePage configuration value to false);
  • If you use some <client-only> components, you should prepare a version that is visually the same with the placeholder slot;
  • This plugin was thought for Bots and uses only the remove() method of Cheerio;
  • You can check the website as a GoogleBot, following this guide.

Related things you should know

  • It use the MobileDetect library to check if .is( 'bot' ), .match( options.lighthouseUserAgent ) or .match( options.matchUserAgent );
  • Nuxt hooks, so the plugin has access to req.headers[ 'user-agent' ] only if the project is running as a server (ex. nuxt start);
  • It use Cheerio, jQuery for servers, library to prune the html.

πŸ’‘ Lighthouse

Lighthouse Audit before Lighthouse Audit after


Setup

  1. Add @luxdamore/nuxt-prune-html dependency to your project;
  2. Add @luxdamore/nuxt-prune-html in the modules section of your nuxt.config.js;
    yarn add @luxdamore/nuxt-prune-html # or npm install --save @luxdamore/nuxt-prune-html

Configuration

N.B. : the config is only shallow merged, not deep merged.

    // nuxt.config.js
    export default {

        // Module installation
        modules: [ '@luxdamore/nuxt-prune-html' ],

        // Module config
        pruneHtml: {
            hideErrorsInConsole: false,
            hideGenericMessagesInConsole: false, // Disabled in production
            enabled: false, // Disabled in dev-mode due to the hot reload (is client-side)
            selectors: [ // Css selectors to prune
                'link[rel="preload"][as="script"]',
                'script:not([type="application/ld+json"])',
            ],
            selectorToKeep: null, // Disallow pruning of scripts with this class, N.B.: this selector will be appended to every selectors, `ex. script:not([type="application/ld+json"]):not(__VALUE__)`
            script: [], // Inject custom scripts only for matched UA (BOTS-only)
            link: [], // Inject custom links only for matched UA (BOTS-only)
            cheerio: { // It use Cheerio under the hood, so this is the config passed in the cheerio.load() method
                xmlMode: false,
            },
            ignoreBotOrLighthouse: false, // Remove selectors in any case, not depending on Bot or Lighthouse
            isBot: true, // Remove selectors if is a bot
            isLighthouse: true, // Remove selectors if match the Lighthouse UserAgent
            matchUserAgent: null, // Remove selectors if this userAgent is matched, either as String or RegExp (a string will be converted to a case-insensitive RegExp in the MobileDetect library)
            hookRenderRoute: true, // Activate the prune during the `hook:render:route`
            hookGeneratePage: true, // Activate the prune during the `hook:generate:page`
            lighthouseUserAgent: 'lighthouse', // Value of the Lighthouse UserAgent, either as String or RegExp (a string will be converted to a case-insensitive RegExp in the MobileDetect library)
            headerName: 'user-agent', // Value of a custom header name passed from a Lambda Edge function, or similar
        },

    };

With link and script it's possibile to add one or more objects ex.:

    export default {
        pruneHtml: {
            script: [
                {
                    src: '/my-custom-lazy-load-for-bots.js',
                    lazy: true,
                    defer: true,
                },
            ],
            link: [
                {
                    src: '/my-custom-lazy-load-for-bots.js',
                    rel: 'preload',
                    as: 'script',
                    position: 'phead', // Default value is 'body' --> Other allowed values are: 'phead', 'head' and 'pbody'
                },
            ],
        },
    };

Development

  1. Clone this repository;
  2. Install dependencies using yarn install or npm install;
  3. Start development server using yarn dev or npm run dev;
  4. Build Github Pages using yarn generate or npm run generate (the content is automatically generated into the /docs folder).

🐞 Issues

Please make sure to read the Issue Reporting Checklist before opening an issue. Issues not conforming to the guidelines may be closed immediately.

πŸ‘₯ Contribution

Please make sure to read the Contributing Guide before making a pull request.

πŸ“– Changelog

Details changes for each release are documented in the release notes.

πŸ“ƒ License

MIT License // Copyright (Β©) 2019-present Luca Iaconelli

πŸ’Έ Are you feeling generous today? :)

Do you want to share a beer? We can be good friends.. Paypal // Patreon

It's always a good day to be magnanimous - cit

πŸ’Ό Hire me

Contacts

ko-fi

About

Nuxt module to prune html before sending it to the browser (it removes elements matching CSS selector(s)), useful for boosting performance showing a different HTML for bots by removing all the scripts with dynamic rendering

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 95.1%
  • Vue 4.3%
  • CSS 0.6%