当我们在讨论前端面试,其实我们在讨论什么?

前言

今天找朋友吃饭,谈起面试方式,他的面试方式是我从来没见过的,直接随便打开一个网站,看 HTML 让你说出技术点,细节,在这个过程中我我更能明白,思考为什么,很重要。

本次打开的网站是掘金

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<head>
<!-- 指定编码 -->
<meta charset="utf-8" />
<!-- 360 等双核浏览器指定 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<!-- 决定视口大小和比例缩放等问题 -->
<meta
name="viewport"
content="width=device-width,initial-scale=1,user-scalable=no,viewport-fit=cover"
/>
<!-- 网站所有权认证 -->
<meta
name="google-site-verification"
content="cCHsgG9ktuCTgWgYfqCJql8AeR4gAne4DTZqztPoirE"
/>
<meta name="apple-itunes-app" content="app-id=987739104" />
<meta name="baidu-site-verification" content="qiK2a1kcFc" />
<meta
name="360-site-verification"
content="4c3c7d57d59f0e1a308462fbc7fd7e51"
/>
<meta name="sogou_site_verification" content="c49WUDZczQ" />
<!-- 全局基本样式 -->
<style>
body {
font-size: 16px;
line-height: 2;
}
a,
button,
input {
margin: 1rem 1.5rem;
}
img {
width: 0;
height: 0;
}
#juejin {
overflow-x: hidden;
}
</style>
<!-- seo 相关 -->
<meta
data-vue-meta="true"
data-vmid="keywords"
name="keywords"
content="掘金,稀土,Vue.js,微信小程序,Kotlin,RxJava,React Native,Wireshark,敏捷开发,Bootstrap,OKHttp,正则表达式,WebGL,Webpack,Docker,MVVM"
/>
<meta
data-vue-meta="true"
data-vmid="description"
name="description"
content="掘金是一个帮助开发者成长的社区,是给开发者用的 Hacker News,给设计师用的 Designer News,和给产品经理用的 Medium。掘金的技术文章由稀土上聚集的技术大牛和极客共同编辑为你筛选出最优质的干货,其中包括:Android、iOS、前端、后端等方面的内容。用户每天都可以在这里找到技术世界的头条内容。与此同时,掘金内还有沸点、掘金翻译计划、线下活动、专栏文章等内容。即使你是 GitHub、StackOverflow、开源中国的用户,我们相信你也可以在这里有所收获。"
/>
<!-- 标题 -->
<title data-vue-meta="true">
掘金 - juejin.im - 一个帮助开发者成长的社区
</title>
<!-- 苹果专用,添加到屏幕的图标 -->
<link
rel="apple-touch-icon"
sizes="180x180"
href="https://b-gold-cdn.xitu.io/favicons/v2/apple-touch-icon.png"
/>
<!-- 各种大小 icon -->
<link
rel="icon"
type="image/png"
sizes="32x32"
href="https://b-gold-cdn.xitu.io/favicons/v2/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="https://b-gold-cdn.xitu.io/favicons/v2/favicon-16x16.png"
/>
<!-- pwa 的 manifest 配置 -->
<link
rel="manifest"
href="https://b-gold-cdn.xitu.io/favicons/v2/manifest.json"
/>
<!-- Safari 专用 icon -->
<link
rel="mask-icon"
href="https://b-gold-cdn.xitu.io/favicons/v2/safari-pinned-tab.svg"
color="#5bbad5"
/>
<link
rel="shortcut icon"
href="https://b-gold-cdn.xitu.io/favicons/v2/favicon.ico"
/>
<!-- 微软专用 -->
<meta
name="msapplication-config"
content="https://b-gold-cdn.xitu.io/favicons/v2/browserconfig.xml"
/>
<!-- 主题颜色,具体作用是浏览器会随之改变的颜色,最好的🌰就是 [Android](https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android) -->
<meta name="theme-color" content="#ffffff" />
<!-- 让浏览器知道我可以搜索 -->
<link
rel="search"
title="掘金"
href="https://b-gold-cdn.xitu.io/conf/search.xml"
type="application/opensearchdescription+xml"
/>
<!-- 各种 css -->
<link
rel="stylesheet"
href="https://b-gold-cdn.xitu.io/ionicons/2.0.1/css/ionicons.min.css"
/>
<link
rel="stylesheet"
href="https://b-gold-cdn.xitu.io/asset/fw-icon/1.0.9/iconfont.css"
/>
<link
href="https://b-gold-cdn.xitu.io/v3/static/css/0.0ecb5f8eb098ca4cba9c.css"
rel="stylesheet"
/>
<!-- 第三方统计 -->
<script
async=""
src="https://hm.baidu.com/hm.js?93bbd335a208870aa1f296bcd6842e5e"
></script>
<script async="" src="//www.google-analytics.com/analytics.js"></script>
<!-- 第三方埋点 -->
<script
type="text/javascript"
async=""
src="https://assets.growingio.com/vds.js"
></script>
<!-- 模块 js -->
<script
charset="utf-8"
src="https://b-gold-cdn.xitu.io/v3/static/js/6.4ab1cd02e9b8f4e56415.js"
></script>
</head>

