0
\$\begingroup\$

On Pokemon Fusion, I found it annoying that the webpage didn't automatically update the tab URL to the permalink when the fusion is changed, so I decided to write a UserScript to do that.

After finishing that, I thought it would also be convenient to update the fusion whenever navigating through the site history as well.

// ==UserScript==
// @name         Automated Permalink
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  automatically synchronizes permalink to fusion
// @author       Patrick Roberts
// @match        http://pokemon.alexonsager.net/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    var image = document.getElementById('pk_img');

    window.addEventListener('popstate', function () {
        var match = location.pathname.match(/\/(\d+)\/(\d+)/);

        pokego(match[1], match[2]);
    });

    function updateHistory() {
        var prev = location.pathname;
        var next = image.src.replace(/.*(\d+)\/\1\.(\d+).*/, '/$2/$1');

        if (prev === '/') {
            history.replaceState(null, document.title, next);
        } else if (prev !== next) {
            history.pushState(null, document.title, next);
        }
    }

    image.addEventListener('load', updateHistory);
    updateHistory();
})();

I'd appreciate any feedback on improving perceived responsiveness for the feature this UserScript adds to the webpage.

I realize changing the URL after a slow image load within image.onload might make the URL change seem slow, but I also noticed that when calling history.pushState() or history.replaceState() within a listener to a.onclick or select.onchange events, it appeared to cause the fusion image to load significantly slower.

Though this UserScript still functioned properly either way, I'm curious if anyone can come up with an approach that improves responsiveness overall.

\$\endgroup\$
3
\$\begingroup\$

I'd appreciate any feedback on improving perceived responsiveness for the feature this UserScript adds to the webpage.

Since you are trying to synchronize the display of the image and the current URL of the page, this is almost entirely dependent on the image loading as quickly as possible, while eliminating any unnecessary calculations from your script.

First, let's attempt to optimize the script (as much as possible):

1. Use const instead of var

var image = document.getElementById('pk_img');
var match = location.pathname.match(/\/(\d+)\/(\d+)/);
var prev = location.pathname;
var next = image.src.replace(/.*(\d+)\/\1\.(\d+).*/, '/$2/$1');

Since you do not appear to directly change the values of these variables, you can use const instead of var:

const image = document.getElementById('pk_img');
const match = location.pathname.match(/\/(\d+)\/(\d+)/);
const prev = location.pathname;
const next = image.src.replace(/.*(\d+)\/\1\.(\d+).*/, '/$2/$1');

2. Unnecessary Title Parameter in replaceState and pushState

history.replaceState(null, document.title, next);
history.pushState(null, document.title, next);

Most browsers ignore the title attribute of these functions, so you can skip adding document.title as it's redundant:

history.replaceState(null, null, next);
history.pushState(null, null, next);

Next, let's improve the speed in which the image appears to the user:

Since this is probably going to be the most time-consuming event for the user, the image needs to be preloaded as early as possible.

You can achieve this effect by using the mouseover or mousedown events on the select or option elements to build the image path and fetch the image on your own to cache it before the website requests the resource from the server.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.