Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting to 100/100 page speed score - Pre-index search #378

Closed
mscoutermarsh opened this issue Jul 10, 2020 · 1 comment
Closed

Getting to 100/100 page speed score - Pre-index search #378

mscoutermarsh opened this issue Jul 10, 2020 · 1 comment

Comments

@mscoutermarsh
Copy link
Contributor

I found a really nice potential improvement for Search that gets the pagespeed score to 100.

This solution is currently kind of hacky and may require node as a dependency (馃槩 ). When I have more time, I'll see if I can clean it up and submit a PR.

Current

Mobile: 72
Desktop: 99

What's slowing it down?

I looked into it and the page is basically perfect except for one thing.

On page load, the search data is loaded and an index is created. The index creation is a bit slow on mobile.

Creating the index is generally really fast in lunr. Unless you're on a slower mobile device. Then it blocks the page for ~1 second.

Here is what it looks like on my MBP in Chrome

The fix

With lunr you can pre-generate the index.

So I hacked together a little script that does this. I currently manually run this before deploying.

// Pre generate the index and drop it in the assets folder
var lunr = require('./assets/js/lunr.js');

const fs = require('fs');
let rawdata = fs.readFileSync('_site/assets/js/search-data.json');

var documents = JSON.parse(rawdata)

var idx = lunr(function () {
  this.ref('id');
  this.field('title', { boost: 200 });
  this.field('content', { boost: 2 });
  this.field('relUrl');
  this.metadataWhitelist = ['position']

  Object.keys(documents).forEach(function (key) {
    this.add({id: key, title: documents[key].title, content: documents[key].content, relUrl: documents[key].relUrl})
  }, this)
})


callback = function(err){
  if(err) throw err;
}

// We put the index and docs in the same file
var output = { docs: documents, index: idx }

fs.writeFile('assets/js/search-index.json', JSON.stringify(output), 'utf8', callback);

Then in just-the-docs.js. Change initSearch() to this.

function initSearch() {
  var request = new XMLHttpRequest();
  request.open('GET', 'assets/js/search-index.json', true);

  request.onload = function(){
    if (request.status >= 200 && request.status < 400) {
      var searchData = JSON.parse(request.responseText);
      lunr.tokenizer.separator = /[\s\-/]+/
      var index = lunr.Index.load(searchData["index"])
      var docs = searchData["docs"]

      searchLoaded(index, docs);
    } else {
      console.log('Error loading ajax request. Request status:' + request.status);
    }
  };

  request.onerror = function(){
    console.log('There was a connection error');
  };

  request.send();
}

After

Score: 馃挴 for both mobile and desktop.

This is on https://docs.htmlcsstoimage.com.

@mattxwang
Copy link
Member

Going back and triaging open issues. I appreciate you putting in work for this, but I think for now this is out of scope of this theme - I don't forsee us adding node hooks to the core theme outside of developer tooling for us (ex Stylelint, Prettier), since that goes against the theme's design principles/out-of-the-box work.

If you have a different approach, feel free to reopen this issue or submit a PR. Nevertheless, great work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants