2009年5月25日 星期一

Amazone EC2 , S3 and Rails



2009年5月24日 星期日

High Performance Web Sites blog: Loading Scripts Without Blocking

Loading Scripts Without Blocking

# Resources in the page are blocked from downloading if they are below the script.
# Elements are blocked from rendering if they are below the sc

IE7 shows that the first script blocks all downloads, then the second script blocks all downloads, and finally the image, stylesheet, and iframe all download in parallel

Scripts block downloads in IE6&7, Firefox 2&3.0, Safari 3, Chrome 1, and Opera

Browsers are single threaded, so it’s understandable that while a script is executing the browser is unable to start other downloads. But there’s no reason that while the script is downloading the browser can’t start downloading other resources.

IE8 shows the scripts do indeed download in parallel, and the stylesheet is included in that parallel download. But the image and iframe are still blocked. Safari 4 and Chrome 2 behave in a similar way. Parallel downloading improves, but is still not as much as it could be.

Scripts still block, even in IE8, Safari 4, and Chrome 2



There are six main techniques for downloading scripts without blocking:

In many situations, the Script DOM Element is a good choice. It works in all browsers, doesn’t have any cross-site scripting restrictions, is fairly simple to implement, and is well understood.

If you have multiple scripts that depend on each other, you’ll need to concatenate them or use a different technique. If you have an inline script that depends on the external script, you’ll need to synchronize them. I call this “coupling” and present several ways to do this in

Testing any situation perofrmance in browsers

http://stevesouders.com/cuzillion/

這個東西可以 讓你快速的建立各種不同的情況以測試在不同瀏覽器的行為

這邊是他的例子
Inline Scripts Block Rendering
Stylesheets Block Downloads in Firefox and JavaScript Execution in IE
IE8 Parallel Script Loading

High.Performance.Web - Rule 6 - Put Scripts at the Bottom

Rule 6 - Put Scripts at the Bottom

PROBLEM 1: Everything below the script won't render until the script is loaded.
PROBLEM 2: All components below the script don't start downloading until the script is done.

這邊給了許多例子, 來展示把script 放在上面和放在底部的差別, 看了以後就把自己的script 搬到底部去吧

High Performance Web Sites memo(2)

HTTP Overview 2

A GET request includes a URL followed by headers.The HTTP response contains a
status code, headers, and a body.
------------------------
Compression

The size of the response is reduced using compression if both the browser and server
support it.Browsers announce their support of compression using the Accept-
Encoding header.Servers identify compressed responses using the Content-Encoding
header.

------------------------
Conditional GET Requests

If the browser has a copy of the component in its cache, but isn’t sure whether it’s
still valid, a conditional GET request is made.If the cached copy is still valid, the
browser uses the copy from its cache, resulting in a smaller response and a faster user
experience.

Typically, the validity of the cached copy is derived from the date it was last modified.
The browser knows when the component was last modified based on the Last-
Modified header in the response

It uses the If-Modified-Since header to send the last modified date back to the server.The
browser is essentially saying, “I have a version of this resource with the following last
modified date. May I just use it?”

If the component has not been modified since the specified date, the server returns a
“304 Not Modified” status code and skips sending the body of the response, resulting
in a smaller and faster response.

In HTTP/1.1 the ETag and If-None-Match headers are another way to make conditional GET requests

--------------------------------
Expires

Conditional GET requests and 304 responses help pages load faster, but they still
require making a roundtrip between the client and server to perform the validity
check

The Expires header eliminates the need to check with the server by making it
clear whether the browser can use its cached copy of a component

----------------------
Keep-Alive

Persistent Connections (also known as Keep-Alive in HTTP/1.0) was introduced to
solve the inefficiency of opening and closing multiple socket connections to the same
server

It lets browsers make multiple requests over a single connection.Browsers
and servers use the Connection header to indicate Keep-Alive support.The
Connection header looks the same in the server’s response.

The browser or server can close the connection by sending a Connection: close
header.Technically, the Connection: keep-alive header is not required in HTTP/1.1,
but most browsers and servers still include it.

Pipelining, defined in HTTP/1.1, allows for sending multiple requests over a single
socket without waiting for a response.Pipelining has better performance than persistent
connections



http://docs.google.com/Present?docid=dfb9f5wn_168fc36vgdr

Why is "primed cache same session" different from "primed cache different session"?

