记一次如何解决谷歌浏览器占用过高cpu问题过程

1. 问题现象 有时候发现mac风扇响的厉害,于是我检查了mac系统的活动监视器,发现Google Chrome Helper占用99%的CPU。 通常来说Chrome如果占用过高的内存,这并不是什么问题,毕竟Chrome的性能以及易用性是建立在占用很多内存的基础上的。但是无论什么程序,持续的占用超过80%的cpu,都是极不正常的。大多数程序都是占用维持在低于10%的CPU。 活动监视器指出问题出现在Chrome浏览器。那么问题可以再次细分为三块。 Chrome系统自身问题 一些插件,例如flash插件,扩展插件 网页程序js出现的问题 2. 从任务管理器着手 其实Chrome浏览器自身也是有任务管理器的,一般来说windows版chrome按住shift+esc就会调出任务管理器窗口。mac版调出任务管理器没有快捷,只能通过Window > Task Manager调出。 调出任务管理器后,发现一个标签页,CPU占用率达到99%, 那就说明,应该是这个标签页中存在持续占用大量CPU计算的程序。 最后找到这个页面,发现该页面背景图是一种动态粒子图。就是基于particles.js做的。我想,终于找到你了。 于是我把这个动态图的相关js代码给注释掉,电脑的风扇也终于变得安静了。 3. 问题总结 问题解决的总结:解决问题的方法时很简单的,基于一个现象,找到一个原因,基于这个原因再找到一个现象,然后一步一步缩小问题范围,逼近最终原因。 机器CPU过高,一般都是可以从任务管理器着手解决。系统的任务管理器可以监控各个程序占用的CPU是否正常,通常程序自身也是有任务管理的。 像谷歌浏览器这种软件,几乎本身就是一个操作系统,所以说它的任务管理器也是必不可少的。Chrome浏览器再带的任务管理器可以告诉你几个关键信息。 任务占用的内存 任务占用的CPU 任务占用的网络流量大小 如果你一打开谷歌浏览器,你的电脑风扇就拼命转,那你最好打开谷歌浏览器的任务管理器看看。 4. 关于动态背景图的思考 动态背景图往往都会给人很酷炫的感觉,但是这种背景图的制作并不是很复杂,如果你使用particles.js来制作,制作一些动态背景图只需要几行代码就可以搞定。但是这种酷炫的背后,CPU也在承受着压力。 particles.js提供的demo效果图,在Chrome中CPU会被提高到100%。 也有几家使用动态背景图的官网。我记得知乎以前就用过动态背景图,但是现在找不到了。另外一个使用动态背景图的是daocloud, CPU也是会在首页飙升到50%。 所谓:强招必自损,动态背景图在给人以炫酷科技感的同时,也需要权衡这种技术对客户计算机的压力。 另外,不要小看JavaScript, 它也可能引起大问题

2018-06-04 17:58:24 · 1 min · Eddie Wang

IE浏览器不支持location.origin

某些IE浏览器location.origin属性是undefined,所以如果你要使用该属性,那么要注意做个能力检测。 if (!window.location.origin) { window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: ''); }i

2018-05-24 14:50:49 · 1 min · Eddie Wang

端到端测试哪家强?不容错过的Cypress

1. 目前E2E测试工具有哪些? 项目 Web Star puppeteer Chromium (~170Mb Mac, ~282Mb Linux, ~280Mb Win) 31906 nightmare Electron 15502 nightwatch WebDriver 8135 protractor selenium 7532 casperjs PhantomJS 7180 cypress Electron 5303 Zombie 不需要 4880 testcafe 不需要 4645 CodeceptJS webdriverio 1665 端到端测试一般都需要一个Web容器,来运行前端应用。例如Chromium, Electron, PhantomJS, WebDriver等等。 从体积角度考虑,这些Web容器体积一般都很大。 从速度的角度考虑:PhantomJS, WebDriver < Electon, Chromium。 而且每个工具的侧重点也不同,建议按照需要去选择。 2. 优秀的端到端测试工具应该有哪些特点? 安装简易:我希望它非常容易安装,最好可以一行命令就可以安装完毕 依赖较少:我只想做个E2E测试,不想安装jdk, python之类的东西 速度很快:运行测试用例的速度要快 报错详细:详细的报错 API完备:鼠标键盘操作接口,DOM查询接口等 Debug方便:出错了可以很方便的调试,而不是去猜 3. 为什么要用Cypress? Cypress基本上拥有了上面的特点之外,还有以下特点。 时光穿梭 测试运行时,Cypress会自动截图,你可以轻易的查看每个时间的截图 Debug友好 不需要再去猜测为什么测试有失败了,Cypress提供Chrome DevTools, 所以Debug是非常方便的。 实时刷新 Cypress检测测试用例改变后,会自动刷新 自动等待 不需要在使用wait类似的方法等待某个DOM出现,Cypress会自动帮你做这些 Spies, stubs, and clocks Verify and control the behavior of functions, server responses, or timers....