前面的其实没啥好说,许多是平台支持更好的 seo,一些平台支持的特性等等,下面来点为什么要这样做

  • 但是为什么全局 css 直接写呢?我想可能是少一个 http 请求,反正都是全局
  • 可以看到有些资源使用 hash 来做版本号,其中一个字体图标为什么是使用 1.0.9 这种方式呢?
    在我理解里面就是 hash 绝大概念是 webpack 打包生成的,而字体图标比较用的少手动管理
  • css 和 js 资源前面的 0. 代表什么意思呢?
    应该是模块化打包的问题,原本可能都有名字比如 foo,bar 等等,但是做好混淆和减少无谓字符串就改成数字这种方式
  • 为什么要模块化打包呢?
    主要为了解耦,当我们在开发一个网站的时候会用到很多共同的模块,同时升级网站的时候又会修改很多模块,如果我只改了业务模块,而基本框架没有修改,则可以只升级业务模块即可
  • script async 加载那些不影响 UI 和其他 JavaScript 依赖的 JavaScript,比如埋点和统计

body

  • 元素中十分多data-v-4ff0bc95,具体是干嘛的呢?
    其实是 css in js 的区分方式,那就不需要担心 css 的全局污染问题
    如果是使用 React,在css-loader里面配置modules:true也会有类似效果,只是他直接在 css name 上增加随机后缀

发散

  • 域名大多数同一个,会有什么影响
    之前在输入 URL 到按下 return 发生了什么提过,主要是浏览器 TCP 限制域名发散(就是多个域名,我都没想到这居然有个专有名词),来绕过浏览器同源的并发 TCP 限制问题,但是掘金这边已经使用 http2,基本上能影响到就只有 http2 SETTINGS帧上的SETTINGS_MAX_CONCURRENT_STREAMS限制。
  • http2 server push
    http2 可以通过服务器推送来实现当浏览器请求 html,直接将 css js img 等资源推送,从而提升加载速度
    • 坑点
      • 推送过多资源不太适合,这个需要评估一下什么比较合适
      • 推送页面外的资源,比如列表可以先推送详情页面的一些资源,这一点可以提升‘第一次进入’的体验
      • 需要 H2O 来配置缓存
  • #锚点,文章列表中,点击评论 icon 是带有锚点的,点击会进入到详情页面的评论区域,但是有个问题,spa 数据异步加载如何使用锚点?
    可以在首次加载完成的时候使用 JavaScript 手动定位。
    其实掘金这边没有做好,你实际上点击并不能每个都好良好的定位,主要原因是图片,当定位的时候图片还没加载,并没有撑起整个高度,当图片加载完成位置发生改变,解决办法是后端返回图片长宽
    • 朋友分享的一个坑点
      在 Android 上缓存数据会只记录 URL 而不记锚点,但是 iOS 某些版本上会记录锚点
    • 朋友分享到一个妙用
      通过锚点获取数据,从而实现模版代码缓存,而关键锚点当作数据 ID,因为不会实际请求,从而做到模版通用性缓存
      PS:不得不说这一招实在太特么骚了!

总结

很多地方可能还没讲到,套用我老大一句话,前端就是各种琐碎的知识拼凑一起,许多地方其实不难,主要是说,真的面试的话,这样给你一个题目,能想到什么可以讲的?或者说等到面试官问你的时候,你能想到什么?如果再深入一点,又能想到什么?