24. August 2015

Optimizing your sites image performance in Drupal

As a developer you can do everything in your power to make your site really slim & fast but when you hand it to the client they could still mess it up in many ways. There are a plethora of things you need to do to keep this from happening, like handling uploaded images better.

I'm able to accomplish this for our clients with a couple very simple modules that you should be using on most (if not on all) of your sites, they are:

Picture & Breakpoints

These two modules work together to handle responsive images. The picture module uses Picturefill to do it's magic. If you don't know about Picturefill it is a polyfill that allows you to use the Picture element today even though only Firefox, Chrome (+ Android Browser) & Opera support it as of writing this.

Setting up these modules is pretty straightforward:

  1. Enable Breakpoints & Picture
  2. Set up your breakpoints by going to /admin/config/media/breakpoints.
    • These are setup just like CSS breakpoints and look like @media(min-width: 640px) Image Breakpoints setup
  3. Configure your new Image Styles breakpoints just made for you.
    • If you breakpoint is a max width of 600px you should scale your image to at max that width.
  4. Edit your display on the content you want to use responsive images to use the Image with sizes format instead of just standard Image. Image with Styles as an option
  5. Then you'll have to choose your sizes which will look like this: (min-width: 0px) (min-width: 640px) (min-width: 1025px) (min-width: 1441px).
  6. Under that you choose which Image Styles you'd like to use. You'll want to choose the ones that breakpoints created for us based on the breakpoints you made.
  7. Choose a fallback image size. I have been using my mid size pictures that are at max ~900px wide. I personally feel like that's large enough it should work for people as a fallback even if it's a little pixelated, that's gotta be better than a 1MB image.
    • When all said and done it should look like this: Image with Styles settings finished
  8. Now when you go to your content it should be switching images based on screen size.
Image API Optimize

Image API Optimize lets you modify the default Drupal image optimization settings. You can choose your compression method and compression amount for your images. This is all helpful things, but there is a patch out there that lets you use this module with TinyPNG. If you've never used Tiny PNG, let me just say it's magic and will make your PNGs crazy small.

Once you have patched and enabled Image API Optimize you will have the options to choose which service you want to use. You can now choose TinyPNG

TinyPNG as option for compression

Once you have that setup you will need to clear your image-cache using drush drush image-flush --all. Then the next time you hit a page with an image it will take a minute because it needs to go out can compress these images, but you should notice they're significantly smaller like 60% smaller at times. Now you don't need to worry about your clients uploading so many PNGs because they need transparencies.

With that very small amount of work we have significantly future proofed the performance of your client's site by making sure all user uploaded pictures are handled properly.

:wq

16. July 2015

Ultimate Tic-Tac-Toe Game

This is a follow up to my P2P Tic-Tac-Toe game I made the other week. In that post I mentioned I was working on a better version of the game and now it's here!

I put this up on CodePen and on this site under my demos and the most up to date version (which at the time of writing the AI is currently broken) is up on GitHub. You can play the game with a friend below!

 

See the Pen Ultimate Tic Tac Toe P2P by Josh Fabean (@fabean) on CodePen.

 

Cool things I'm currently working on is getting a server running to do match making, and making the AI smarter. I feel like with enough rewriting & wizardry I can get the AI unbeatable.

Thanks so much for playing my game I hope you liked it!

:wq

08. July 2015

JavaScript P2P Tic-Tac-Toe

This is a follow up to my P2P chat program I made the other month. I've now morphed it into a game of Tic-Tac-Toe!

Like usual I threw it up on CodePen so you can dig through the code and see how I did it. It was simple and I did most of it in a day or two. The big thing I want to figure out are match-making or at least easier way to connect to your friends.

 

See the Pen Multiplayer Tic Tac Toe Web RTC by Josh Fabean (@fabean) on CodePen.

 

Hope you enjoyed it. I will let you know this was all just an entry into me working on an Ultimate Tic-Tac-Toe game which I've already started and it works beyond knowing when you win and where your next move needs to be.

:wq

30. June 2015

Better Performance With Drupal

Your site's performance is bad, and you should feel bad

When you build a site with Drupal if you don't do it right your users are going to have a bad time. Drupal, like every CMS, when not properly tamed can be slow and use tons of bandwidth. It's 2015, I shouldn't have to explain to you why performance is important and why you should care about it.

There's lots of great things you can and should do to optimize performance. Using these modules you will be able to make your site fast and save your users money on their data bill.

Modules I'm using

Module I've used or heard of and cannot completely give my stamp of approval

In a little over two hours configuring the modules listed above, I was able to gain large performance increases on a very simple site. File size dropped from 985KB to 382KB, speed from 6.67s to 299ms. This was all running locally so I wasn't even using things like Memcache or Varnish which I would suggest for any production site.

alt text

Please be a responsible developer or designer and make websites that perform, no one wants to wait for a site. You absolutely cannot overdue performance! Thanks for helping to make the world a better place.

:wq

11. June 2015

My Grunt.js Boilerplate

The other day I was starting a project and I was to the point where I was needed to create my grunt file and move on with coding the project. The project was my Javascript Chat using WebRTC in case you were wondering. I started pulling from old projects and mashing together a grunt file to my liking for this project. When it was all said and done I ended up spending a good 30 minutes to a hour to get it all worked out working, what a waste of time! Right then I knew I needed to come up with a better solution.

I ended up creating a simple to use grunt boilerplate that I'm going to use when I start all my projects. I plan on this boilerplate being an ever changing thing as needs change and I come up with cool ways to do things. I threw my Grunt Boilerplate on GitHub so you can check it out and use it all you want. There's a how to use there also so I won't waste your time here with that. But I will explain some of the cool tasks it runs.

Tasks in Gruntfile

  • time-grunt: This adds awesome graphs to your grunt builds, what more could you want?
  • load-grunt-tasks: This saves you from having to include grunt.loadNpmTasks('grunt-babel') for each task used.
  • grunt-autoprefixer: This prefixes your css so you can forget adding -webkit- to all your fancy css
  • grunt-babel: Write ES6 code and beyond today and have it compiled down to ES5 so it works in today's browsers.
  • grunt-contrib-connect: While grunt is running you can access your site on 127.0.0.1:9001 saving you time of setting up a local server for each little project.
  • grunt-contrib-jade: Write jade and have it compiled to HTML.
  • grunt-contrib-jshint: run jshint to check your code for errors on build.
  • grunt-contrib-sass: Write sass (pretty self explanatory what this is for and why you need it).
  • grunt-contrib-uglify: you need to compress your JS before you run it in the wild, performance matters punk.
  • grunt-contrib-watch: Watch lets you re-run grunt on each file save.

A couple of things I want to add shortly are:

  • Switch to PostCSS instead of sass.
  • Switch to eslint instead of jshint.
  • Put this in something like Yeoman to make it easier for other people to pick this up and fit their workflow.

So there it is, this is going to save me a lot of time in the future I hope it does for you too. Thanks

:wq

25. May 2015

Chat App Written in Javascript Using WebRTC

Today Nathan Phelps and I decided we would play around with WebRTC to try to do some fun p2p things.

After awhile of playing around we ended up being able to successfully make a p2p chat web app. You can check out javascript-p2p-chat on GitHub. It was written using PeerJS which made it quite easy actually, we spent most of the time rendering it out to the page and making it semi user friendly.

I actually decided to host an working example of it on my site so feel free to play around with it but you'll need to open two browsers or find a friend.

This is still very much a work in progress, I was just too excited to not share with the world.

You will need a browser that supports WebRTC to use this.

alt text

20. May 2015

Drupal Background Image Field Formatter

Ever ran into the issue on Drupal where you want the user to create a piece of content, but the image they upload needs to be a background image so you can do something like background-contain? I ran into this issue last week multiple times while building out the new Code Koalas site[^1]. The first couple of times we just created a custom field template that looked like this:

<?php foreach ($items as $delta => $item): ?>
  <div class="project-image" style="background-image: url(<?php print file_create_url(image_style_path('half_page_image', $item['#item']['uri'])); ?>)"></div>
<?php endforeach; ?>

There's nothing wrong with the above approach, but it seemed repetitive to do the same thing over and over again each time we needed this, because of our designer we needed this a lot. That's when I started thinking maybe there was some sort of module creating a new field type, but then I realized it just needed to be a field formatter for the image field. That's when I found the module Background Image Formatter, but that only lets you use that image and attach it to a css selector. That's not what I needed, I needed a div that was the background image. That's when I'd like to say I found the module I really needed, Simple Background image formatter, but I didn't find that module until I have completely recreated that module myself[^2].

The module Simple Background image formatter, is fantastic! It does exactly what I needed, it removes the need for tons of custom field templates.

Once you have the module installed, go to your display settings for your content type, on your image field open the formatter options:

alt text

Once you do that, you'll want to edit the settings to make sure you're adding the classes you like.

alt text

You can choose your image style, whether to output as CSS or an inline style on a div, and put css classes on your div. I also am using Display Suite and I choose expert template mode, and leave it blank. I do this because otherwise this div you're making will be wrapped in another div, and that isn't want I wanted.

Once you do all that here is the final results!

alt text

Now you can make background images a breeze with Simple Background image formatter.

[^1]: Site isn't launched yet, sorry to disappoint. [^2]: I seriously created the exact same module by myself, that guy beat me by one month.

08. May 2015

JavaScript ES6 for-of vs for-in

Looping in javascript is the best thing ever and I do it all day everyday. I just stumpled upon some of the new ES6 iterators and one stuck out to me a lot. It's called the for-of loop and it much like to a for-in but with one major improvement.

The syntax for both are the same, as shown below:

//ES5
var myArray = ['cheddar','provolone','swiss','parmesan'];
for (var value of myArray) {
  console.log(value);
}

//ES6
let myArray = ['cheddar','provolone','swiss','parmesan'];
for (var value in myArray) {
  console.log(value);
}

Okay, easy enough so what is the difference right? The difference is in the output.

var myArray = ['cheddar','provolone','swiss','parmesan'];
for (var value of myArray) {
  console.log(value);
  // outputs 1,2,3,4
}

let myArray = ['cheddar','provolone','swiss','parmesan'];
for (var value in myArray) {
  console.log(value);
  // outputs 'cheddar','provolone','swiss','parmesan'
}

Do you get the difference? I've always been writing console.log(myArray[value]) to output what for-in outputs out of the box. It's not so life changing change, but it sure is welcomed by me and I appreciate the couple keystrokes this will save me.

Edit May 19, 2015: I did find one thing that might be bad/weird about the for-in loop. It's just a reference to the value and cannot be used to modify the original array.

25. April 2015

Initial Thoughts on PostCSS

Lets just use JavaScript for EVERYTHING!

Earlier today I found out about PostCSS, now my life is forever changed?

Very frequently do I complain about just how slow ruby Sass is (sometimes taking a whole 1s to compile a website's CSS... our definition of slow is just silly these days), but libsass is always behind and missing the cool kid features. This is where PostCSS comes in.

It's not meant to be a Javascript version of Sass like how libsass is a C++ version of ruby Sass, it's a completely different thing. At it's core it's just a CSS parser written in Javascript which people have written plugins for that give it Sass like features. This is the line that got me,

PostCSS can do the same work as preprocessors like Sass, Less, and Stylus. But PostCSS is modular, 4-40 times faster, and much more powerful.

4-40 Times faster... wow!

I immediately started reading the docs and playing with it. I even went so far as to making an example/tutorial and threw it up on github.

I used grunt to compile out my CSS, I tried straight from the command line and it didn't work after 2 tries so I switched to grunt as that's how I'd do it for real anyways.

Here's a snippet of my gruntfile.js

postcss: {
  options: {
    map: false,
    processors: [
      require('postcss-import')(),
      require('postcss-simple-vars')(),
      require('postcss-simple-extend')(),
      require('postcss-nested')(),
      require('postcss-media-minmax')(),
      require('postcss-merge-rules')(),
      require('postcss-discard-comments')({removeAll: true}),
      require('autoprefixer-core')({browsers: 'last 2 version'}).postcss,
      // require('csswring').postcss,
    ]
  },
  dist: {
    files: {
      'dist/styles.css': 'src/all.css'
    }
  }
}

You just add in all the plugins you want to run. Worth noting, order is important as that's the order they'll run in. One plugin said it needed to run before postcss-nested as running it after caused some issues. So far simple enough I think. I've left csswring commented out as it's a minifier and I think that isn't best practice when giving examples of what it does to the CSS when it's basically unreadable as minified.

After that you write CSS just like you would write Sass and it just sort of works. A couple things that were different were:

  • on @import you must include an _ if your filename starts with one.
  • cannot use file extension of .scss which caused some highlighting issues
  • @extend didn't work the way I thought it would (I rarely use extends in real life though)
  • comments must be in /* comment goes here */ format, // here is my comment won't get removed properly.
  • postcss-merge-rules sort of worked. I think it's an issue with nesting. It worked on my h1 tags, but not on one that had nesting on it.

I'm sure I've missed a ton of things, and if you know of cool things worth trying out or you see why things didn't work right for me let me know. I'm excited to keep playing with PostCSS!

24. April 2015

Sticky Bar With CSS Popup Animation

I was tasked with making a Google Adwords landing page for our company. Our designer Alex Benson decided he wanted a contact form to stick to the bottom of the page and popup when you click it.

 

See the Pen Sticky contact bar with popup animation by Josh Fabean (@fabean) on CodePen.

 

You can poke around the code yourself but I'll break down the main thing I did to accomplish this.

First there is the easy part, I did a couple CSS animations.

.fadeout {
  opacity: 0;
  transition: opacity 1s ease;
}
.fadein {
  opacity: 1;
  transition: opacity 1s ease;
}
.contact {
  position: fixed;
  bottom: 0;
  margin-bottom: 0;
  padding: 10px 0;
  width: 100%;
  height: auto;
  transition: all 400ms cubic-bezier(0, 0, 0.32, 1.50);
}

I was able to do that crazy transition simply by playing with the new Chrome Dev tools easy popup thingy.

alt text

After getting the CSS out of the way all that was left was to adjust the height of that bar based on the content we need to show and the CSS animation should do the rest.

Here's the js, cut up to only show the important part

// get all our elements we're going to be playing with.
var contact = document.getElementById('sticky-contact');
var formEl = document.getElementsByClassName('with-form')[0];
var getStarted = document.getElementById('get-started');

// when you click the first button do this thing!
getStarted.addEventListener('click', function(){
  var initHeight = contact.scrollHeight; // quick grab the current height
  contact.style.height = initHeight + 'px'; // set that height on the element
  formEl.classList.remove('hide'); // show the next step
  var withForm = formEl.scrollHeight; // find what new height would be
  contact.style.height = (withForm + 20) + 'px'; // set that height on the element
  document.getElementsByClassName('initial')[0].classList.add('hide'); // hide the first section of the bar
}, false);

If reading that code isn't enough here is the written out version.

When you click the 'Get Started' button we first grab the current height of the sticky bar. We take that height and set that as the height of the element instead of just height: auto;. Take the part that will show next and remove the class of hide so now it's visible. Grab the height of that element, now reset the height of the sticky bar to the height of the next step. Finally we take the first step that we just clicked and hide that.

Doing that allows for the CSS animation to take over and animate the height giving us the cool effect.

Overall nothing crazy complicated here just a bunch of simple things put together to make a good end result.