Posted on

通过 rel=noopener 属性进行性能优化

当你通过打开新标签的方式跳转页面时,最好给 a 标签加上 rel=”noopener” 属性,特别是在调往其他域的页面的时候。

代码如下:

<a href=”http://example.com” target=”_blank” rel=”noopener”>
Example site
</a>

从安全上看:

如果没有添加这个属性,那么新页面可以通过 window.opener 变量访问原来的页面,虽然受限于跨域安全机制,新页面不能读取老页面信息,但是新页面可以通过 window.opener.location = newURL 来修改老页面连接,让其跳转到其他页面。

从性能上看:

另外一个重要的问题是,如果仅仅通过 target=”_blank” 标签从新标签打开页面。新老页面将运行在同一个进程上,如果新老页面上有运行大量计算任务的脚本时,新老页面的性能都会受到影响。

还有要注意的点,在老的浏览器中,rel=noreferrer 除了禁用 window.opener 外,还一并禁用了 HTTP 头部 的 Referer 属性,会对页面打点等功能造成影响,可以通过

var otherWindow = window.open(); 
otherWindow.opener = null; 
otherWindow.location = url;

的方式进行规避。但是这样的话又会引入新的问题。这个方法在 safari 下会因为弹出机制被拦截。

参考文章:
https://developers.google.com/web/tools/lighthouse/audits/noopener?hl=zh-cn
https://jakearchibald.com/2016/performance-benefits-of-rel-noopener/
https://mathiasbynens.github.io/rel-noopener/#hax
http://lists.w3.org/Archives/Public/public-whatwg-archive/2015Jan/0002.html
http://www.jdon.com/idea/target-blank.html
https://my.oschina.net/dawd/blog/816023

Posted on

webpack 3 脚手架 tapable 依赖错误问题修复

负责公司 vue 项目脚手架维护,有段时间没改过脚手架,最近对脚手架进行依赖升级,防止依赖腐化导致后面升级维护困难。

结果发现项目直接跑不起来了。排查后发现遇到了 webpack 升级 4 后升级了依赖的 tapable 组件的版本,并且和老版本不兼容,而 webpack 3 中依赖 tapable 没有指定版本号,导致依赖 webpack 3 的很多项目都跪了的问题。强制指定 tapable 版本号到 0.2.5 后问题修复。

Posted on

前端用户行为打点方案

背景

网站访问量大了以后,运营希望收集部分用户行为记录,用来分析预测用户偏好,进行针对性的优化。

方案

1、先要确定要收集哪些行为

根据我们公司的情况,这里确定了要收集用户鼠标点击,手指移动起始位置,和表单获取焦点的行为。除此之外,还有用户键盘输入等行为可以记录,可以选择性的增加。

2、确定上报的方式

上报是通过将行为数据提交到一个后端接口进行记录。为了避免实时的提交数据,造成无必要的性能损耗,可以将行为数据存储到一个列表中,每隔一段时间,从列表中获取一定数量的数据进行提交。

用户行为数据可能会比较多,选择间隔时间提交固定数量的行为数据后,可能会有部分数据在用户离开页面之前,无法有效的提交到后端。这时候,需要在用户离开页面之前,将剩下未提交的数据全部都一起提交了。但是有个问题,用户离开页面的时候,如果再触发 ajax 去提交数据,ajax 很大概率会被中断,导致数据提交失败。所以这里采用的方案是,在 window 的 unload 事件里把剩下的行为数据存储到 localStorage 之中。然后再访问下一个页面,或者下次访问同域的页面的时候,在用户第一次触发点击行为的时候合并 localStorage 里的数据一次性提交到后端。

不过存放到 localStorage 的方式也无法保障能提交所有的数据。在用户关闭浏览器 tab,或者浏览器 crash 的时候,window 的 unload 是不会触发的。并且不是所有浏览器都支持 window unload 事件。支持请见 http://w3help.org/zh-cn/causes/SD9026

为了通用性,提交数据可以使用跨域支持的 new Image() 方式

3、确定数据存储格式

前面提到要将数据存储到列表中,所以需要确定下数据存储格式。
点击和移动需要记录点击事件的 screenX, screenY, pageX, pageY 还有时间和事件名。

