slides-front-end-build-stack



slides-front-end-build-stack

0 0


slides-front-end-build-stack

Single page site front-end build stack

On Github RiaanBurger / slides-front-end-build-stack

Single Page Build Stack

My Summer Holiday

  • Only quiet time in the year to really learn.
  • 20-hour work/learn days cycling through the day/night.

Two Notable Accomplishments

  • Scripted our server configurations with Ansible.

    • Now in version control.
  • Advanced Gulp build automation familiarity.

Gulp to build Burtronix.co.za

  • Single-page
  • Easily Extendible (Several Upcoming Ideas)
  • Last a Few Years
  • Low on Maintenance
  • Paints and Doesn't Draw where possible.

Gulp to build Burtronix.co.za

  • As online now:

    • single download
    • lazy-load video background
  • Currently being developed:

    • Angular elements
    • Interactive 3D models
    • 14kb first-load

Typical Basic HTML Page

Elements:

  • Marked-up Contents
  • Style
  • Media Assets
  • Client-side Scripting

Typical Basic HTML Page

Separate Files:

  • Marked-up Contents as HTML in index.html
  • Style as CSS in style.css
  • Media Assets as (among others) images (SVG, PNG, JSPEG)
  • Client-side Scripting as JavaScript in script.js
  • HTML links to the separate assets.

Typical Basic HTML Page

Process of Fetching:

  • Browser URL ➜ DNS ➜ Request ➜ TCP Packets return HTML
  • HTML contains URLs of Separate Assets
    • URL ➜ DNS ➜ Request ➜ TCP Packets return Asset

Typical Basic HTML Page

Inline Elements:

  • CSS, JS and SVG can be inline directly in HTML
  • PNG, JPEG, ICO etc. can be base64 encoded inline in HTML

Site Build

The Things You Should Do

  • Like Tableless Design and Clean Paths in the 90s
  • Like Responsive Design more recently
  • These are the things you should tend to 100% of the time now

Site Build

Image Optimisation

  • Often online tools like
    • TinyPNG and
    • Compressor.io (SVG, JPEG)

Site Build

Base64 Encode Assets: How & Why

  • Online Base64 Converters like base64-image.de
  • You can Inline Assets in HTML and in CSS.
  • You can Inline CSS with Inline Base64 Assets.

  • When to use Base64:

    • Base64 is Larger.
    • GZipped Base64 only Marginally Larger.
    • Inline Base64 not Downloaded Concurrently.
    • Inline Base64 in HTML not Cached for Multi-page Sites.

Site Build

Base64 Encode Assets: When Not

  • So skip Base64:
    • for below-the-fold, large assets.
    • for assets inline in HTML for multi-page sites.
    • for SVG which should rather be inline.

Site Build

Base64 Encode Assets: Example

Example Asset:

<img src="image.png" />

Example Base64:

<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmN..." />

Site Build

CDN Assets

  • You can use a CDN without setting one up!
  • Common Assets available on CDNs:
    • JQuery (and Mobile)
    • Bootstrap
    • Angular
  • Separate Assets on CDNs can be:
    • More Locally Served
    • May be Cached

Site Build

CDN Assets: Why Not

  • Privacy: Yours and Your Site Users'
  • Privacy Extensions (now used by millions)
    • Examples: RequestPolicy (Firefox), uMatrix (Chrome, Opera)
    • High-impact Users
      • Site may be okay to lose small, shrinking % IE6 users.
      • Site may not be okay to lose % growing top-end users.
  • Can be slower if not cached and new DNS lookup needed.
  • Won't be available for off-line use (such as for off-line slides).

Site Build

Minify HTML, CSS and Uglify JS

  • As opposed to well-formatted source
  • It is smaller, so faster to download

Site Build

Minify HTML

Example HTML:

<a itemprop="email" title="E-mail Riaan Burger" href="mailto:riaan.burger@burtronix.com">
  riaan.burger@burtronix.com
</a>

Example Minified:

<a itemprop=email title="E-mail Riaan Burger" href=mailto:riaan.burger@burt↵
ronix.com>riaan.burger@burtronix.com</a>

Site Build

Minify CSS

Example CSS:

#logo a {
  display: block;
  overflow: hidden;
}
/* line 97, /home/riaan/.../burtronix.co.za/app/styles/style.scss */
#logo a img {
  display: block;
  margin: 0 auto;
  width: 100%;
  max-width: 600px;
}

Example Minified:

#logo a{display:block;overflow:hidden} #logo a img{display:block;margin:0 a↵
uto;width:100%;max-width:600px}

Site Build: Uglify JavaScript

Example JavaScript (75 Lines with Comments):

Example Uglified:

