How to Display a Video Playlist - P1- Using MB Views

How to Display a Video Playlist - P1- Using MB Views

Using a video playlist allows you to display a collection of videos. You can use this type of content for websites of many fields such as education for courses, exercise for daily movements, music for songs in a category, etc.

The video playlist will keep your visitors engaged for longer, and they will find videos in the same playlist easily. Let’s figure out the way to display a video playlist with the help of MB Views from Meta Box.

Continue reading "How to Display a Video Playlist - P1- Using MB Views"

How to Delay The Execution of JavaScript to Boost Page Speed

How to Delay JavaScript to Boost Page Speed

In recent years, approaching users on multiple channels such as advertising websites, social networks, or live chat services has become more and more popular. And then, using scripts to insert those services into a website is the most important technique. However, using too many 3rd party scripts will cause a slower loading speed of the website and its Page Speed scores may be worse. At that time, you often have just 2 options: accept the slow loading or remove some scripts. After a while of researching, we found a way to have one more option. It’s delaying the execution or loading of JavaScript. Let's see how!

Why delaying JavaScript?

Data downloaded from third-party servers like Facebook Page Widget, Facebook Messenger, Facebook Comments, iframe or live chat services like Tawk.to are data that you cannot control. You cannot compress, merge or cache them, simply because they are not on your host. These data are often very heavy and can cause serious problems related to website loading speed. To see this clearly, you can use Google PageSpeed ​​Insights, GTmetrix, or any other speed test tools to verify.

And since you cannot optimize them, the only solution to integrate the above services into the website without affecting the page speed is to delay the execution of their scripts. In this way, you will reduce your page render time and improve speed indexes on page speed testing tools such as Time to Interactive, First CPU Idle, Max Potential Input Delay, etc. This will also reduce the initial payload on the browser by reducing the number of requests.

Note: This technique is based on the code of Flying Scripts, which allows you to delay scripts in WordPress. The plugin has more control options in the admin area where you don't need to touch code. So, check it out if you want that. Otherwise, let's discover how the code works below.

How to delay JavaScript in WordPress

The delay script

To delay scripts, we need to write a custom code. This code is called "delay script" and its job is delaying other scripts. In other words, it's used to load other scripts on the website.

You can put this script in the <head> or <body> tag. But you should put it in the <head> tag to run it at the same time with the lazy load scripts. It is more reasonable for most cases. If the delayed scripts are in the <head> tag, they will not work when placed in the <body> tag because the script will be loaded just after the whole page finished loading.

<script>
{
    const load = () => {
        document.querySelectorAll("script[data-type='lazy']").forEach(el => el.setAttribute("src", el.getAttribute("data-src")));
        document.querySelectorAll("iframe[data-type='lazy']").forEach(el => el.setAttribute("src", el.getAttribute("data-src")));
    }
    const timer = setTimeout(load, 5000);
    const trigger = () => {
        load();
        clearTimeout(timer);
    }
    const events = ["mouseover","keydown","touchmove","touchstart"];
    events.forEach(e => window.addEventListener(e, trigger, {passive: true, once: true}));
}
</script>

Note: You can use the Slim SEO plugin to to add code to the header. This plugin allows you to insert any code to the header, body, or footer. So you can use it to insert Webmaster tool verification codes or tracking scripts.

Because there will still be scripts you want to execute right away, the above script doesn’t delay the execution of all the scripts on your site. In there, I specified that only scripts with the attribute data-type='lazy' (you can rename the attribute freely) will be delayed. Therefore, after adding the above script, you need to find all the scripts that you want to delay to add this attribute. I will do this in the next step.

The above script also specifies that it will delay the execution of the specified scripts until one of the following two conditions occurs:

  1. The user interacts on the website, such as scrolling the screen, typing from the keyboard, or touching from mobile devices.
  2. After a certain time specified by you, in the above code - 5s, the script will still be executed even if there is no user interaction.

Modify existing scripts

After adding the delay script, we need to modify exising scripts on your website to make them delayed. For each type of script, there will be a different way to do that. Here is how to do it for some popular scripts like Google Tag Manager, Facebook Customer Chat, Youtube, or Google Maps.

Google Tag Manager

Below is the default Google Tag Manager script:

<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','YOUR-GTM-ID');</script>