基本是这样的,逻辑确定好后,实现也比较简单了,实际写下来 200 行左右的代码。

Posted on

IOS 模拟器命令行使用方法

背景

在公司写完页面之后要先自己测试页面的兼容性,作为非测试的同学,手头没有那么多的测试机可以用,所以很多情况下需要使用模拟器进行测试。

默认情况下使用 IOS 模拟器比较麻烦,在使用模拟器之前

1、首先需要安装 Xcode 编辑器,模拟器是作为 xcode 的一个子组件出现的。

2、装好后,打开 Xcode,在首选项里选择安装模拟器。

安装好模拟器后,通过下面的命令进行启动调试

1、查看设备列表 simctl list devices 命令

2、启动模拟器, open -a Simulator –args -CurrentDeviceUDID $设备ID

3、安装程序包 simctl install booted $程序安装包绝对路径

4、启动程序 simctl launch booted $程序包名

5、打开需要调试的页面, simctl openurl booted $唤起短链

6、电脑上打开 safari 浏览器,点击开发目中的模拟器,选择模拟器中的运行的页面

7、关闭模拟器,killall Simulator 命令

下面是模拟器中一些常用的快捷:

1、回到桌面:⌘+⇧+H

2、模拟器缩放:⌘+1、⌘+2、⌘+3、⌘+4、⌘+5,对应缩放100%、75%、50%、33%、25% 大小

3、锁屏&解锁屏:⌘+L

另外一个注意的要点是,模拟器中的代理与 mac 系统的代理是同步的。

代码溜的同学,可以对这些命令做一个封装,比如用前端常用的 nodejs 来处理。

写起来也比较简单,主要使用 commander 和 prompt 包,实现命令行和交互功能。

Posted on

Could not create lock at /var/run/yum.pid: [Errno 28] 问题修复

环境:
Linux VM_185_189_centos 3.10.0-514.21.1.el7.x86_64 #1 SMP Thu May 25 17:04:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

执行 yum update -y ,发生报错

Could not create lock at /var/run/yum.pid: [Errno 28]

执行 ps aux | grep yum 查看是否有进程冲突,发现没有。

查 google 发现是 centos 的 bug ,需要重启修复问题。

reference:
https://www.davidvandertuijn.nl/could-not-create-lock-at-varrunyumpid-errno-28-no-space-left-on-device
https://bugs.centos.org/view.php?id=14278

Posted on

debian 9 安装 docker 教程

环境
Debian Stretch 9
uname -a => Linux VM-1-242-debian 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2 (2017-06-12) x86_64 GNU/Linux

1、卸载老版本:sudo apt-get remove docker docker-engine docker.io
2、更新仓库: sudo apt-get update
3、安装可以使 apt 运行在 https 协议上的依赖:sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
4、添加 docker 官方 GPG key:curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo “$ID”)/gpg | sudo apt-key add -。简单介绍下,这里的 GPG key 是公钥,用来解密加密的 docker 安装包。这是在网上安全传播发布的软件的一种方式。
5、验证 GPG key 正确安装:sudo apt-key fingerprint 0EBFCD88,看输出中 Key fingerprint 是否为 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
6、添加 docker 仓库 sudo add-apt-repository “deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo “$ID”) $(lsb_release -cs) stable”,如果想安装 edge 或者 测试版,可以在 stable 后面加 edge 和 test
7、再次执行 sudo apt-get update 更新新添加仓库里的信息。
8、sudo apt-get install docker-ce 安装 docker,如果第六步中添加了 edge 版本,那这个命令安装的是最新版本,而不是稳定版本。在生产环境里建议安装最新的稳定版本。可以通过 sudo apt-get install docker-ce=版本号 进行安装。版本号可以通过 apt-cache madison docker-ce 命令获取。
9、验证安装成功 sudo docker run hello-world。
10、卸载 sudo apt-get purge docker-ce && sudo rm -rf /var/lib/docker

reference:
https://docs.docker.com/install/linux/docker-ce/debian/

Posted on

小米手机 adb 调试无法识别问题解决

