Since the internet started out front end development has been taking a long time in reaching maturity. Websites are looking sleeker and the tools to make it so are getting easier. One of the biggest pain points has been dealing with different results from different web browsers. To overcome this libraries have gone through the pain-staking process of providing DSLs that work with each browser. Two prime examples are jQuery and Bootstrap.
Front end development can still be painful at times. But if we put aside the manual way of doing things and exercise exclusive use of the libraries and tools built for this the pain will increasingly go away with experience.
I’d like this thread to be a discussion on tools and practices for the most painless front end development advice and tips we can share.
My first advice is to style all visual positions with Bootstrap layout DSLs. It’s been difficult for me to move away from setting my own margins, paddings, fixed / relative position, and alignment. But seeing different results in different browsers just proves to me that I need to rely more on the proper tools to get a consistent result.
What are your tips and advice for a painless front end development?
For me I’d like to avoid directly having to deal with javascript - so tech like Opal and Elm and libraries and frameworks like Clearwater and Volt and even React.rb are interesting… hopefully we’ll see a lot more options thanks to Web Assembly design/FAQ.md at master · WebAssembly/design · GitHub though personally I wish it -was- a replacement of JS.
Just code it in Opal, it really let’s you do some difficult stuff which can hardly be achieved with pure JS, and you’ll love to code your frontends.
For really light weight CSS, I like Yahoo Pure (4.4 KB), although you don’t get as much as you do with something like Thoughtbot’s Bourbon.
When you start adding events in your jQuery, I would say start paying attention to how much it grows, esp if you need to start syncing data with the server - at some point you may want to use an Angular/Ember/Backbone/other JS framework to help with the data binding. It’s been a particular pain point for myself.
I’ve used that approach myself. It means you can apply a lot of the column-type style attributes to the columns class, and then just apply the size specific styling to the one, two … classes. It is also easy to understand from the code, what is happening.
Something I’ve been using lately in Clearwater apps to keep things painless has been using functional stores. It’s a lot like Redux, but in Ruby. I was originally turned off by the idea, but I saw Dan Abramov’s talk on React Hot Loader with Redux at React Europe and not only was it amazing, but the Redux-style concepts work even better in Ruby.
You dispatch actions to your store, which returns a new version of its state object (not the store itself, though):
initial_state = {
todos: [],
}
store = GrandCentral::Store.new(initial_state) do |state, action|
case action
when Actions::NewTodo
state.merge todos: state[:todos] + [action.todo]
else # Return the same state if we didn't handle the action
state
end
end
store.on_dispatch do |old_state, new_state|
# Rerender the app when a dispatch modifies state
app.render unless old_state.equal?(new_state)
end
If your state is held in a Hash, your store’s reducer block uses state.merge to return a new state. If it’s an array, you might use an Enumerable method to return a new array, such as state.reject(&:completed?) in response to the “Clear Completed” button in a TodoMVC app. The point is, modifying the state in-place is bad, especially if you’re caching renders.
Notice how in the on_dispatch block, we compared old_state.equal?(new_state). Because we aren’t modifying the state in-place, we can use an identity comparison, which is the fastest comparison we can make between two data structures.
Admittedly, creating a copy of the data structure for the new state is O(n), but if we had modified it in-place, we would have to do all kinds of context-specific things to determine whether or not we needed to rerender — some of which are probably also O(n). Rerendering isn’t necessarily slow (if you decided to forego that check), but not rerendering is a whole lot faster.