All Projects → LuXDAmore → nuxt-prune-html

LuXDAmore / nuxt-prune-html

Licence: MIT license
🔌⚡ 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/audits by removing all the scripts with dynamic rendering

Programming Languages

javascript
184084 projects - #8 most used programming language
Vue
7211 projects
CSS
56736 projects

Projects that are alternatives of or similar to nuxt-prune-html

nuxt-speedkit
nuxt-speedkit will help you to improve the lighthouse performance score (100/100) of your website.
Stars: ✭ 401 (+481.16%)
Mutual labels:  nuxt, nuxtjs, lighthouse, nuxt-module, web-vitals
nuxt-humans-txt
🧑🏻👩🏻 "We are people, not machines" - An initiative to know the creators of a website. Contains the information about humans to the web building - A Nuxt Module to statically integrate and generate a humans.txt author file - Based on the HumansTxt Project.
Stars: ✭ 27 (-60.87%)
Mutual labels:  modules, nuxt, nuxtjs, nuxt-module
nuxt-modules
AX2's Nuxt modules
Stars: ✭ 30 (-56.52%)
Mutual labels:  modules, nuxt, nuxtjs, nuxt-module
vue-plausible
Plausible Analytics Vue.js Plugin and NuxtJS Module
Stars: ✭ 107 (+55.07%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
generative-art
🌈🎨 Generative Art is the idea realized as genetic code of artificial events, as construction of dynamic complex systems able to generate endless variations. This is also a nuxt-module (@luxdamore/nuxt-canvas-sketch) - [three.js, tensorflow.js and gsap are not included].
Stars: ✭ 41 (-40.58%)
Mutual labels:  modules, nuxtjs, nuxt-module
nuxt-gsap-module
GSAP module for Nuxt.js
Stars: ✭ 183 (+165.22%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
nuxt-ts-module
A tiny module to use Typescript within Nuxt.js application.
Stars: ✭ 21 (-69.57%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
lumen-cms
GraphQL API-First CMS based on NodeJS and Vue 2, Nuxt and Vuetify
Stars: ✭ 77 (+11.59%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
nuxt-quasar
Nuxt module for the Quasar Framework
Stars: ✭ 36 (-47.83%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
nuxt-ghost
Easy Ghost content API integration with Nuxt.js.
Stars: ✭ 27 (-60.87%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
nuxt-stripejs
💳 NuxtJS module for Stripe.js which loads only when required and w/ retry mechanism
Stars: ✭ 17 (-75.36%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
nuxt-stencil
Easy Stencil.js component library integration with Nuxt.js.
Stars: ✭ 16 (-76.81%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
Nuxt Optimized Images
🌅🚀 Automatically optimizes images used in Nuxt.js projects (JPEG, PNG, SVG, WebP and GIF).
Stars: ✭ 717 (+939.13%)
Mutual labels:  optimization, nuxt, nuxtjs
nuxt-typo3
TYPO3 Frontend rendered in Vue.js and Nuxt (frontend for EXT:headless)
Stars: ✭ 66 (-4.35%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
k-domains
A simple module to manage multiple subdomains with just one project
Stars: ✭ 41 (-40.58%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
global-components
Module to register global components for Nuxt.js
Stars: ✭ 57 (-17.39%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
nuxt-babel
Use normal .babelrc file with your Nuxt app
Stars: ✭ 32 (-53.62%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
nuxt-feature-toggle
The nuxt feature toggle module
Stars: ✭ 78 (+13.04%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
applicationinsights-module
Application Insights module for NuxtJS
Stars: ✭ 14 (-79.71%)
Mutual labels:  nuxt, nuxtjs, nuxt-module
supabase
An easy way to integrate Supabase with NuxtJS
Stars: ✭ 39 (-43.48%)
Mutual labels:  nuxt, nuxtjs, nuxt-module

🔌 Nuxt Prune HTML

Code Quality Downloads Dependencies Circle CI Version 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/audits 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 server, has everything it needs already injected in the HTML (ex. css styles). So, usually, for a bot, a audit or for a human, the website its almost visually the same with or without Javascript.

This library is born to remove all the scripts injected into the HTML only if a visitor is a Bot or a Performance Audit (ex. a Lighthouse Audit). This should speed up (blazing fast) your nuxt-website up to a value of ~99 in performance because it cheats various scenarios.

Usually, with less assets, resources and html to download, the number of urls crawled by a bot are widely boosted 📈.

Inspired by this rcfs and this issue.

Features

  • Prune based on default detection;
    • match the user-agent;
    • match a bot;
    • match an audit;
    • match a custom-header;
  • Prune based on headers values (useful in/for Lambdas);
  • Prune based on query parameters (useful during navigation, hybrid-experience).

Pro et contra

This could cause some unexpected behaviors, but..

Cons.:

Pros.:

  • Some of these features aren't "used by" a bot/audit, so you don't really need them:
  • Images with lazy-load can be fixed with a native attribute, with a custom script or with classesSelectorsToKeep (check the configuration);
  • You can pre-load ad inject all of the data that you need (Rest API, GraphQL, ecc) during the build phase with nuxt-apis-to-file, speeding up the website loading time;
  • Hydration decrease performance, so it's ok to prune it for bots or audits;
  • Less HTML, assets and resources are served to browsers and clients;
  • Bot/audit only have the Javascript they need;
  • With less assets to download, the number of urls crawled are widely boosted;
  • Bots, PageSpeed Insights, Google Measure and Lighthouse Audit are already pruned by the plugin with the default configuration;
  • Faster web-vitals, faster TTI, faster FCP, faster FMP, faster all.

N.B.: This is known as Dynamic Rendering and it's not considered black-hat or cloaking.


💡 Lighthouse

Lighthouse Audit before Lighthouse Audit after


Setup

  1. Install @luxdamore/nuxt-prune-html as a dependency:
    • yarn add @luxdamore/nuxt-prune-html;
    • or, npm install --save @luxdamore/nuxt-prune-html;
  2. Append @luxdamore/nuxt-prune-html to the modules array of your nuxt.config.js.

Configuration

    // nuxt.config.js
    export default {

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

        // Module - default config
        pruneHtml: {
            enabled: false, // `true` in production
            hideGenericMessagesInConsole: false, // `false` in production
            hideErrorsInConsole: false, // deactivate the `console.error` method
            hookRenderRoute: true, // activate `hook:render:route`
            hookGeneratePage: true, // activate `hook:generate:page`
            selectors: [
                // CSS selectors to prune
                'link[rel="preload"][as="script"]',
                'script:not([type="application/ld+json"])',
            ],
            classesSelectorsToKeep: [], // disallow pruning of scripts with this classes, n.b.: each `classesSelectorsToKeep` is appended to every `selectors`, ex.: `link[rel="preload"][as="script"]:not(__classesSelectorsToKeep__)`
            link: [], // inject custom links, only if pruned
            script: [], // inject custom scripts, only if pruned
            htmlElementClass: null, // a string added as a class to the <html> element if pruned
            cheerio: {
                // the config passed to the `cheerio.load(__config__)` method
                xmlMode: false,
            },
            types: [
                // it's possibile to add different rules for pruning
                'default-detect',
            ],

            // 👇🏻 Type: `default-detect`
            headerNameForDefaultDetection: 'user-agent', // The `header-key` base for `MobileDetection`, usage `request.headers[ headerNameForDefaultDetection ]`
            auditUserAgent: 'lighthouse', // prune if `request.header[ headerNameForDefaultDetection ]` match, could be a string or an array of strings
            isAudit: true, // remove selectors if match with `auditUserAgent`
            isBot: true, // remove selectors if is a bot
            ignoreBotOrAudit: false, // remove selectors in any case, not depending on Bot or Audit
            matchUserAgent: null, // prune if `request.header[ headerNameForDefaultDetection ]` match, could be a string or an array of strings

            // 👇🏻 Type: 'query-parameters'
            queryParametersToPrune: [
                // array of objects (key-value)
                // trigger the pruning if 'query-parameters' is present in `types` and at least one value is matched, ex. `/?prune=true`
                {
                    key: 'prune',
                    value: 'true',
                },
            ],
            queryParametersToExcludePrune: [], // same as `queryParametersToPrune`, exclude the pruning if 'query-parameters' is present in `types` and at least one value is matched, this priority is over than `queryParametersToPrune`

            // 👇🏻 Type: 'headers-exist'
            headersToPrune: [], // same as `queryParametersToPrune`, but it checks `request.headers`
            headersToExcludePrune: [], // same as `queryParamToExcludePrune`, but it checks `request.headers`, this priority is over than `headersToPrune`

            // Emitted events for callbacks methods
            onBeforePrune: null, // ({ result, [ req, res ] }) => {}, `req` and `res` are not available on `nuxt generate`
            onAfterPrune: null, // ({ result, [ req, res ] }) => {}, `req` and `res` are not available on `nuxt generate`
        },

    };

With link and script it's possibile to add one or more objects on the pruned HTML, ex.:

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

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

Types / Rules

Possible values are [ 'default-detect', 'query-parameters', 'headers-exist' ]:

  • default-detect: prune based on one header(request.headers[ headerNameForDefaultDetection ])
    • different checks with MobileDetect:
      • isBot, trigger .is( 'bot' ) method;
      • auditUserAgent or matchUserAgent, trigger .match() method;
  • query-parameters: prune based on one or more query parameter, tests key / value based on queryParametersToPrune / queryParametersToExcludePrune:
    • you can also specify routes in nuxt.config, ex. { generate: { routes: [ '/?prune=true' ] } }
  • headers-exist: prune based on one or more header, tests key / value based on headersToPrune / headersToExcludePrune.

N.B.: It's possibile to mix different types.


Related things you should know

  • Nuxt hooks, the plugin has access to request.headers only if the project is running as a server (ex. nuxt start)
    • If you generate your site it's not possibile to check request.headers, so (for types: [ 'default-detect', 'headers-exist' ]) it always prune, but You can disable this behavior by setting hookGeneratePage to false (or by using the type query-parameters);
  • Usage with types: [ 'default-detect' ], load the MobileDetect library;
  • It use Cheerio, jQuery for servers, library to filter and prune the html.

Advices


👩🏻‍💻👨🏻‍💻 Development

  1. Clone the repository:
    • git clone https://github.com/LuXDAmore/nuxt-prune-html.git;
  2. Install dependencies:
    • yarn install (or npm install);
  3. Start a development server:
    • yarn dev (or npm run dev);
  4. Test your code:
    • yarn test (or npm run test);
  5. Extra, generate the documentation (Github Pages):
    • 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.

📝 Discussions

We're using Github discussions as a place to connect with other members of our community. You are free to ask questions and share ideas, so enjoy yourself.

👥 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-now Luca Iaconelli

💼 Hire me

Contacts

💸 Are you feeling generous today?

If You want to share a beer, we can be really good friends 😄

Paypal // Patreon // Ko-fi

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].