今天开发的一个页面在公司 App 安卓版本中测试发现有些问题。页面使用一种叫 xcore 的技术实现,在公司 App 中使用公司定制的内核渲染。定制的内核基于腾讯的 x5 浏览器内核。本来公司有自己开发的一套真机页面测试软件,但是疏于维护,已经废弃停止使用了。App 团队的同学推荐使用腾讯的 TBS_Studio 来测试。调试工具有了,还缺少一台安卓机子,从测试团队借来一只超级大的小米手机,不记得什么型号了。

1、需要在手机上调试,先要开启调试模式吧,手机上找系统版本号,点击 6 下开启开发者模式。

2、开启开发者模式后还需要开启 USB 调试模式:“设置”-“其他高级设置”-“开发者选项”-“USB调试”

一般情况下这样子就可以了,至少前几年是这样子,好几年没开发 H5 页面,没想到发生了这么多变化。

设置完上面两步之后,发现 TBS_Studio 还是无法识别这个小米手机。继续往上查找解决方案。

3、发现新的小米系统里,开启USB调试模式后还要开启调试端口:保持手机连接在电脑上,然后在拨号界面输入 *#*#717717#*#* ,输入完成之后会看到 “Diag USB port enable” 的弹出提示,表示端口已经成功开启。

4、在电脑命令窗口中 adb kill-server,然后 adb start-server,重启 adb 服务,最后 adb devices,就可以看到设备啦

TBS_Studio 底层的连接肯定也是使用 adb 啊,adb devices 里看到了设备,TBS_Studio 自然是成功的连上了

Posted on

服务器 ssh 自动断开问题

有好几种解决方案

1、最不好的一种,设置终端超时自动输入字符。对 iTerm 而言 Profile 的 Session tab 里面可以设置。缺点很明显,超时时会自动输入字符影响使用。

2、客户端 ssh 配置定时保持连接,方法是修改 ~/.ssh/config 文件,加入
Host *
ServerAliveInterval=60

这样每 60 秒给服务器发送一个 no-op 包用来保持连接。

3、对单次连接可以使用 ssh -o ServerAliveInterval=30 user@host 命令来传递 ServerAliveInterval 参数

4、服务端 ssh 配置,方法是修改 /etc/ssh/sshd_config 文件,取消
TCPKeepAlive yes
ClientAliveInterval 30
ClientAliveCountMax 3
5、行代码的注释开启定时发包保持连接的功能。记得重启 ssh 服务激活配置。

6、当然还有更高级的技术。可以试试 mosh,除了保持连接外,还可以实现自动连接。需要分别在服务器和客户端安装软件。

2018-03-08 15:31:14

既然讲到了 mosh,讲下怎么安装吧。其实很简单,三行命令,以 debian 服务器,mac 客户机为例:

1、服务端安装 apt-get install mosh
2、配置语言 vim ~/.bashrc 添加 export LC_ALL=”en_US.UTF-8″,source ~/.bashrc
3、客户端 brew install mosh

下面就可以使用了

mosh user@host

Posted on

wordpress 不建议给has_cap传入一个参数问题修复

装了几个插件发现 wordpress 后台报了下面的错误:

不建议给has_cap传入一个参数!用户级别已被废弃,请改用能力。 in /usr/share/wordpress/wp-includes/functions.php on line 4031

检查发现是 baidu sitemap 插件引起的,将

add_options_page(“Baidu-Sitemap”,”Baidu-Sitemap”, 8, __FILE__, ‘baidu_sitemap_optionpage’);

里的 8 改成 ‘manage_options’ 就可以修复问题

add_options_page(“Baidu-Sitemap”,”Baidu-Sitemap”, ‘manage_options’, __FILE__, ‘baidu_sitemap_optionpage’);

Posted on

h5py FutureWarning 问题修复

h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
from ._conv import register_converters as _register_converters

h5py 和 numpy 版本冲突,h5py 官方已修复合并到 master 分支,但是还没发新版,在发版之前可以用降级 numpy 的方法跳过这个问题。降级命令如下:

pip install numpy==1.13.0

referece:
https://stackoverflow.com/questions/48340392/futurewarning-conversion-of-the-second-argument-of-issubdtype-from-float-to