mark pilgrim: google's html5 evangelist
CSS layout
-
see also your google doc on this at https://docs.google.com/document/d/1PFX_eQ7wcld5Uy-xvAYQZ2K3WDXKu1rs822HNxIQqoY/edit
-
height:auto
inherits height from parent -
property combos: http://bitsofco.de/how-positioning-css-properties-interact/
typicalDisplay() if display:block, display:inline, ... display:block else if display:inline-table display:table else display:as specified
if display:none override/ignore everything else else if position:absolute/fixed float:none typicalDisplay() else if float:left/right typicalDisplay() else if position:static offsets:ignored
safe fonts
- sans-serif
- arial
- verdana
- helvetica?
- monospace
- courier new
- serif
- georgia
- times new roman
rss
- some web-based feed readers include subscriber counts in their user agent
strings
- eg "Bloglines/3.1 (http://www.bloglines.com; 602 subscribers)"
- http://www.rss4lib.com/2007/05/counting_rss_subscribers.html
3D
- webgl: low-level JS API based on opengl es 2.0
- O3D: scene graph; built on webgl & js as of 5-2010; was originally a plugin
encodings
- url encoding:
user%40domain.com
,hello%20world
,%6A
forj
- html encoding:
1 < 2
,j
forj
- javascript escaping: eg for json
- css escaping
JSON
- always use object literal
{...}
in top-level to serve JSON- if you use array
[...]
then hacker can override Array ctor and source your JSON as a script, capturing values - object literals in top-level are JS syntax error
- or prepend e.g.
throw 1
orfor (;;)
, which legit client can strip - ECMAScript 5 changes array literals to use built ctor, which closes this attack vector
- if you use array
HTTP
- cookies
- subdomains can set for parent domains, except for TLDs (edu) due to dot restriction
- domains must contain at least 2-3 dots, depending on what kind of TLD (.com, .va.us)
- session cookies may be persisted when using browsers' "restore sessions" features (eg firefox)
- flags: secure, httponly
- http://curl.haxx.se/rfc/cookie_spec.html
- chunked transfer encoding
- break body up into chunks; each specifies size; end w 0-length chunk
- so, know when done receiving whole body; Content-Length unneeded
- in 1.1
HTTP session flash msg
- The flash scope should only be used to transport success/error messages on simple non-Ajax applications. As the data are just kept for the next request and because there are no guarantees to ensure the request order in a complex Web application, the Flash scope is subject to race conditions.
- http://www.playframework.org/documentation/2.0.1/JavaSessionFlash
flash RTFMP
- udp only (RTMP is the tcp-based one)
- can make p2p connections using RTFMP server (eg adobe stratus) as rendezvous
- server maintains list of potential peers that can be connected to
- server assigns temp uniq IDs to connections from SWFs
- other SWFs connected to server can subscribe to streams and events from that ID once the bcasting SWF agrees to the connection
- if NetConnection to server is lost/closed, any peer connection is also closed
- server also assists in nat-t; supports TURN
- in flash 10; see NetConection, NetStream objects
- security
- privacy: 128-bit AES encryption; key negotiated with D-H
- auth: none, but provides secure nonces to aid with app-level auth
- only enables sending media from mic/cam to other flash player endpoints that subscribe to media streams
session continuity
- persistence
- cookies
- window.name: only for this tab session
- HTTP authentication
- flash local shared objects (LSOs)
- HTML5
- message passing
- hidden form fields
- URL query string
misc
rel=nofollow
: indicates to search engine that a link should not influence the target's ranking
techniques
- css spriting: combining multiple images into one (reducing requests) and cutting pieces out using css
css architecture
-
avoid
- overriding styles based on context (with parent selectors):
#sidebar .widget
, etc. - complex deep selections (tied strongly to html structure)
- very generic class names:
title
,content
,action
, etc. - both layout & style in a rule
- overriding styles based on context (with parent selectors):
-
do
-
simple flat selectors; don't allow for styling unwanted elements based on html structure
-
separate layout & style concerns; don't have a class do both
-
namespace classes:
widget__title
,widget__content
, etc. -
adjust components with modifier classes:
widget--sidebar
, etc. -
organize rules into 5 categories: base, layout, state, templates (abstract reusable pieces for components), and components
-
use classes for styling only; don't use for JS hooks, feature detection, testing, etc. (or at least identify with prefixes, e.g.
.js-
) -
semantic naming scheme/punctuation:
/* Templates Rules (using Sass placeholders) */ %template-name %template-name--modifier-name %template-name__sub-object %template-name__sub-object--modifier-name
/* Component Rules */ .component-name .component-name--modifier-name .component-name__sub-object .component-name__sub-object--modifier-name
/* Layout Rules */ .l-layout-method .grid
/* State Rules */ .is-state-type
/* Non-styled JavaScript Hooks */ .js-action-name
-
-
tools
- when using preprocessors like Sass:
- don't nest
- don't use mixins without args; always better to use as templates to extend with
- don't use
@extend
on a selector that isn't a single class, or else bloat - don't use
@extend
in modifier rules; e.g., don't makebutton--primary
extendbutton
, or else JS can't select allbutton
s
- css lint
- html inspector
- when using preprocessors like Sass:
-
http://engineering.appfolio.com/2012/11/16/css-architecture/
browser plugins
- plugins like flash can be windowed for perf, or windowless (opaque or transparent)
- z-ordering
- certain browser elements like native widgets or iframes are traditionally also windowed
- windowed elements are all drawn on top of other elements
- de-facto standard practice: use iframes to pos things atop other windows
- harder to smoothly (synchronously) scroll windowed plugins
- must desynchronize for responsiveness, but windowless gtk, moz moving to eliminate widgets in own native windows
session management
- 3 techniques to pass around session IDs: URLs, cookies, and hidden fields (for POSTs only)
x drawables TODO
xt: ancient toolkit for windowed plugins
3 old techniques for dynamically typed languages on language vm's
- all objects in lang subclass a common root object; lots of cons
- reflection: may be mismatch for lang type concepts
- interpreter: slow invokedynamic
- opcode identifies method name & type (which can be very generic, e.g. (Object;Object)Object)
- a bootstrap method is registered with a class
- first time you encounter a particular invokedynamic in some class C's method, call C's bootstrap method
- bootstrap method is passed the calling class C, method name, method type
- return a CallSite whose target has been set to some MethodHandle (a pointer to a method)
- for some reason, the CallSite ctor takes the same args as the bootstrap method; not sure how this is used
- as side effect, the CallSite may be stored away in a data structure managed by the lang runtime, so that it can be retargeted in the future
Google SPDY (Alyssa (Rzeszutek) Wilk, talk at MIT 12/8/2009)
- HTTP protocol built on TCP; former internal name "FLIP"
- features
- basic
- multiplexed streams: done by packetizing/framing (has SYN, DATA, FIN pkts)
- prioritization: advisory, per-req; can reduce load times by eg loading js
first that processes while other resources are loading
- determined entirely by browser
- header compression: gzip dicts are kept across reqs
- advanced (optional
- server push: avoid half the round trip of having client send a req
- hints: client may request this soon, but don't xmit yet
- basic
- status
- protocol still being developed
- will be opt-in in chrome; built in-memory server
- will do out-of-lab experiments, deploying across google services
- performance
- 40% fewer packets than compressed HTTP, 15% fewer bytes
- 88% header compression, 85% resp hdr compression
- saved 45-1142ms per page load
- real world pkt loss is ~1%; SPDY is 41-47% faster for PL btwn 1-2% because (1) fewer packets and (2) prioritization
- SSL: a bunch of remaining work/issues; want to negotiate SPDY as part of SSL handshake
- future work
- caching implications: what are latency implications of not using proxy caches, etc? (can't proxy bc not enough support for SPDY)
- unidirectional streams: replace bidir streams + half-close
- flow control: backoff + GOAWAY; if server overloaded, tell client "slow down" or lose benefits
- insecure content: classify data as public + cacheable?
- related work
- HTTP over SCTP, SST, MUX, BEEP
- offers some improvements but doesn't fix HTTP itself
- requires big infrastructure changes to client/server networking stacks
- HTTP pipelining
- FIFO, so lost packet is disastrous
- hard for web proxies to implement
- server must return results in same order; possibly suboptimal
- disabled in most browsers/proxies by default
- HTTP over SCTP, SST, MUX, BEEP
- http://lwn.net/Articles/362473/
decentralized identity/auth/social standards
- types
- identity/SSO: manage a single centralized identity; need only sign on once
- windows live ID aka ms passport aka ms wallet: identity/SSO; an openid provider
- openauth: identity/SSO; access authorization
- by AOL; auth AOL/AIM users
- openid: authentication
- oauth: authentication and authorization
- 3-legged: normal auth flow; requires access token
- 2-legged: domain admin authorizes req for all users; no access token
- server-to-server, no user
- flow:
- all app.com to platform.com requests are https and signed for app.com authenticity; valid methods are hmac-sha1 w key = shared-secret, rsa-sha1, plaintext
- user goes to app.com/welcome w button to app.com/connect
- /connect requests reqtoken, reqsecret from https://platform.com/initiate; this also sets callback for the reqtoken to be http://app.com/ready
- /connect redirects to https://platform.com/authorize?reqtoken=blah
- user redirected to app.com/ready?reqtoken=blah&verifier=blah
- /ready requests platform.com to verify (reqtoken, verifier) and return accesstoken
- opensocial: social network API (JS for gadgets, REST for else)
- friend connect: opensocial router and gadgets
- facebook connect: links acounts elsewhere with facebook accts
- facebook platform: everything
- saml: common in enterprise settings
- SAML2.0 supported by MS ADFS 2.0 (since windows server 2008?)
- used by google apps
- saml vs openid: http://identitymeme.org/doc/draft-hodges-saml-openid-compare.html
- ref: http://y_z.scripts.mit.edu/wp/2010/01/19/making-sense-of-openid-oauth-opensocial-google-friend-connect-facebook-connect-and-more/
latency costs
- amazon: every 100ms latency cost 1% in sales http://home.blarg.net/~glinden/StanfordDataMining.2006-11-29.ppt
- google: adding .5s lost 20% traffic http://glinden.blogspot.com/2006/11/marissa-mayer-at-web-20.html
- brokers could lose $4M revenue/ms if etrading platform 5ms behind competition http://www.tabbgroup.com/PublicationDetail.aspx?PublicationID=346
- http://highscalability.com/blog/2009/7/25/latency-is-everywhere-and-it-costs-you-sales-how-to-crush-it.html
online advertisement
- cost per mille/impression (CPM): per 1,000 views
- cost per click (CPC)
- cost per action (CPA): per purchase
- cost per engagement (CPE): interact with ad
caching
- edge side includes (ESIs): small markup lang for dynamic web content in
caches
- developed by a group of companies incl. akamai, bea, oracle)
- eg
<esi:include src="http://example.com/1.html" alt="http://bak.example.com/2.html" onerror="continue"/>
html5
- simpler doctype, charset
- tags
- section: group related content
- article: section that can stand alone
- header: heading, intro, nav, etc; non-recursive
- hgroup: special header that contains only 2+ h1-h6 elts
- nav: section of nav links
- aside: section of tangentially related content
- figure: essential content but not nec inline
- footer: add'l info: signature, related links, copyright; non-rec
- address: email contact info
meta tags
- quirks mode: pre-IE7 behavior; specified with e.g.
<!DOCTYPE html PUBLIC>
- strict mode: IE7 behavior
- standards mode: IE8 behavior
x-ua-compatible
: implemented by IE8; aka "version targeting"- eg `content="IE=EmulateIE7" causese IE8 to behavior like older version
js module systems
- chaotic landscape
- commonjs: "synchronous"
require()
calls; simpler, flatter- server side impls: node
- client side impls: browserify (npm), ender (npm), onejs (npm), component,
cpm, hem
- component: pkg mgr & build tool
- ender: pkg mgr
- browserify: buggy, other problems; prefer onejs http://stackoverflow.com/questions/10556013/pros-and-cons-of-using-requirejs-or-onejs
- AMD: requires nesting & evaluates body as callback to support async
- supports loading non-JS resources via plugins
- client side impls: requirejs, curl.js, jam
- ES6: has
module mymod { export var foo = 0; } import * from mymod;
- opinions
- slightly prefer commonjs since it's simpler; compiling server-side anyway
- prefer component since it's client side specific; can't just use node
- misc
- bower: simply fetches files; agnostic to module system
- volo: supports both AMD & CJS
- refs
js testing systems
- frameworks
- qunit: very easy to start; can use pavlov for BDD (unmaintained; 100+ stars as of 2013-05)
- jasmine: BDD; easier to start than mocha; not tightly maintained; by pivotal; 5k stars as of 2013-05
- mocha: more flexible; can use chai as BDD/TDD assertion lib, sinon as test
spy; has 2800+ stars as of 2013-05
- chai has 600 as of 2013-05; allows funky syntax:
expect(x).should.be.equal(y)
(vsexpect(x).shouldBe(y)
- chai has 600 as of 2013-05; allows funky syntax:
- buster: seems promising/nice; feels cleaner than mocha/chai; has 200+ stars as of 2013-05
- refs
- runners
- karma (formerly testacular): actually in-browser
- testem: similar to karma; curses interface; overtaken in popularity
- buster
- http://zachlendon.github.io/blog/2013/03/26/quick-thoughts-on-testem-vs-testacular-karma/
- commonly use phantomjs or node packages dom and vm
angular
- issues
- no built-in support for:
- nested routing
- no built-in support for:
react relay
node(...)
orviewer()
specify what 'root' data to load- can specify query params
- specify fields/related objects in json-like format
- pagination:
.after(ID).first(N)
; usu. egN
is a query param - composition: each object specifies own queries, but queries are merged, and fetches are batched
- component not rendered till all
required
data loaded - single central store/cache for all data
- supports optimistic mutations
- https://gist.github.com/wincent/598fa75e22bdfa44cf47
- https://www.youtube.com/watch?v=9sc8Pyc51uU
JS languages
- coffeescript
- crazy global variable scoping
- no support for
for...of
- no es6 module system
- es6 (babel)
- es6 module system: supports cyclic dependencies
- scala.js
- very slowly trying to get to "usable" state
sync kit (marcua, edbenson, www10)
-
idea: easier way to utilize client-side db caching
-
sync primitives: sets, queues
-
instead of:
template = Template('index.template') results = db.query('select * from users where ...') return template.render(results)
or "flying templates" (shipping just the data, relying on client cache of template):
template = Template('index.template') results = db.query('select * from users where ...') return flying([template, results])
return:
template = Template('index.template') return synckit([template, Queue(table='users', order='DESC', filter='predicate', ...)])
-
perf eval: higher tput, competitive (slightly better) latency
- higher tput from network-bound workloads
- latency comes from client-side processing + local db queries