You can rewrite it with the delay script as follows:

<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({'gtm.start': new Date().getTime(), event: 'gtm.js'});
</script>
<script data-type="lazy" data-src="https://www.googletagmanager.com/gtm.js?id=YOUR-GTM-ID"></script>

Google Analytics

The default Google Analytics code looks like this:

<script async src="https://www.googletagmanager.com/gtag/js?id=YOUR-ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());

gtag('config', 'YOUR-ID');
</script>

To delay it, change it to:

<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'YOUR-ID');
</script>
<script data-type="lazy" data-src="https://www.googletagmanager.com/gtag/js?id=YOUR-ID"></script>

Facebook Customer Chat

Here is the default Facebook script, used to load the Customer Chat widget:

<div id="fb-root"></div>
<div id="fb-customer-chat" class="fb-customerchat"></div>
<script>
    var chatbox = document.getElementById('fb-customer-chat');
    chatbox.setAttribute("page_id", "YOUR_PAGE_ID");
    chatbox.setAttribute("attribution", "biz_inbox");

    window.fbAsyncInit = function() {
        FB.init({
            xfbml : true,
            version : 'v12.0'
        });
    };

    (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) return;
        js = d.createElement(s); js.id = id;
        js.src = 'https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js';
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));
</script>

In it, the code is in the paragraph (function()...); used to load chat widgets to your website.

I will shorten it by removing the function() code and adding a script like this right below the the code as follows:

<script data-type='lazy' data-src="https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js"></script>

Then, the code of Facebook Customer Chat will look like this:

<div id="fb-root"></div>
<div id="fb-customer-chat" class="fb-customerchat"></div>
<script>
    var chatbox = document.getElementById('fb-customer-chat');
    chatbox.setAttribute("page_id", "YOUR_PAGE_ID");
    chatbox.setAttribute("attribution", "biz_inbox");

    window.fbAsyncInit = function() {
        FB.init({
            xfbml : true,
            version : 'v12.0'
        });
    };
</script>
<script data-type='lazy' data-src="https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js"></script>

If you use another plugin of Facebook such as Facebook Comment, Facebook Widget, or other live chat services such as Tawk.to, you can do likewise.

Youtube

Youtube and Google Maps use iFrame tags. With this tag, you just have to add data-type='lazy' and data-src like this:

The default of Youtube is:

<iframe src="https://www.youtube.com/embed/I3ncHxLxwlM"></iframe>

Now, I will change it into this:

<iframe data-type='lazy' data-src="https://www.youtube.com/embed/I3ncHxLxwlM"></iframe>

Google Maps

The default iFrame of Google Maps is:

<iframe src="https://www.google.com/maps/embed/v1/place?key=API_KEY&q=Space+Needle,Seattle+WA"></iframe>

So I will change it by adding data- type='lazy' inside the tag <iframe> like this:

<iframe data-type='lazy' data-src="https://www.google.com/maps/embed/v1/place?key=API_KEY&q=Space+Needle,Seattle+WA"></iframe>

Other Scripts

If you want to apply this method to the common scripts, you just need to replace src into data-src and add the data-type='lazy' attribute.

An example is:

<script src="custom-javascript.js"></script>

Then, change it into this:

<script data-src="custom-javascript.js" data-type='lazy'></script>

Should (not) you delay scripts?

This technique should be used for scripts related to the user interaction or live chat like Facebook Customer Chat, Facebook Widget, Facebook Comment, iframe (Youtube, Google Maps), Tawk.to, …

Otherwise, it isn’t recommended for scripts like tracking or analyzing user data such as Google Analytics, Facebook Pixel, Google Tag Manager, Crazy Egg, Google Remarketing Tag, ... Because applying this technique may cause recording data incompletely or inaccurately. You certainly won't want to miss this data, right?

However, even in the case you use tracking scripts, you still want to delay them, to increase the performance of the website. That will give you a better pagespeed score, better Core Web Vitals and as they're a ranking factor, it might help you rank better on Google.

Last words

Delaying the script execution method will help you optimize your website’s loading and increase page speed scores as well. There are many ways to increase the speed of websites; so, consider what is more suitable for you to use. If you cannot apply this method to your websites, you can read about other methods in this series.

If you have any questions, feel free to let us know in the comment section. Good luck!

