{"action":"created","issue":{"url":"https://api.github.com/repos/camsong/blog/issues/4","labels_url":"https://api.github.com/repos/camsong/blog/issues/4/labels{/name}","comments_url":"https://api.github.com/repos/camsong/blog/issues/4/comments","events_url":"https://api.github.com/repos/camsong/blog/issues/4/events","html_url":"https://github.com/camsong/blog/issues/4","id":119158465,"number":4,"title":"抛弃jQuery，拥抱原生JavaScript","user":{"login":"camsong","id":948896,"avatar_url":"https://avatars.githubusercontent.com/u/948896?v=3","gravatar_id":"","url":"https://api.github.com/users/camsong","html_url":"https://github.com/camsong","followers_url":"https://api.github.com/users/camsong/followers","following_url":"https://api.github.com/users/camsong/following{/other_user}","gists_url":"https://api.github.com/users/camsong/gists{/gist_id}","starred_url":"https://api.github.com/users/camsong/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/camsong/subscriptions","organizations_url":"https://api.github.com/users/camsong/orgs","repos_url":"https://api.github.com/users/camsong/repos","events_url":"https://api.github.com/users/camsong/events{/privacy}","received_events_url":"https://api.github.com/users/camsong/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-11-27T09:16:05Z","updated_at":"2015-12-01T13:22:11Z","closed_at":null,"body":"前端发展很快，现代浏览器原生 API 已经足够好用。我们并不需要为了操作 DOM、Event 等再学习一下 jQuery 的 API。同时由于 React、Angular、Vue 等框架的流行，直接操作 DOM 不再是好的模式，jQuery 使用场景大大减少。因此我们项目组在双十一后抽了一周时间，把所有代码中的 jQuery 移除。下面总结一下：\r\n\r\n## Why not jQuery\r\n\r\n### 1. 模式变革\r\n\r\njQuery 代表着传统的以 DOM 为中心的开发模式，但现在复杂页面开发流行的是以 React 为代表的以**数据/状态**为中心的开发模式\r\n\r\n应用复杂后，直接操作 DOM 意味着手动维护状态，当状态复杂后，变得不可控。React 以状态为中心，自动帮我们渲染出 DOM，同时通过高效的 DOM Diff 算法，也能保证性能。我们在 React 应用实践中也发现，大部分当你想直接操作 DOM 的时候，就意味着你可能做错了。\r\n\r\n### 2. 不支持同构渲染\r\n\r\n重构就是前后端运行同一份代码，后端也可以渲染出页面，这对 SEO 要求高的场景非常合适。由于 React 等流行框架天然支持，已经具有可行性。当我们在尝试把现有应用改成同构时，因为代码要运行在服务器端，但服务器端没有 DOM，所以引用 jQuery 就会报错。这也是要移除 jQuery 的迫切原因。同时不但要移除 jQuery，在很多场合也要避免直接操作 DOM。\r\n\r\n### 3. 原生 API 足够好用\r\n\r\n由于浏览器的历史原因，曾经的前端开发为了兼容不同浏览器怪癖，需要增加很多成本。jQuery 由于提供了非常易用的 API，屏蔽了浏览器差异，极大地提高了开发效率。这也导致很多前端只懂 jQuery。其实这几年浏览器更新很快，也借鉴了很多 jQuery 的 API，如 `querySelector`，`querySelectorAll` 和 jQuery 选择器同样好用，而且性能更优。\r\n\r\n### 4. 性能\r\n\r\n前端开发一般不需要考虑性能问题，但你想在性能上追求极致的话，一定要知道 jQuery 性能很差。原生 API 选择器相比 jQuery 丰富很多，如 `document.getElementsByClassName` 性能是 `$(classSelector) ` 的 50 多倍！\r\n\r\n\r\n![jQuery VS Native API](http://segmentfault.com/img/bVrgkW)\r\n\r\n测试链接：http://jsperf.com/jquery-vs-native-api\r\n\r\n\r\n### 5. 时机成熟\r\n\r\n差的浏览器（IE）已经淘汰的差不多了。\r\n\r\n> If We Didn't Spend So Much on IE Support, We Could Be Taking Vacations on Mars\r\n> Christian Alfoni\r\n\r\n我们的主打产品现在有千万用户，因为我们一直引导用户升级浏览器，上个月统计 IE 9 以下用户只占不到 3%。但为了这 3% 的用户我们前端开发却增加了很多工作量，也限制了我们升级我们的架构，因此放弃支持他们利大于弊。当然这要根据产品来定，比如这是百度统计的国内浏览器占有率，IE8 竟然还有 22%。有些产品可以为了保证用户体验，在旧的浏览器上投入很大成本，甚至做到了极致。其实我觉得产品更应该做的是**引导用户升级浏览器**。微软也宣布 [2016年1月12号停止支持 IE 11 以下浏览器](https://www.microsoft.com/en-us/WindowsForBusiness/End-of-IE-support)，继续使用旧浏览器就会有安全风险，我们更应该主动引导，只要产品有足够吸引力，大部分用户升级并不困难。\r\n\r\n![浏览器分布率](http://img.alicdn.com/tps/i2/TB1LyLYKFXXXXbuXpXXWCK5PpXX-721-312.png)\r\n\r\n数据来源 [百度统计](http://tongji.baidu.com/data/browser)\r\n\r\n下面是国际上 IE 占有率，IE8 已经跌出前 10，IE 11 比较多，还好支持他们并不难。\r\n\r\n![国际浏览器分布率](http://img.alicdn.com/tps/i3/TB121HKKFXXXXXJXVXXSrt.VXXX-522-456.png)\r\n\r\n数据来源 [W3 Counter](http://www.w3counter.com/globalstats.php)\r\n\r\n\r\n## 如何移除 jQuery\r\n\r\n### 1. 替换代码\r\n\r\n移除 jQuery 可以很顺利，我们把整个过程详细整理了，并开源。\r\n\r\n打开 https://github.com/oneuijs/You-Dont-Need-jQuery 对 API 查找替换即可。\r\n\r\n同时我们简单封装了一些方法：\r\n\r\n* [oui-dom-utils](https://github.com/oneuijs/oui-dom-utils) 来做选择器和样式相关\r\n* [oui-dom-events](https://github.com/oneuijs/oui-dom-events) 来做 Event，支持命名空间和事件代理\r\n\r\n刚去了 jQuery 又引了新的库，这不是玩我吗？？其实以上两个库很简单，只是常用方法的简单封装，建议你看一下代码。你当然可以不用。\r\n\r\n以上的库都用于我们的生产环境，我们会长期维护，保证更新。\r\n\r\n### 2. 旧浏览器自动跳转\r\n\r\n代码替换后，当用户用旧浏览器打开时，你还要做一个跳转，把用户定位到提示页面，提示用户下载升级浏览器。IE9 以下浏览器都支持条件判断语句，可以在 `</head>` 标签结束前添加如下代码做自动跳转\r\n```js\r\n<!--[if lte IE 9]>\r\n  <script>if (!/update\\.htm/.test(location.href)) window.location = '//abc.com/update.htm'; </script>\r\n<![endif]-->\r\n```\r\n\r\n## 总结\r\n\r\n本文并不是强迫你一定要移除 jQuery，jQuery 为支持旧浏览器节省了很多成本。但条件成熟的情况下，移除 jQuery，参照 [You Don't Need jQuery](https://github.com/oneuijs/You-Dont-Need-jQuery) 拥抱原生 JavaScript 能同样保证开发效率，也可以给产品带来更好的性能，同时也能提高开发者水平。"},"comment":{"url":"https://api.github.com/repos/camsong/blog/issues/comments/160967290","html_url":"https://github.com/camsong/blog/issues/4#issuecomment-160967290","issue_url":"https://api.github.com/repos/camsong/blog/issues/4","id":160967290,"user":{"login":"whatmon","id":11900721,"avatar_url":"https://avatars.githubusercontent.com/u/11900721?v=3","gravatar_id":"","url":"https://api.github.com/users/whatmon","html_url":"https://github.com/whatmon","followers_url":"https://api.github.com/users/whatmon/followers","following_url":"https://api.github.com/users/whatmon/following{/other_user}","gists_url":"https://api.github.com/users/whatmon/gists{/gist_id}","starred_url":"https://api.github.com/users/whatmon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/whatmon/subscriptions","organizations_url":"https://api.github.com/users/whatmon/orgs","repos_url":"https://api.github.com/users/whatmon/repos","events_url":"https://api.github.com/users/whatmon/events{/privacy}","received_events_url":"https://api.github.com/users/whatmon/received_events","type":"User","site_admin":false},"created_at":"2015-12-01T13:22:11Z","updated_at":"2015-12-01T13:22:11Z","body":"mark\r\n"}}