Browsers store resources in memory so they don't need to read them from disk.

---------------
Two considerations with disk cache

* Is the resource fresh (vs. expired)?
* If it's expired, is it valid (vs. updated)?

If a resource is fresh, no HTTP request is made – it's just read from disk.

If a resource is expired, a Conditional GET request is made.

* If the resource is valid, it's read from disk and the Conditional GET response is empty.
* If the resource has been updated, the Conditional GET response contains the updated version.

High Performance Web Sites memo(1)

High Performance Web Sites
Chapter A: The Importance of Frontend Performance

The first bar, labeled html, is the initial request for the HTML document.The
browser parses the HTML and starts downloading the components in the page

The HTML document is only 5% of the total response time.The user spends
most of the other 95% waiting for the components to download; she also spends a
small amount of time waiting for HTML, scripts, and stylesheets to be parsed, as
shown by the blank gaps between downloads.



One redirect ????
One cached image , conditional GET request

the HTTP status codes and headers
affect the browser’s cache



you can see a blank space with no downloads that occurs immediately
following the HTML document’s HTTP request.This is time when the browser
is parsing HTML, JavaScript, and CSS, and retrieving components from its
cache



there are as many as six or seven simultaneous HTTP requests.This behavior is due to the
number of different hostnames being used, and whether they use HTTP/1.0 or
HTTP/1.1

Parallel requests don't happen during requests for scripts.That's because in
most situations, browsers block additional HTTP requests while they download
scripts.

2009年5月22日 星期五

5 Tips to Scale Your Ruby on Rails Application

5 Tips to Scale Your Ruby on Rails Application

1) Cache, cache, cache and more cache.

Cache at the client, Ajax, gateway, reverse proxy, expiration, etags, built-in page, fragment caching, Use memcache to cache results

2) Segregate data and data serving

Datasets that are independent should go into separate databases
Serve static assets from a separate tier, or use Amazon S3 or a CDN like Akamai to serve those assets.

Maybe you can get away with a simpler key-value data store for some of your simpler data. There are ruby clients, so use Hadoop for scaling the storage and analysis of large amounts of unstructured data

If you have heavy data reporting needs, do your reporting from a copy of your main database, not from your production database!

2009年5月20日 星期三

在model 裡叫 controller的 method 或是 一些其他的helper

叫application controller 的 method

叫一些好用的helper




奇怪, 後來在做就不行了 當初到底做了啥 @@

2009年5月19日 星期二

Rails Rich editor, TinyMCE, jquery, attachment_fu, ja_tiny_mce

因為想要提供Rails Rich Editor 的功能, 就找到了 tiny_mce plugin 可以很簡單的把 TinyMCE editor 整合進來,
但是因為很貪心的想要有可以插圖的功能所以就找到了 tiny_mce_plus, 可是沒想到他是用prototype , 我想用jquery 阿, 所以又找到了j_tiny_mce
可是又沒想到他卻是用 paperclip 我已經有用attachment_fu 了 不想再弄一套阿, 加上這個也跑不起來 @@, 只好自己動手改了這個九成都是別人code 的 plugin ja_tiny_mce



1: 安裝 ja_tiny_mce, migrate 存上傳圖檔時需要的東西

cd vendor/plugins
git clone git://github.com/ilake/ja_tiny_mce.git


script/generate ja_tiny_mce_migration
rake db:migrate


2, 安裝需要的 plugins:

rake ja_tiny_mce:plugins

這邊會把attachment_fu, responeds_to_parent, will_paginate 到你的plugin 資料夾, 因為需要用到jquery 所以include 一下jquery file 或者 安裝一下 jrails

還有因為上傳圖一定會用到 user , 我們這邊用的是restful_authentication 來做登入登出
當然你可以把 TinyMcePhotosController 的 current_user 改成你相對應的user

3, layout 裡要include TinyMCE 需要的js:
<%= javascript_include_tiny_mce_if_used %>
<%= tiny_mce if using_tiny_mce? %>

4, controller 裡要加上 uses_tiny_mce 做設定:

uses_tiny_mce(:options => AppConfig.default_mce_options, :only => [:new, :edit])

AppConfig.default_mce_options 在 config/initializers/tiny_mce_plus_config.rb 你可以改變default的設定或加入自己的


5. View 裡面要設定哪個textarea 你要用tinymce

