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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

production performance improvements #164

Open
wants to merge 41 commits into
base: master
Choose a base branch
from

Conversation

techieshark
Copy link
Contributor

Getting ready for having lots of real users, some of which may be in remote places with slow internet connections, the changes here do a few things:

  1. Eliminate the need for Handlebars.js and jQuery-UI, reducing network size by 36 KB and 46 KB, respectively. This is done by switching from Handlebars to Mustache (which comes with CartoDB), and switching to the Tiny Autocomplete library (only 2K).
  2. We use cleancss to minify CSS (and we concatenate it, so we reduce the number of file requests the client does). We use uglifyjs to concatenate and minify JS files. At the same time, we produce source maps so that when using Chrome or Firefox development tools to inspect the live site you'll still be able to debug it. The effect of this is less and smaller files sent across the network. See also Chrome documentation on source maps and HTML5Rocks intro to source maps.
  3. Reduce the amount of CSS we try to download before first page render. This is done by some asynchronous loading code which fetches things like the cartodb CSS. Look near the bottom of the index.html for that.

Other changes:

  • The commands to make all this happen are just in a makefile. Makefiles aren't super sexy but I'm hoping it'll be easiest to understand and get working in our environment.
  • There is a publish target which creates a gh-pages branch. So once we're ready to deploy, we just run make publish (first running git branch -D gh-pages if we had a gh-pages branch previously that we need to delete first).
  • You can run a production-like server by running make server. This is just the python HTTP server but includes gzip compression so you can see how large files will be when transferred across the network in a production-like environment.
  • some typos and small CSS invalid code fixed.
  • misc other changes and optimizations

Impact: At "Regular 2G" network speeds, we can drop DOMContentLoad time by half (note that first page render is actually around 3s).

older, slower page

^ Previous

new page

^ with these changes (look at "DOMContentLoaded" content in the bottom right).

Further improvement:

The biggest file we have to download before the user's browser can first render the page is the CartoDB JS library. It's large (165KB gzipped and minified), and combines it's own jQuery copy (which we can't use since that old version doesn't work with Bootstrap, so we have to also download a newer copy of jQuery). However, version 4 is coming (eventually) and appears to be more modular. This may allow us to eliminate the redundant jQuery download as well as just downloading a subset of it before page load, then downloading the remainder asynchronously after page load.

techieshark and others added 30 commits September 17, 2015 17:58
- Simulations in chrome developer tools show this changes download times
  from 2.2min and 2.0min to 1.4min and 1.3min for jquery-ui and handlebars JS files,
  on a GPRS (50Kbps) network speed, decreasing overall Load time from 2.8min to 2.4min.
- The custom jquery-ui download we used previously included components we didn't use
- This change reduces file size from 71.9kb for jquery-ui.min.js to 33kb.
  Chrome dev tools show a time reduction on a GPRS network (50Kbps) from 1.4 minutes to 50 seconds,
  reducing total Load time from 2.4 to 2.3 minutes.
- for bootstrap & cartodb, we're using CDNs
- for jquery-ui & handlebars, we're using the minified local version
- since we only have one jquery-ui file, it can be in vendor/ like all the others
- Makefile target compresses JS & CSS (`make uglify`) and exports to public/
- index.html references compiled JS & CSS
- js directory structure changed to make it easy to grab files in correct order
  (by the cunning use of the numbers 1, 2, and 3)
- git ignore files in public/
- this allows a better demo of what a performance server will give us
  and lets us better speed test for users on slower networks.

- from https://github.com/ksmith97/GzipSimpleHTTPServer,
  run via `python GzipSimpleHTTPServer`
- we also put all command options after the filenames as
  uglifyjs docs suggest. https://github.com/mishoo/UglifyJS2#usage
- comments are /* */, not //
- caught by CSSO (https://github.com/css/csso)
- reducing DNS lookups: https://gtmetrix.com/minimize-dns-lookups.html
- also reduces chance of failure due to external site
- we can load some CSS asynchronously because we don’t need it for
  the initial page render. This reduces the number of bytes we need to
  send for first render and will speed page load time.
- style sheets are more important for user than GA
- simplifies our custom CSS, makes layout more clear from HTML,
  reduces CSS duplication
- things not controlled by index.html left alone (leaflet controls, etc)
- can’t get directions from paper. We include address elsewhere.
- can’t click buttons in print
- to make async css changes work
- dropped from 114K of CSS,    35K of JS, to
                48K of CSS and 6.5K of JS.

Customized config can be found at

http://getbootstrap.com/customize/?id=4df4d577dfa8cc58c088
- combined/minified vendor.js reduced from 31KB to 23 KB
- we’re using Mustache now:
  Mustache is smaller, and comes packaged with CartoDB
  so we can just re-use that without requiring another download.
  Page now at 360 KB, 24 requests, down from 460 KB, 44 requests;
  DOMContentLoad in 1.7 seconds in DSL vs 2.6 seconds previously.

- further possible improvements:
  - Use SVG for site logo.
  - When CartoDB 4 comes out, it’ll include newer jQuery (which works
    with Bootstrap), so we’ll not need to be downloading jQuery twice.
  - When CartoDB 4 comes out, it’ll be more modular, so we might be able
    to just load core + sql api first (plus getting jQuery from CDN
    so users already have it) and then we wouldn’t block page render with
    the map stuff we don’t use until later.
  - find a way to minify CSS selectors across html,js,css. See:
    https://gist.github.com/twolfson/8117853
further improve performance by combining vendor and app javascript files
- reduce number of file transfers by one
- cleancss appears to produce the smallest files,
  and doesn’t have this issue that we
  discovered in CSSO:
  css/csso#251

  (That issue could be seen the “I’m looking for:” text - it became too small as you shrunk the page.)

- source: https://github.com/jakubpawlowicz/clean-css
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant