bbc news

strategies

purpose


Discuss...

  • Refactoring existing code
  • Moving to Desktop
  • Review ideas for new strategies
  • Tooling

quick break down...


  • JavaScript
  • CSS
  • Sass
  • Components
  • GUTS
  • Cutting The Mustard
  • Proposal
  • What can we do right now?
  • Grunt
  • Questions that need answers
  • Summary

Javascript


Things to discuss:

  • Global AMD
  • DOM Ready
  • Code Smells

global amd


  • Scripts calling `require` before RequireJS loaded
    (done for Specials content - originally conditionally loaded, not anymore)

  • Means we store all `require()` calls

  • Execute them at a later stage when RequireJS ready

This smells a little funny to me?

Should we load RequireJS 'sync' & cache the hell out of it?

dom ready 

Currently...
  • Using a plugin to determine DOMContentLoaded
  • Because of scripts loaded during page construction
    we can't move scripts to the bottom of the page

Should we...
  • Place <scripts> at bottom of page
  • Negates need for  a DOM Ready  plugin
  • If we can't stop injecting calls to `require()`
    during page construction then it can still
    be worked around.

code smells


  • better pub sub communication (Twitter Flight)
  • write 'plain vanilla' where appropriate
  • follow the GUTS guidelines
  • don't re-wrap jQuery objects in jQuery
  • dont wrap elements in jQuery unnecessarily
  • recognise other jQuery smells (see GUTS)
  • be wary of overuse...

 $(this).attr('id') => this.id

pubsub communication

Need to better decouple our components!

Current PictureGallery.js
init: function() {
    pictureViewer.init(); // CONTEXT SHOULD BE REMOVED
    ...lots of set-up method calls...
}
Should have been...
init: function() {
    news.pubsub.emit('pictureGallery:initialized')
    ...lots of set-up method calls...
}

Current PictureViewer.js...
var PictureViewer = {
    ...code...

    init: function() {
        ...lots of set-up method calls...
        this.bindEvents();
    }
}
Should be...
var PictureViewer = {
    ...code...

    init: function() {
        ...lots of set-up method calls...
        this.bindEvents();
    }
}

news.pubsub.on('pictureGallery:initialized', PictureViewer.init);

css


  • Current strategy
  • Performance
  • Other options
  • What's wrong with current CSS
  • Code Smells

current strategy


Unclear...

  • Core and Compact = individual
  • Tablet and Wide = shares styles?
  • Core has relied on CSS3 in places
  • What is 'core' in Group terminology?
  • Using CSS3 features (such as "columns")
    • does it gracefully degrade
    • do we progressively enhance
    • even IE9 gets linear content

performance


it's important... very important!

but for the sake of discussion it's best to
leave performance at the door

good ideas get lost
when we're thinking about "everything"

other options?


"inheritance model"

  • Use media-queries to load CSS
  • Each style sheet gets smaller in size
  • Load desktop styles for non-supporting browsers
  • Downside: design changes = knock on effect

what's wrong with current css?


  • Over engineered
  • Too fragmented
    (i.e. core, compact, tablet, wide, shared)
  • Smelly code

This isn't any single persons fault.
This is a combination of factors.

code smells


  • Undoing styles (reverses purpose of cascade)
  • Magic numbers  (they just work?)
  • Qualified selectors  (div.blah)
  • Generic selectors (div)
  • line-height units (trick question: no unit!)
  • Brute forcing styles (I don't know why it's broken)
  • IDs
  • Generic class names (.card? id/credit/birthday-card ?)

sass

components


JavaScript and CSS

encapsulation


  • Components should be self contained

  • Logic (specifically Sass' @if $this or $that)
    should be encapsulated within the component

  • Easy to understand

modular


versioning?


How do we use semantic version for our components?

BBC News builds a new component.
World Service uses this component.

BBC News updates the component. 
World Service isn't ready to implement the update. 

How can this be achieved?

packaging


How modular should a component be?

  • With RequireJS we can load CSS with our modules

  • Should we consider making a components more
    like packages (see previous slide re: versioning)

  • If so, how to we go about 'distributing' components

page specific modules


  • Our single JavaScript module build 
    should definitely be split into individual
    page modules to keep file size down

  • Should we do the same with our CSS?
    If so then we'll need to re-think our
    current architecture to allow this.

  • Both JS and CSS loading strategies
    should be as performant as possible

guts



" G et U p T o S peed"

?


This was supposed to be our components library.

Still will be... one day?

style guides


There are guides for writing:

cutting the mustard


For full details see:
https://gist.github.com/Integralist/47f424ab3e275fcac093

problem?


  • Are we ready for desktop?
  • Pressure to support old browsers
    ("old IE" = be careful of narrowing terminology)
  • Will mean compromises

compromises?


non-JS / non-HTML5 devices...

  • Can't render CSS on HTML5 elements

  • Un-styled 'core' experience

  • Server-side browser sniff to replace tags

  • Move code base back to HTML4

  • 'Double Bag' -> wrap HTML5 tags in HTML4

should we support old browsers?


Depends.

We need statistics to tell us the market share
of browsers viewing our content.

when do we make this decision?


Depends.

Continue building for modern browsers:
means we'll have to go back and fix

Add a solution now (still need to rewrite current code):
means we'll need to remove it all and could be waste of time

could we encourage users t0

upgrade their browser?


A lot of agencies load up a "Internet Explorer"
message to make the user aware that they
can upgrade their browser to get a better
user experience

Doesn't help XP users!

JavaScript/CSS proposal


As part of my GUTS fork I've started working on
what our JS/CSS structure could be
(if we had a chance to start over)

Not massively different, just tweaks in places

But we need an "end goal" -> something to aim for

No point chipping away without knowing where we're going

javascript loading


  • Single bootstrap script in the <head>

  • Script is 541 bytes minified/gzipped

  • Loads asynchronously via `async` attribute
    (for browsers that support it - otherwise it will block rendering until
    loaded, but at 541b it's tiny and shouldn't have a noticeable effect)
    best thing to do:   test it and confirm with data


  • When loaded: it asynchronously loads RequireJS

...continued...


  • Rest of the page can still make calls to `require()`
    (we store in fake method until RequireJS loaded)

  • We then `require()` in our Stylesheet Loader
    and main JS app at the same time.

  • Additional stylesheets then get loaded in
    parallel as our js app fires up
    We still need DOM Ready plugin as I've assumed script tags are still
    being injected into the page while it's being loaded

sass strategy


Use technique by Google's @jaffathecake

  • We load single group1.css in our HTML
    JS takes care of loading groups 2/3/4

  • Followed by group4-ie.css inside
    IE conditional comments

  • Each 'group' imports the components they need

...continued...


  • group4 loads additional 'utils' which carries
    out some set-up for media queries and old IE

  • group4 includes a mixin (from 'utils') that
    controls the setting of old IE related styles

  • the mixin only generates content when
    group4 is imported into the group4-ie Sass file

  • Example component

what can we do right now?


  • Clean up our existing CSS/Sass files

  • Start implementing a more component
    based structure where conditional logic
    is better encapsulated

  • Ensure our JavaScript follows patterns
    and has clean PubSub implementations 
    meaning more decoupled modules
A task runner using Node.js

tasks

moving forward?


I like Grunt and want to use it more, but collectively
we need to decide if Grunt is a tool we want to use
moving forward?

If so, let's start writing more tasks for it
and moving over front-end related tasks
from Rake

More info on Grunt see this post
More info on custom tasks see this post

Questions that need answers


  • Should we do anything about our use of
    the DOM ready plugin (ties into Global AMD)?
  • What should our CSS strategy be?
    • remove CSS3 from core
    • composition or inheritance
    • encapsulate logic into single Sass component file
    • how should we handle Graceful Degradation (e.g. css3 columns not supported)
  • Should we version and package our components?
    • How do we handle desktop? now or later?
    • Do we continue to use Grunt?

    summary of what we should

    do regardless of todays decisions


    • Simplifying our Sass and JavaScript

    • Making JavaScript components
      more decoupled

    • Avoid common code smells and
      in general try really hard to make
      our code more flexible

    BBC News Strategies

    By Mark McDonnell

    BBC News Strategies

    Open discussion on our current strategies, where they fail and how they should evolve

    • 2,816