:class => "mceEditor"

6. 安裝需要的controller, view, helper
rake ja_tiny_mce:install

will Install following files:

app
|-- controller
|-- tiny_mce_photos_controller.rb
|-- helpers
|-- remote_link_renderer.rb
|-- models
|-- tiny_mce_photo.rb
|-- views
|-- tiny_mce_photos
|-- _photo_list.html.erb
config
|-- initializers
|-- tiny_mce_plus_config.rb

public
|-- images
|-- tiny_mce
|-- javascripts
|-- tiny_mce



其他:

1. 上傳圖片時跳出的視窗view 是在 public/javascripts/tiny_mce/plugins/curblyadvimage/image.htm 裡, 有需要就自己改吧
2. 用到的function 在這 public/javascripts/tiny_mce/plugins/curblyadvimage/js/functions.js

jquery memo tips (2)

split, parents, replace

2009年5月15日 星期五

jquery fade hightlight

hightlightFade

做新訊息出來的時, hightlight 效果很方便

2009年5月13日 星期三

jquery memo tips

2009年5月3日 星期日

Rails 2.3 Extras

Rails 2.3 Extras

Batch Find
What's New in Edge Rails: Batched Find

One quick caveat exists: you can’t specify :order or :limit in the options to find_each or find_in_batches as those values are used in the internal looping logic.

Batched finds are best used when you have a potentially large dataset and need to iterate through all rows. If done using a normal find the full result-set will be loaded into memory and could cause problems. With batched finds you can be sure that only 1000 * (each result-object size) will be loaded into memory



Dynamic Scopes
What's New in Edge Rails: Dynamic Scope Methods



Default Scopes
What's New in Edge Rails: Default Scoping



Object#try
try()

you can avoid nil-checking by writing code like <%= @person.try(:name) %>. Well, now it’s baked right into Rails. As implemented in Rails, it raises NoMethodError on private methods and always returns nil if the object is nil.



Smart Rendering of Partials
What's New in Edge Rails: render Stops Being High-Maintenance



Unified Rendering

rails engines

把一支 app 可以像plugin 一樣 裝到另外一支 application 裡

Rails Engines railscast
Engines in Rails 2.3
Rails Engines Make your plugins more powerful.

masterview in rails, layout

Masterview template engine
masterview quick start

Rails templates

就是讓你把建project 的每次都會做的一些動作弄成script , 常用的gem ,plugin, git commit, 這樣就不用每次都要在手動建一次

高速開發的利器:Rails 2.3 之 Template & Engine
App Templates in Rails 2.3
Rails templates
rails-templates in github
rails-template in github2

Rails on Rack

Rails on Rack
Ruby on Rack #1 - Hello Rack!
Ruby on Rack #2 - The Builder 13
Introducing Rack
Rails meets Sinatra

What is Rack ?
Rack: a Ruby Webserver Interface
rack-contrib in github

Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.



Rack Specification

Rack specification specifies how exactly a Rack application and the web server should communicate :

A Rack application is an Ruby object (not a class) that responds to call. It takes exactly one argument, the environment and returns an Array of exactly three values: The status, the headers, and the body.



Rack Gem
Rack gem is a collection of utilities and facilitating classes, to make life easier for anyone developing Rack applications. It includes basic implementations of request, response, cookies & sessions. And a good number of usefult middlewares. In short, install the rack gem. You’re gonna need it :

$ sudo gem install rack



To summarize
Ruby on Rack #1 - Hello Rack!
* Rack is a framework to roll your own ruby framework.
* Rack provides an interface between different web servers and your framework/application. Making it very simple for your framework/application to be compatible with any webserver that supports Rack – Phusion Passenger, Litespeed, Mongrel, Thin, Ebb, Webrick to name a few.
* Rack cuts your chase. You get request, response, cookies, params & sessions for free.
* Makes it possible to use multiple frameworks for the same application, provided there is no class collision. Rails and sinatra integration is a good example of this.
* Middlewares ! Think of middlewares as Rails’s before_filter/after_filter that are reusable across different rack supported frameworks/applications. For example, you can use the same Anti-spamming rack middleware for your Rails app, Sinatra app and your custom Rack application too!



2.1 Rails Application’s Rack Object

ActionController::Dispatcher.new is the primary Rack application object of a Rails application. Any Rack compliant web server should be using ActionController::Dispatcher.new object to serve a Rails application.



