好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

好搜移动端页面研究_html/css_WEB-ITnose

首先声明,我并不是好搜员工,研究源码只是爱好,并没有别的意思,下面的代码是在 pc-chrome模拟手机访问时截取的 m.so测试数据,并自己适当的修改了些变量名(因为源码被混淆、压缩了),只是学习用,如果有冒犯贵司之处,还请【联系我】 ,我会第一时间删除~

先看整个无缓存时的源码:源码部分变量我修改过,注释是我根据上下文添加的~

html       360搜索,SO靠谱   wpo={p:"m_so",start:+(new Date),page:"home"}    MSO = {}; SOH = {}; ENV = {};   ENV.android = '6_0'; ENV.webp = '1'; ENV.domain = 'so测试数据'; ENV.abv = 'a'; ENV.nat = '1'; ENV.brandname = '360'; ENV.sitename = '360搜索';  
输出不同的html片段)有耦合 --> (function (e, document) { // 查找id元素 function getId(e) { return document.getElementById(e) } // 给cookie上打个标识,来设置浏览器不支持缓存 function setNotSupportLS() { setCookie("stc_nls", 1, 1) } /** * 读取ls的数据 */ function i(n, r) { var i = ""; // 容错,主要是怕读取出错 try { i = LS[n] || "", // 如果小于99则认为是error,则清空ls版本号 i.length -1 && (i += "; Secure"), // 写入吧,少年 document.cookie = i } /** * 读取id=e的元素内容,写入ls * @param {string} e ls里的key名 * @param {string} t 元素id名 */ function html2ls(e, t) { // 如果元素存在,就获取内容,并去两端空格 var r = getId(t) && getId(t).innerHTML.trim(); setLS(e, r) } /** * 读取ls数据,并生成标签到页面中 */ function ls2html(e, n, r) { var s = i(e, r), o = document.createElement(n); o.innerHTML = s, document.head.appendChild(o) } /** * 清除cookie里的ls版本号 */ function clearLS() { var e = /(?:;)?stc_[^=]*=[^;]*;?/g, n = document.cookie.match(e) || [], r = n.length; while (r) --r, setCookie(n[r].split("=")[0], 0) } /** * 更新版本号,这个很牛b */ function updateVersion(e, t, n) { var r = o(e).split(""), i = !1; // cookie里是以2位版本号紧邻存储,比如: // a文件的一位版本是a,二位版本是b: xxoo=ab // b文件的一位版本是1,二位版本是2: xxoo=ab12 // // 后端在判断是否有缓存时应该也是这样循环,判断b文件版本对否时循环1,然后判断紧邻的版本是不是2,如果是则认为有缓存,否则认为缓存失败 // // 这样的好处是cookie值非常的小,因为最多2个版本,比md5要小 // 但由于位数限制,和只能用 数字+字母+部分符号 做为版本 可能文件数量上有些问题,但对于移动端来说应该完全足够 for (var s = 0, a = r.length; s 输出html真实代码,并设置到ls里,更新版本号,这里是 !U --> /*css*/ LS.html2ls("stc_home_next_css","stc_home_next_css");LS.updateVersion('stc_ls_p_s','!','U') (function (e, t, n) { var r = alert, i = encodeURIComponent, // ... e.onerror = function (e, t, n, r, i) { for (var o = 0; o 4 || l[e]) return; p({ code: "notice", msg: e }), l[e] = 1, ++c }, 1e3) }, e.alert = function (e) { p({ code: "warning", msg: "alert " + e }), !arguments.length && (e = ""), r(e) }})(this, ENV) body{display:none} try { // 设置页面样式,应该有版本区分 document.documentElement.className += " w-" + (localStorage.home_w || 0)}catch (e) {}// 速度打点wpo.head = +(new Date) - wpo.start html{background:#fff} ... // 这里引用了es6-promise库,可见用了很多promise的api// 这里引用了zepto库和一些常用模块// 这里写了个monitor,主要是日志上报模块 LS.html2ls("stc_home_next_base","stc_home_next_base");LS.updateVersion('stc_ls_p_s','T','R') // 这里是webpack.js// 这里是webpack打包后的一些常用模块,应该是so的公用lib:模板引擎、 能用滚动事件、解析url参数、webp图片适配(切图)、图片延迟加载(跟dom有耦合)、节流、https代理(但我试了几个图片发现不管用,应该做了域名白名单或者我姿势不对)// 这里是基于webpack生成的MSO.observer,看代码应该是整个页面的事件驱动,应该有些固定的勾子,比如scroll、show之类,好处是事件统一接管,提供页面hook// 下面有一个牛b的东西登场:window._loader,看意思是个加载器,但她不只是加载器,在代码大概意思是:// 在使用时 _loade.use(uri),然后会首先判断该uri模块有没有被执行:// 如果执行过:则直接执行回调// 如果未执行过:// 读取ls里是否有该uri:// 有:// 判断版本:// 匹配:读取ls并执行回调// 不匹配:执行加载远程操作// 没有:// 直接加载文件,文件的内容类似jsonp,加载成功后会执行回调,并把文件md5+内容写入ls以方便后续使用// 再往下就是些逻辑代码不说了 LS.html2ls("stc_common","stc_common");LS.updateVersion('stc_ls_p_s','(','(')

总结

开发模式

看代码应该是使用的 es6开发,使用 webpack来打包成浏览器端可运行版本,这样开发效果很高,但感觉也并没有使用 es6的全部特性,因为全部特性需要 runtime环境,而这个环境的 shim不小,我看有 promise-shim,感觉应该只用了部分功能,然后转换。但在一定的程度上也可以提高开发效率~

localStorage的应用

使用 localStorage来缓存静态文件的手法很常见,但 so的方式很新颖:

cookie里使用2位版本号存放,这样很能减少 cookie的体积,由其是在流量很大的站 常用模块也使用 localStorage来存在,如果不存在则异步请求,这样也很省流量呢,比如iscroll、城市code数据,你懂的~

之前写的一个: 设计localStorage自动更新

事件管理

整个页面统一由 MSO.observer接管,公用事件统一 trigger(在这里叫 publish),我相信 so内部肯定有这方面的文档,并且有公用事件详细的说明~

比如页面加载完成有 load事件、搜索框聚焦时有 search:focus事件,这样的事件 hook可以很好的使不同模块之间的通信和判断

其他的一些

比如容错做的很好,不至于你关了 cookie或者 ls就报错,还有使用了 webp,并且我看上面有 window.ENV变量,应该是 server端判断了ua信息 输出的

当然还有很多有特我的发现~

查看更多关于好搜移动端页面研究_html/css_WEB-ITnose的详细内容...

  阅读:39次