2018-05-14 10:43:02 · 1 min · Eddie Wang

掌握谷歌搜索高级指令

1. 谷歌搜索指令 2. 基本命令 3. 关键词使用 4. 特殊工具 4.1. define 快速返回关键词定义 4.2. 计算器 4.3. 单位转换 4.4. 时区查询 4.5. 地区查询 4.6. 天气查询 5. 参考 1. 谷歌搜索指令 2. 基本命令 符号 简介 语法 注意点 示例 | 包含A且必须包含B | A +B | A和+之间有空格 | Maxwell +wills | 包含A且不包含B | A -B | A和+之间有空格 | Maxwell -Absolom " " | 完整匹配AB | “AB” | | “Thomas Jefferson” OR | 包含A或者B | A OR B 或者 A | B | | nodejs OR webpack +-“OR | 指令可以组合,完成更复杂的查询 | | | beach -sandy +albert +nathaniel ~ | 包含A, 并且包含B的近义词 | A ~B | | github ~js ....

2018-04-26 16:56:01 · 1 min · Eddie Wang

金钱游戏 - 银行造钱的秘密

1. 角色划分 名称 角色 账户 A 银行家 0 B 建筑商 100万 C 商人 0 2. 建筑商向银行存储100万 名称 角色 账户 A 银行家 100万 现金 B 建筑商 100万 支票 C 商人 0 2. 商人向银行贷款100万 此时银行的账户存款已经是0了,但是B还在银行存了100万。那银行究竟是还有100万呢, 还是一毛都没有了呢。 此时建筑商如果要取现金,那么银行马上就要破产。 名称 角色 账户 A 银行家 100现金 B 建筑商 100万 支票 C 商人 100万 支票 3. 商人需要建筑商来建造房子 商人需要建筑商来建筑房子,费用是100万,付给建筑商,建筑商又把100支票存到银行 名称 角色 账户 A 银行家 100万现金 B 建筑商 200万 支票 C 商人 0 商人又从银行借钱100万,来付给建筑商建房子,建筑商把钱存到银行 名称 角色 账户 A 银行家 100万现金 B 建筑商 300万 支票 C 商人 0 只要这个循环还在继续,你会发现,建筑商的账面上的支票越来越多,但是银行始终都是100万现金存在那里,从来都没动过。...

2018-04-25 13:33:52 · 1 min · Eddie Wang

Express静态文件浏览器缓存设置与缓存清除

1. Express设置缓存 Express设置静态文件的方法很简单,一行代码搞定。app.use(express.static(path.join(__dirname, 'public'), {maxAge: MAX_AGE})), 注意MAX_AGE的单位是毫秒。这句代码的含义是让pulic目录下的所有文件都可以在浏览器中缓存,过期时长为MAX_AGE毫秒。 app.use(express.static(path.join(__dirname, 'public'), {maxAge: config.get('maxAge')})) 2. Express让浏览器清除缓存 缓存的好处是可以更快的访问服务,但是缓存也有坏处。例如设置缓存为10天,第二天的时候服务更新了。如果客户端不强制刷新页面的话,浏览器会一致使用更新前的静态文件,这样会导致一些BUG。你总当每次出问题时,客户打电话给你后,你让他强制刷新浏览器吧? 所以,最好在服务重启后,重新让浏览器获取最新的静态文件。 设置的方式是给每一个静态文件设置一个时间戳。 例如:vendor/loadjs/load.js?_=123898923423"></script> 2.1. Express 路由 // /routes/index.js router.get('/home', function (req, res, next) { res.render('home', {config: config, serverStartTimestamp: new Date().getTime()}) }) 2.2. 视图文件 // views/home.html <script src="vendor/loadjs/load.js?_=<%= serverStartTimestamp %>"></script> 设置之后,每次服务更新或者重启,浏览器都会使用最新的时间戳serverStartTimestamp,去获取静态文件。 2.3. 动态加载JS文件 有时候js文件并不是直接在HTML中引入,可能是使用了一些js文件加载库,例如requirejs, LABjs等。这些情况下,可以在全局设置环境变量SERVER_START_TIMESTAMP,用来表示服务启动的时间戳,在获取js的时候,将该时间戳拼接在路径上。 注意:环境变量SERVER_START_TIMESTAMP,一定要在其他脚本使用前定义。 // views/home.html <script> var SERVER_START_TIMESTAMP = <%= serverStartTimestamp %> </script> // load.js 'vendor/contact-center/skill.js?_=' + SERVER_START_TIMESTAMP

2018-04-08 09:00:48 · 1 min · Eddie Wang