2.2 script/server

script/server does the basic job of creating a Rack::Builder object and starting the webserver. This is Rails’ equivalent of Rack’s rackup script.

Here’s how script/server creates an instance of Rack::Builder



2.3 rackup

To use rackup instead of Rails’ script/server, you can put the following inside config.ru of your Rails application’s root directory:



3 Action Controller Middleware Stack
Rack Middleware railscast

Many of Action Controller’s internal components are implemented as Rack middlewares. ActionController::Dispatcher uses ActionController::MiddlewareStack to combine various internal and external middlewares to form a complete Rails Rack application.

ActionController::MiddlewareStack is Rails’ equivalent of Rack::Builder, but built for better flexibility and more features to meet Rails’ requirements.



3.2 Configuring Middleware Stack

Rails provides a simple configuration interface config.middleware for adding, removing and modifying the middlewares in the middleware stack via environment.rb or the environment specific configuration file environments/.rb.

3.2.1 Adding a Middleware


3.2.2 Swapping a Middleware

You can swap an existing middleware in the middleware stack using config.middleware.swap.




3.4 Customizing Internal Middleware Stack

It’s possible to replace the entire middleware stack with a custom stack using ActionController::Dispatcher.middleware=.



3.5 Using Rack Builder

The following shows how to replace use Rack::Builder instead of the Rails supplied MiddlewareStack.

Clear the existing Rails middleware stack
Add a config.ru file to RAILS_ROOT



4 Rails Metal Applications
Rails Metal railscast
Rails Metal: a micro-framework with the power of Rails
Introducing Rails Metal

Rails Metal applications are minimal Rack applications specially designed for integrating with a typical Rails application. As Rails Metal Applications skip all of the Action Controller stack, serving a request has no overhead from the Rails framework itself. This is especially useful for infrequent cases where the performance of the full stack Rails framework is an issue.

Rails 2.3 release notes

Ruby on Rails 2.3 Release Notes

1. Session stores are now lazy loaded. If you never access the session object during a request, it will never attempt to load the session data (parse the cookie, load the data from memcache, or lookup an Active Record object).

2. ActiveRecord::QueryCache middleware is automatically inserted onto the middleware stack if ActiveRecord has been loaded. This middleware sets up and flushes the per-request Active Record query cache.

3. The Rails router and controller classes follow the Rack spec. You can call a controller directly with SomeController.call(env). The router stores the routing parameters in rack.routing_args.

