sphinx-book-theme icon indicating copy to clipboard operation
sphinx-book-theme copied to clipboard

Tie the theme to good design principles

Open chrisjsewell opened this issue 4 years ago • 12 comments

With my scholarly hat on, it would be nice to apply a bit of theory to the design. It feels mainly the theme is being designing based on "I like the look of that", which is not necessarily a bad thing, but it would be good to do some due diligence and documentation on how the theme applies to good design principles. Just googling "web page design principles" you get 1000s of results, and obviously there's no silver bullet, but some that start to crop up often are:

  • Simplicity and Visual Hierarchy: too many elements on the page can be distracting, the eye should be drawn to the most important
  • Consistency: in typographies and color pallete
  • F Pattern: Utilising eye tracking software, studies have identified that people tend to view computer screens in a ‘F’ shaped pattern. Meaning that users tend to focus on the left side of the screen and will only take in a few elements on the right side.
  • mobile first: its generally easier to design for the simpler mobile first, then add in features for desktop
  • Responsiveness/Load times

chrisjsewell avatar Aug 07 '20 19:08 chrisjsewell

I love this idea. Agreed - your assessment of "I like the look of that" is partially true though I've definitely drawn inspiration from some specific other themes and sites (most notably, git book and the tufte css guide)

choldgraf avatar Aug 07 '20 19:08 choldgraf

A few others that I have used:

  • Draw attention to the content. Find ways to "highlight" the center column of the page.
  • Mimic other modern book-like structures. Don't do anything too wacky that users aren't used to. Instead take inspiration from some of the modern book themes out there. Some inspiration:
  • Draw inspiration from publishing-specific design and elements
  • Following Tufte - think about "ink to information ratio". Don't use too many visual elements or colors if it isn't necessary. Use whitespace instead of visual spacers, don't add lots of shading and fancy boxes unless it really helps parse the content, etc.

choldgraf avatar Aug 07 '20 20:08 choldgraf

Responsiveness/Load times

Throttling myself to "Good 2G" speeds in Firefox's development tools, disabling cache and loading https://sphinx-book-theme.readthedocs.io/en/latest/ today takes... 59s to load the page. :o

The main culprits for this are:

Even without throttling, I can see that my browser waits for a bit downloading from unpkg.com before showing me the page.

pradyunsg avatar Aug 10 '20 15:08 pradyunsg

Here's the screenshot of the dev-tools (full screen, zoomed out to show all assets)

Screenshot 2020-08-10 at 8 47 55 PM

pradyunsg avatar Aug 10 '20 15:08 pradyunsg

Cheers, well thebelab we now "control": https://github.com/executablebooks/thebe, so could look if there is anything that could be optimized there.

chrisjsewell avatar Aug 10 '20 15:08 chrisjsewell

I think we should absolutely have a speed audit and optimize the low-hanging fruit. E.g. thebe and the widget JS are really only needed on certain pages, so I wonder if we could get away with only loading as-needed (or vendoring that JS if we think it could speed things up)

choldgraf avatar Aug 10 '20 21:08 choldgraf

Yep definitely should only add to pages that need it; I've wanted to work out a standard way to do that for some other sphinx extensions.

I also note that require and jupyter-widgets are not loaded asynchronously:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
    <script src="https://unpkg.com/@jupyter-widgets/html-manager@^0.18.0/dist/embed-amd.js"></script>
    <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <script async="async" src="https://unpkg.com/thebelab@latest/lib/index.js"></script>

I don't know if they should, or if it would make any difference? (if you want a refresher on asynchronous loading see https://flaviocopes.com/javascript-async-defer/#async-and-defer)

chrisjsewell avatar Aug 10 '20 23:08 chrisjsewell

One thing I still haven't figured out is how to make a JS / CSS bundle load only on some pages. To my knowledge the only way to do this (other than directly modifying a template file) is to use app.add_js_file, but this adds it for each page of the website rather than only specific pages. Is that the experience you've had as well?

choldgraf avatar Aug 11 '20 00:08 choldgraf

Using this theme with https://github.com/pradyunsg/sphinx-themes, gives the following loading times for the various pages. (image below)

Screenshot 2020-08-11 at 12 08 23 PM

This is actually decent, with the page at ~500KB and most of it coming from Bootstrap. I think there's still a strong case for better optimization, but looks like that is more of a sphinx-thebe issue in general, rather than something specific to this theme.

And, in case you're wondering why I brought up #148, here's the preview image generated for this theme (as of today) by the automation there:

image

pradyunsg avatar Aug 11 '20 06:08 pradyunsg

make a JS / CSS bundle load only on some pages ... other than directly modifying a template file

Not sure if this is what you already meant by template files, but you may possibly be able to do this via metadata and theming: https://www.sphinx-doc.org/en/master/templating.html

For example in https://github.com/executablebooks/meta/commit/dc88790f3993d1a3d97391cb884a5d9454831192, I only add the tabulator JS/CSS to a certain page, based on its docname. But if you could add metatags to certain pages via an extension, then you could also look for these

chrisjsewell avatar Aug 11 '20 13:08 chrisjsewell

here's the preview image generated for this theme (as of today) by the automation there:

Yeh I think another good principle is to "prefer HTML/CSS over JS", i.e. if you disable JS it shouldn't adversely affect the UI and/or disable "critical" UX features

chrisjsewell avatar Aug 13 '20 12:08 chrisjsewell

One thing I still haven't figured out is how to make a JS / CSS bundle load only on some pages. To my knowledge the only way to do this (other than directly modifying a template file) is to use app.add_js_file, but this adds it for each page of the website rather than only specific pages. Is that the experience you've had as well?

Recently found that you can use add_js_file on the builder, e.g. in an env-updated event only when certain criteria is met (see e.g. https://github.com/sphinx-doc/sphinx/blob/ae9f0dd29998a9985aea90777e92e03cf1c9d591/sphinx/ext/mathjax.py#L84)

edit: actually it is still for all pages 🤦 but at least you can stop the js in some cases

chrisjsewell avatar Aug 27 '20 22:08 chrisjsewell