WebSocket断开原因分析

1. 把错误打印出来 WebSocket断开的原因有很多,最好在WebSocket断开时,将错误打印出来。 在线demo地址:https://wdd.js.org/websocket-demos/ ws.onerror = function (e) { console.log('WebSocket发生错误: ' + e.code) console.log(e) } 如果你想自己玩玩WebSocket, 但是你又不想自己部署一个WebSocket服务器,你可以使用ws = new WebSocket('wss://echo.websocket.org/'), 你向echo.websocket.org发送消息,它会回复你同样的消息。 2. 重要信息错误状态码 WebSocket断开时,会触发CloseEvent, CloseEvent会在连接关闭时发送给使用 WebSockets 的客户端. 它在 WebSocket 对象的 onclose 事件监听器中使用。CloseEvent的code字段表示了WebSocket断开的原因。可以从该字段中分析断开的原因。 3. 关闭状态码表 一般来说1006的错误码出现的情况比较常见,该错误码一般出现在断网时。 状态码 名称 描述 0–999 保留段, 未使用. 1000 CLOSE_NORMAL 正常关闭; 无论为何目的而创建, 该链接都已成功完成任务. 1001 CLOSE_GOING_AWAY 终端离开, 可能因为服务端错误, 也可能因为浏览器正从打开连接的页面跳转离开. 1002 CLOSE_PROTOCOL_ERROR 由于协议错误而中断连接. 1003 CLOSE_UNSUPPORTED 由于接收到不允许的数据类型而断开连接 (如仅接收文本数据的终端接收到了二进制数据). 1004 保留. 其意义可能会在未来定义. 1005 CLOSE_NO_STATUS 保留. 表示没有收到预期的状态码. 1006 CLOSE_ABNORMAL 保留. 用于期望收到状态码时连接非正常关闭 (也就是说, 没有发送关闭帧)....

2018-03-29 20:35:38 · 1 min · Eddie Wang

js中的真值和假值

无论什么语言,都需要逻辑,而逻辑中,能否判断出真假,是最基本也是最重要技能之一。 JS中的假值有6个 false '' undefinded null 0, +0, -0 NaN 有点类似假值的真值有两个 {} [] 空对象和空数组,很多初学者都很用把这两个当做假值。但是实际上他们是真值,你只需要记住,除了null之外的所有对象类型的数据,都是真值。 typeof null // 'object' 据说:typeof null返回对象这是一个js语言中的bug。实际上typeof null应该返回null才比较准确,但是这个bug已经存来好久了。几乎所有的代码里都这样去判断。如果把typeof null给改成返回null, 那么这必定会导致JS世界末日。 我们承认JS并不完美,她有很多小缺点,但是这并不妨碍她吸引万千开发者拜倒在她的石榴裙下。 就像一首歌唱的:有些人说不清哪里好 但就是谁都替代不了

2018-03-27 14:31:01 · 1 min · Eddie Wang

在实践中我遇到stompjs, websocket和nginx的问题与总结

1. AWS EC2 不支持WebSocket 直达解决方案 英文版 简单说一下思路:WebSocket底层基于TCP协议的,如果你的服务器基于HTTP协议暴露80端口,那WebSocket肯定无法连接。你只要将HTTP协议修改成TCP协议就可以了。 然后是安全组的配置: 同样如果使用了NGINX作为反向代理,那么NGINX也需要做配置的。 // https://gist.githubusercontent.com/unshift/324be6a8dc9e880d4d670de0dc97a8ce/raw/29507ed6b3c9394ecd7842f9d3228827cffd1c58/elasticbeanstalk_websockets files: "/etc/nginx/conf.d/01_websockets.conf" : mode: "000644" owner: root group: root content : | upstream nodejs { server 127.0.0.1:8081; keepalive 256; } server { listen 8080; location / { proxy_pass http://nodejs; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } "/opt/elasticbeanstalk/hooks/appdeploy/enact/41_remove_eb_nginx_confg.sh": mode: "000755" owner: root group: root content : | mv /etc/nginx/conf....

2018-03-20 22:09:34 · 1 min · Eddie Wang

状态码为200时 jQuery ajax报错

1. 问题现象 HTTP 状态码为 200 OK 时, jquery ajax报错 2. 问题原因 jquery ajax的dataType字段包含:json, 但是服务端返回的数据不是规范的json格式,导致jquery解析json字符串报错,最终导致ajax报错。 jQuery ajax 官方文档上说明: “json”: Evaluates the response as JSON and returns a JavaScript object. Cross-domain “json” requests are converted to “jsonp” unless the request includes jsonp: false in its request options. The JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. As of jQuery 1.9, an empty response is also rejected; the server should return a response of null or {} instead....

2018-03-15 14:17:59 · 1 min · Eddie Wang