4. Instead of config.action_controller.session = { :session_key => 'foo', ... use config.action_controller.session = { :key => 'foo', ....



Nested Attributes, Nested Object Forms
Rails 2.3 前的 nested model/complex forms problem 都是這樣做
What's New in Edge Rails: Nested Model Mass Assignment

2.3 之後可以這樣做了
What's New in Edge Rails: Nested Object Forms
Nested Model Forms



Nested Transactions



Multiple Conditions for Callbacks
When using Active Record callbacks, you can now combine :if and :unless options on the same callback, and supply multiple conditions as an array:




Find with having
mysql group_by having
MYSQL GROUP BY 和 HAVING 子句

HAVING子句可以讓我們篩選成組後的各組數據.
WHERE子句在聚合前先篩選記錄.也就是說作用在GROUP BY 子句和HAVING子句前.
而 HAVING子句在聚合後對組記錄進行篩選。

Rails now has a :having option on find (as well as on has_many and has_and_belongs_to_many associations) for filtering records in grouped finds. As those with heavy SQL backgrounds know, this allows filtering based on grouped results:




Reconnecting MySQL Connections
mysql Controlling Automatic Reconnection Behavior
MySQL supports a reconnect flag in its connections – if set to true, then the client will try reconnecting to the server before giving up in case of a lost connection. You can now set reconnect = true for your MySQL connections in database.yml to get this behavior from a Rails application



Application Controller Renamed

If you’re one of the people who has always been bothered by the special-case naming of application.rb, rejoice! It’s been reworked to be application_controller.rb in Rails 2.3. In addition, there’s a new rake task, rake rails:update:application_controller to do this automatically for you – and it will be run as part of the normal rake rails:update process.



HTTP Digest Authentication Support

For those that may now know the difference, basic authentication only base 64 encodes the authenticating username and password (making it easily decoded) whereas digest authentication sends an MD5 hash of your username and password. To simplify, digest is more secure than basic.

What's New in Edge Rails: HTTP Digest Authentication



More Efficient Routing

Another big change is that Rails now supports multiple routing files, not just routes.rb. You can use RouteSet#add_configuration_file to bring in more routes at any time – without clearing the currently-loaded routes. While this change is most useful for Engines, you can use it in any application that needs to load routes in batches.



Rack-based Lazy-loaded Sessions

In addition, sessions are now lazy-loaded (in line with the loading improvements to the rest of the framework). This means that you no longer need to explicitly disable sessions if you don’t want them; just don’t refer to them and they won’t load.



MIME Type Handling Changes

There are a couple of changes to the code for handling MIME types in Rails. First, MIME::Type now implements the =~ operator, making things much cleaner when you need to check for the presence of a type that has synonyms:

The other change is that the framework now uses the Mime::JS when checking for javascript in various spots, making it handle those alternatives cleanly.



Asset Hosts as Objects

Asset hosts get more flexible in edge Rails with the ability to declare an asset host as a specific object that responds to a call. This allows you to to implement any complex logic you need in your asset hosting.



grouped_options_for_select Helper Method





Disabled Option Tags for Form Select Helpers

New in rails 2.3 – disabled option tags and lambdas for selecting and disabling options from collections



Swappable Parsers for XMLmini

The support for XML parsing in ActiveSupport has been made more flexible by allowing you to swap in different parsers. By default, it uses the standard REXML implementation, but you can easily specify the faster LibXML or Nokogiri implementations for your own applications, provided you have the appropriate gems installed:




Faster Boot Time in Development Mode with Lazy Loading/Autoload

Quite a bit of work was done to make sure that bits of Rails (and its dependencies) are only brought into memory when they’re actually needed. The core frameworks – Active Support, Active Record, Action Controller, Action Mailer and Action View – are now using autoload to lazy-load their individual classes. This work should help keep the memory footprint down and improve overall Rails performance.

You can also specify (by using the new preload_frameworks option) whether the core libraries should be autoloaded at startup. This defaults to false so that Rails autoloads itself piece-by-piece, but there are some circumstances where you still need to bring in everything at once – Passenger and JRuby both want to see all of Rails loaded together.

2009年5月2日 星期六

JavaScript Programming Patterns

JavaScript Programming Patterns

The Old-School Way
working example




singleton
working example




Module Pattern
working example






Revealing Module Pattern
working example






Custom Objects
working example

Using prototype, we can now add additional properties to the object “blueprint” so that these items are available for every instance of that object right from the start. I ended up with having 3 properties, namely: config, changeColor and init.

呼叫用法也不同




Lazy Function Definition
his pattern is particularly useful when you need to do computations on the page once and then reuse the output multiple times.
working example


用法

As stated above, this pattern is not that handy here, but consider a situation when there is some heavy and complex computing involved. You certainly do not want to do that each time the function gets called. Peter calls this kind of function definition a “promise”, which means the outer declaration can be viewed as some kind of promise that later on this function will get redeclared to provide something more useful.




Conclusion

There is no general solution on how such problems should be approached. For a task like this, I believe that the singleton pattern is the most convenient way of doing it. Mostly because less lines of code are required. But for other, more complex problems, using the module pattern or creating custom objects or the lazy function definition might be more appropriate.

The seven rules of Unobtrusive JavaScript

The seven rules of Unobtrusive JavaScript
[譯文]The seven rules of
Unobtrusive JavaScript


像這種全域式的有可能會造成跟人家命名相衝的結果


所以我們將他包成一個object


可是這樣的結果有可能會造成命名太長, 或者是我有些function 只是內部使用, 不想給外面用
就可以用下面的方式, 將想給外面用的方法放在return 裡





對於js 操控的 HTML 和 CSS 應該將其分離出來放到一個物件裡, 方便管理

2009年5月1日 星期五

ruby 中文

Use Regexp to handle String 用 Regexp 拯救字串處理
1.8, 1.9


Unicode codepoint
另一種在 Ruby 1.8 拯救 UTF-8 字串的方式
1.8 1.9

block, Proc , lambda AND module mixin AND method_missing

Ruby 程式語言簡介

帶參數的 code block


Proc object
將 code block 明確轉成物件




Module 和 Mixins




Method Missing


Introspection (反射機制)