"use strict";!function(){function g(a,b){a.classList?a.classList.add(b):a.c↵
lassName+=" "+b}function h(a,b){a.classList?a.classList.remove(b):a.classNa↵
me=a.className.replace(new RegExp("(^|\\b)"+b.split(" ").join("|")+"(\\b|$)↵
","gi")," ")}function i(){return f||(f=!0,setTimeout(function(){f=!1},50),e↵
=!e,e?(g(a,d),h(a,c)):(g(a,c),h(a,d))),!1}var a=document.getElementsByTagNa↵
me("body")[0],b=document.getElementById("menu"),c="menu-opened",d="menu-clo↵
sed",e=!0,f=!1;b.onclick=function(){i(b)},b.onTouchStart=function(){i(b)}}(↵
);

Site Build

Inline CSS and JS in HTML

Example Inline Minified CSS in HTML <head>:

<style type="text/css">@font-face{font-family:Lato;font-style:normal;font-w↵
eight:700;src:url(data:application/x-font-ttf;base64,d09GRgABAAAAAIw4ABEAAA↵
...
ckground video{display:block;position:fixed;right:0;bottom:0;min-width:100%↵
;min-height:85%;width:auto;height:auto;z-index:-100}</style>

Example Inline Uglified JS in HTML <body>:

<script>!function(e,t){"object"==typeof module&amp;&amp;"object"==typeof mo↵
dule.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)t↵
...
ct=function(t){return e.$===Z&amp;&amp;(e.$=Mn),t&amp;&amp;e.jQuery===Z&amp↵
;&amp;(e.jQuery=Rn),Z},typeof t===kt&amp;&amp;(e.jQuery=e.$=Z),Z});

Site Build

All Together

  • Results in one single very long line of HTML.
  • Would you really want write this by hand?
  • Automation and Authoring Performance Next:
    • Authoring Tools
    • Automated Build Stack

Authoring Tools

"But wait, there's more!"

Authoring Tools

Faster HTML with Emmet

Example: Nesting

Example: HTML5

Authoring Tools

Faster, More Powerful

CSS with Sass (libsass)

  • libsass is much faster than Ruby's Sass
  • libsass doesn't have Ruby as a dependency
  • Sass compiled to CSS

Example Sass:

$light_grey:                  darken(white, 5%);
$dark_grey:                   darken(white, 60%);
...
body {
  background:                 $light_grey;
  color:                      $dark_grey;
  font-family:                $font-family;
}
a { @include($primary, $secondary); }

Authoring Tools

Faster, Briefer, Cleaner

JavaScript with CoffeeScript

CoffeeScript compiles to JavaScript

function gcd(x, y) {
  var z
  do {
    z = x % y
    x = y
    y = z
  } while (y != 0)
  return x
}

JavaScript (above) in CoffeeScript (below):

gcd = (x, y) ->
  [x, y] = [y, x%y] until y is 0
  x

Authoring Tools

Linting

  • Linting automatically reports problems with your source
  • Command Line Tools for:
    • SCSS, CSS, CoffeeScript, JavaScript, HTML, Drupal PHP...
  • Can run "live" in your editor, like Sublime Text, PHPStorm
  • Get used to Drupal standards with:
    • DrupalCS
    • ESLint RC file with Drupal 8

Authoring Tools

Custom JavaScript Libraries

  • You can and should customise some JavaScript libraries:
    • include just the functionality you need
    • turns out to be much smaller
  • Examples:
    • Modernizr
    • JQuery (&UI)

Authoring Tools

Testing

  • Test often
  • Examples (we'll cover further in Burtronix Training):
    • End-to-end Testing
    • Unit Testing
    • Code Coverage

Site Building

and

Authoring Tools

Do you really want to do all this manually?

No way! Let's automate!

Gulp

  • Gulp is a Node.js Build Automation Tool
  • It takes your clean, fast and easy source
  • Lints, tests and optimises it
  • Assists in development work-flow automation
  • Compiles it for production
  • Runs from the command line

Gulp

gulpfile.js

  • Is a JavaScript file
  • Describes all the tasks you want to automate
  • Depends on Node.js packages which contains all the complexity

Example task to clean (delete) some directories:

gulp.task('clean', function (cb) {

  $.del(['build', 'temp', 'serve'], cb);

});

Gulp

package.json

  • Describes your Node.js project
  • Including development dependencies that Gulp will use

Example excerpt:

"devDependencies": {
  "browser-sync": "^1.9.0",
  "del": "^1.1.1",
  "gulp": "^3.8.10",
  "gulp-autoprefixer": "^2.1.0",
  "gulp-cached": "^1.0.2",
  "gulp-cat": "^0.3.2",
  "gulp-changed": "^1.1.0",
  "gulp-concat": "^2.4.3",
  ...

Gulp

Packages

A selection of Gulp packages you may use to compile the tasks you want to automate:

Gulp: Node Packages

  • Some file operations:
    • del: Delete files, folders... globs.
    • mkdirp: Recursively mkdir, like mkdir -p.
    • gulp-rename: Renames files.
  • Example:
gulp.src("./src/main/text/hello.txt")
  .pipe(rename("main/text/ciao/goodbye.md"))
  .pipe(gulp.dest("./dist"));

Gulp: Node Packages

  • gulp-cat: Like cat in bash.
  • Example:
gulp.task('burtronix', function(cb) {
  return gulp.src('burtronix')
    .pipe(gulpCat(), cb);
});
       ______
      //   ) )
     //___/ /            __    __  ___  __      ___       __     ( )
    / __  (   //   / / //  ) )  / /   //  ) ) //   ) ) //   ) ) / / \\ / /
   //    ) ) //   / / //       / /   //      //   / / //   / / / /   \/ /
  //____/ / ((___( ( //       / /   //      ((___/ / //   / / / /    / /\

Gulp: Node Packages

  • Some early extras:
    • gulp-help: Present help for users of your gulpfile's tasks.
    • gulp-if: Conditional control structures.
    • gulp-load-plugins: Loads all your gulp plugins, to, for eg. $ var.
  • Example:
gulp.task('burtronix', function(cb) {
  return gulp.src('burtronix')
    .pipe($.cat(), cb);
});

Gulp: Node Packages

  • Some JS and CSS:

    • gulp-eslint: Lint your JavaScript (can be Drupal 8 standards).
    • gulp-uglify: Uglifies your JavaScript.
    • gulp-sass: Compile your Sass to CSS.
    • gulp-autoprefixer: Adds browser vendor prefixes to your CSS.
    • gulp-concat: Concatenate files together.
  • Live Preview

    • browser-sync: Live-presents changes in your browser on save.

Gulp: Node Pacakges

  • Example custom build JS lib: Modernizr:
    • gulp-modernizr: Crawls through your project files, gathers up your references to Modernizr tests and outputs a lean, mean Modernizr machine.
gulp.task('modernizr', function() {
  gulp.src('./js/*.js')
    .pipe($.modernizr())
    .pipe($.uglify())
    .pipe(gulp.dest('build'))
});

Gulp: Node Packages

  • Minification of:
    • gulp-minify-css: CSS files.
    • gulp-minify-html: HTML files.
    • gulp-minify-inline: CSS (and Uglifies JS) that's inline.

Gulp: Node Packages

  • Optimize Images:
    • gulp-imagemin: Optimize images.
    • Comes with very basic defaults.
    • For optimal use, configure these additional plugins carefully:
      • imagemin-advpng
      • imagemin-jpeg-recompress
      • imagemin-mozjpeg
      • imagemin-optipng
      • imagemin-pngcrush
      • imagemin-pngout
      • imagemin-pngquant

Gulp: Node Packages

  • Base64 Encode:
    • gulp-css-base64: Assets referenced in CSS.
    • gulp-img64: Assets referenced in HTML.

Gulp: Node Packages

  • Check size on the go?:
    • gulp-gzip: GZips files.
    • gulp-size: Reports the size of files.
  • This is particularly helpful when you build for small loads.

Gulp: Node Packages

  • Optimize your Gulp tasks too:
    • gulp-filter: Subsets your glob file selections, can restore.
    • gulp-changed: Compares to dest and only passes changed.
      • Slow file system comparison, but works first run.
    • gulp-newer: Like gulp-changed, but supports many:1.
    • gulp-cached: Loads files in mem first time, then only passes changed.
      • Fast in-mem comparison, works only consecutive runs.
      • Good for many:1
    • gulp-remember: Recall all the in-mem files, even unchanged.

Gulp: Node Packages

  • Injection:
    • gulp-inject: Injects references into HTML.

HTML Source:

<head>
  <title>My index</title>
  <!-- inject:css -->
  <link rel="stylesheet" href="/src/style1.css">
  <link rel="stylesheet" href="/src/style2.css">
  <!-- endinject -->
</head>
  • Can inject anything you want.

What's Next

  • I'll probably forget 50% if I don't use it continually
  • This is not my "day-job" of managing the company
  • One only remembers with repetition
  • Transfer your knowledge fast so others help you remember ;-)

Next

14kb First Load

  • Create a new Gulp build stack
  • To Produce <= 14kb first-load site
  • Lazy-load additional assets optimally and in correct order

Next

Angular Widget (Top Sites)

  • Easy to add to the new extendible website
  • Andre and I working on the back-end in Node.js now
  • With router for additional data-heavy pages
  • Re-presents the top Drupal sites analysis from two years ago
  • Keeps the data current
  • Presents and integrates historic weekly data

Next

Pablo-Inspired 3D

  • Pablo the Flamingo
    • Maya and three.js
  • Already build Burtronix Logo as an early test model
    • Blender to model
    • three.js for web

Drupal

How can this be used with Drupal

  • Theme

    • We use gulp for live theme development in our websites
  • Mobile Apps

    • We use Gulp to automate mobile web apps we develop
    • Such apps often use a Drupal back-end

Thank You

  • Most of this stuff I didn't know a year ago
  • Wouldn't have if not for the JHB Drupal community
  • Thank you in particular, as relevant instigator, Ivan
  • Thank you in particular, as relevant co-worker, Andre
  • Thank you to:

Everyone attending and sharing at our meet-ups!

Drupal Associtation South Africa