Development Guidelines

Performance

Non-blocking styles

Only use this in conjunction with Critical Path CSS — web.dev reference.

          
            <!-- resources/views/partials/head.blade.php -->
            <link rel="preload" href="@asset('styles/main.css')" as="style" onload="this.onload=null;this.rel='stylesheet'">
            <noscript><link rel="stylesheet" href="@asset('styles/main.css')"></noscript>
          
        

Note: this is untested and relies on Contact Form 7 not changing path to CSS.

          
            // app/setup.php
            add_action('wp_enqueue_scripts', function () {
              wp_dequeue_style('contact-form-7');
            }, 100);
          
        
          
            <link rel="preload" href="/wp-content/plugins/contact-form-7/includes/css/styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
            <noscript><link rel="stylesheet" href="/wp-content/plugins/contact-form-7/includes/css/styles.css"></noscript>
          
        

Critical Path CSS

          
            yarn add html-critical-webpack-plugin@1.1.0 -D
          
        
          
            // resources/assets/build/webpack.config.optimize.js
            const HtmlCriticalWebpackPlugin = require('html-critical-webpack-plugin');

            // in plugins: []
            new HtmlCriticalWebpackPlugin({
              base: config.paths.dist,
              src: config.devUrl,
              dest: 'styles/critical.css',
              ignore: ['@font-face', /url\(/, /wpcf7/, /swiper/],
              inline: false,
              minify: true,
              extract: false,
              dimensions: [
                {
                  width: 640,
                  height: 640,
                },
                {
                  width: 1500,
                  height: 1080,
                },
              ],
              penthouse: {
                blockJSRequests: false,
              },
            }),
          
        
          
            // app/helpers.php
            function locate_asset($asset): string
            {
                return trailingslashit(config('assets.path')) . sage('assets')->get($asset);
            }

            function get_file_contents($asset): string
            {
                global $wp_filesystem;

                if (empty($wp_filesystem)) {
                    require_once ABSPATH . '/wp-admin/includes/file.php';
                }

                \WP_Filesystem();

                $asset_path = locate_asset($asset);

                if ($wp_filesystem->is_readable($asset_path)) {
                    return $wp_filesystem->get_contents($asset_path);
                }

                return '';
            }
          
        
          
            // config/assets.php
            'path' => get_theme_file_path().'/dist',
          
        
          
            // config/assets.php
            'path' => get_theme_file_path().'/dist',
          
        
          
            // app/setup.php
            // NOTE: comment out the loading of the main.css file in enqueue scripts function
            add_action('wp_head', function (): void {
              $critical_CSS = 'styles/critical.css';
              if (file_exists(locate_asset($critical_CSS))) {
                echo '<style id="critical-css">' . get_file_contents($critical_CSS) . '</style>';
              }
            }, 1);
          
        

Async gtag.js

Google analytics reference

          
            <!-- <head> -->
            <script>
              window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
              ga('create', '{GA_PROPERTY_ID}, 'auto');
              ga('send', 'pageview');
            </script>
            <script async src="https://www.google-analytics.com/analytics.js"></script>
          
        

Lazy load iframes using AlpineJS 3

It is best practice to apply an overlaying image (poster).

          
            <!-- add intersect plugin to <head>, before alpinejs script tag -->
            <script defer src="https://unpkg.com/@alpinejs/intersect@3.x.x/dist/cdn.min.js"></script>
          
        
          
            <!-- Basic HTML for loading iframe from WordPress -->
            <iframe x-data="lazyiframes" x-intersect="load($el)" title="YouTube video" class="lazyframe" loading="lazy" width="560" height="315" data-src="{YOUTUBE_EMBED_URL}" frameborder="0" allowfullscreen x-cloak></iframe>
          
        
          
            // initiate the x-data function
            document.addEventListener('alpine:init', () => {
              Alpine.data('lazyiframes', () => ({
                // using x-intersect, switch the data-src to the src tag when user arrives at iframe
                load(el) {
                  el.setAttribute('src', el.getAttribute('data-src'));
                },
              }))
            });