Top Must-Read Blogs for Developers - P3 - JavaScript

Top Must-Read Blogs for Developers - P3 - JavaScript

Over the past 20 years, JavaScript has been the most popular programming language in the world. You can learn it quickly and apply it to various purposes, thus creating more opportunities for your career. That’s why we have selected the five best blogs about JavaScript in this series of top must-read blogs for developers. Maybe there will be at least an appropriate blog for you no matter what level you are at.

Continue reading "Top Must-Read Blogs for Developers - P3 - JavaScript"

How to Send GET and POST Requests with JavaScript Fetch API

How to Send GET and POST Requests with JavaScript Fetch API

It's a common task for JavaScript developers to send GET and POST requests to retrieve or submit data. There are libraries like Axios that help you do that with beautiful syntax. However, you can achieve the same result with a very similar syntax with Fetch API, which is supported in all modern browsers.

In this post, we'll use the Fetch API to create get() and post() function with a beautiful syntax, much better than the default syntax provided in the Fetch API. We also improve the request performance with a simple caching and we'll take a look at how to use fetch requests with the WordPress REST API. Let's dive in!

JavaScript Fetch API: create GET, POST requests

Why using Fetch API instead of Axios?

Although you can import an external library like Axios to make get and post requests, using the native Fetch API has some benefits:

  • It's native and supported by all modern browsers, no polyfill is needed. You don't have to install an external library and thus, reduce the built file size.
  • It's promise-based, which allows you to use modern async/await syntax for handling asynchronous operations. This makes your code more readable and maintainable.
  • The Fetch API is a web standard, so it's consistent across different browsers. Axios, on the other hand, is a third-party library, and you might need additional configuration or polyfills to ensure consistent behavior across browsers.

Most people love Axios because of its beautiful syntax. But do you know that you can achieve the same thing with just a little code? Let's do that!

Sending Requests with Fetch API

To send a GET request with Fetch API, use the following code:

fetch( 'https://domain.com/path/?param1=value1&param2=value2' )
    .then( response => response.json() )
    .then( response => {
        // Do something with response.
    } );

To send a JavaScript POST request, use the following code:

const params = {
    param1: value1,
    param2: value2; 
};
const options = {
    method: 'POST',
    body: JSON.stringify( params )  
};
fetch( 'https://domain.com/path/', options )
    .then( response => response.json() )
    .then( response => {
        // Do something with response.
    } );

You can see the main difference between GET and POST requests is how the parameters are passed to the fetch call. In most cases, developers expect to pass an object of parameters and send requests in a beautiful syntax like this:

const params = {
    param1: value1,
    param2: value2; 
};

const response = get( url, params );
// or
const response = post( url, params );

To do that, we need some code to transform the original code with fetch to the new syntax.

Creating get and post Functions

Because the codes that send requests are similar between GET and POST, we'll create a common function request to make a request first. And then use it to create get and post functions like this:

const request = ( url, params, method ) => {
    // All logic is here.
};

const get = ( url, params ) => request( url, params, 'GET' );
const post = ( url, params ) => request( url, params, 'POST' );

Now it's time to build the request function.

Note that for each function (get or post), we have different ways to construct parameters: they're in the URL for GET, and in the body for POST. Thanks to URLSearchParams we can transform an object to a query string for the GET request.

Here is the first version:

const request = ( url, params = {}, method = 'GET' ) => {
    let options = {
        method
    };
    if ( 'GET' === method ) {
        url += '?' + ( new URLSearchParams( params ) ).toString();
    } else {
        options.body = JSON.stringify( params );
    }
    
    return fetch( url, options ).then( response => response.json() );
};

const get = ( url, params ) => request( url, params, 'GET' );
const post = ( url, params ) => request( url, params, 'POST' );

The above code returns a promise, and you can use it in your app like this:

get( 'https://domain.com/path', { param1: value1, param2: value2 } )
.then( response => {
    // Do something with response.
} );

You can see it in action on CodeSandbox.

Caching Requests

One problem developers usually need is caching requests, to avoid sending the same request multiple times.

To implement caching, we can create an object to store the data and use it to return the data earlier:

