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"
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
- Simplify our usage
- Avoid over-engineering!
- BEM removes need for nesting
- Maintainability
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
- shouldn't take on too much responsibility
- should have a logical structure
- should be clear where they live
- clean communication between components (js)
- layout should always be a opt-in modifier (css)
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.
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 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!
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
(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
-
I've written a task to dynamically generate our
Jasmine Spec modules into a single file (so you
don't have to manually update the Spec Runner)
- I'm currently writing tasks for dynamically
generating Sass/Watch sub tasks based on
directory globs (note: going to be re-written)
-
700+ pre-built tasks. Some we're already
using for building our AMD modules,
linting JavaScript, watching/compiling
Sass + other stuff
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
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