let cache = {};
const request = ( url, params = {}, method = 'GET' ) => {
    // Quick return from cache.
    let cacheKey = JSON.stringify( { url, params, method } );
    if ( cache[ cacheKey ] ) {
        return cache[ cacheKey ];
    }

    let options = {
        method
    };
    if ( 'GET' === method ) {
        url += '?' + ( new URLSearchParams( params ) ).toString();
    } else {
        options.body = JSON.stringify( params );
    }
    
    const result = fetch( url, options ).then( response => response.json() );
    cache[ cacheKey ] = result;

    return result;
};

WordPress REST API

As a WordPress developer, I usually work with the WordPress REST API. While the code above works fine in a general JavaScript app, it needs some changes to work in WordPress.

To send a request to the WordPress API, you need to authenticate the request. Also, the URL for REST requests must contain the WordPress base URL. Here is the updated code:

let cache = {};
const request = ( url, params = {}, method = 'GET' ) => {
    let cacheKey = JSON.stringify( { url, params, method } );
    if ( cache[ cacheKey ] ) {
        return cache[ cacheKey ];
    }

    let options = {
        method,
        headers: { 'X-WP-Nonce': MyApp.nonce }, // Add nonce for WP REST API
    };

    // Setup the rest base URL for requests.
    url = `${ MyApp.restBase }/${ url }`;

    if ( 'GET' === method ) {
        const query = ( new URLSearchParams( params ) ).toString();
        if ( query ) {
            url += MyApp.restBase.includes( '?' ) ? `&${ query }` : `?${ query }`;
        }
    } else {
        options.body = JSON.stringify( params );
    }
    
    const result = fetch( url, options ).then( response => response.json() );
    cache[ cacheKey ] = result;

    return result;
};

To send restBase and nonce to JavaScript, we need to use the wp_localize_script function as follows in your plugin or theme PHP file:

wp_enqueue_script( 'my-app', plugin_dir_url( __FILE__ ) . 'js/app.js', [], '1.0', true );
wp_localize_script( 'my-app', 'MyApp', [
    'restBase' => untrailingslashit( rest_url() ),
    'nonce'    => wp_create_nonce( 'wp_rest' ),
] );

After that, you can make requests like this:

get( 'my-namespace/my-endpoint', { param1: value1, param2: value2 } )
.then( response => {
    // Do something with response.
} );

Conclusion

This post shows you how to make basic GET, POST requests in JavaScript with the Fetch API. It also shows you how to make requests for the WordPress REST API. With little code, we can have a beautiful syntax like in other libraries. You can use this method in your general JavaScript app or in a WordPress plugin. In fact, we use it in our plugins like Meta Box Builder, MB Views, Slim SEO Schema, and Slim SEO Link Manager.

I also wrote an article about modernizing JS code (improving and modernizing a large JavaScript codebase). So if you're interested, you can read it to have a better code.

Happy coding!

How to Remove Unused CSS and JavaScript Files in WordPress

How to Remove Unused CSS and JavaScript Files in WordPress

Website owners and developers as well usually care about improving the website’s loading speed. One of the most effective techniques to do that is removing the unused CSS and Javascript files. This execution is quite simple. We are going to show you how to find unused CSS and JS files, and then clean up CSS and JS with a dedicated plugin or a self-created plugin in WordPress.

Continue reading "How to Remove Unused CSS and JavaScript Files in WordPress"

How to Add Custom JavaScript Actions Using Button Field with Meta Box

How to Add Custom JavaScript Actions Using Button Field with Meta Box

In WordPress, there are only default functional buttons on the backend to do some actions like submitting posts or adding categories. Do you want to add other custom functional buttons to make your management much easier? Today, we’ll find a way to add custom JavaScript actions using the Button field with Meta Box in the most convenient way.

Continue reading "How to Add Custom JavaScript Actions Using Button Field with Meta Box"

Modernizing JavaScript Code in WordPress

Modernizing JavaScript Code in WordPress

I’ve just had a nice experience improving and modernizing a large JavaScript codebase in a WordPress plugin. The original code was written in an old-fashioned way with jQuery in a single large file. Using modern EcmaScript and tools like Webpack, I was able to split it into modules and improve the code structure. The new code is much more readable and maintainable, and of course, fewer bugs. In this tutorial, I’ll show you how I did that.

Continue reading "Modernizing JavaScript Code in WordPress"