2020-06-03 html的webp图片格式 + css 的声明块 + js的delete函数 + 工作流程混乱

本文深入探讨了WebP图片格式的优势与局限性,包括其压缩算法、支持的特性以及在不同场景下的应用策略。

# 2020-06-03 题目来源:http://www.h-camel.com/index.html

# [html] 你有使用过webp的图片格式吗?
    webp是一种新兴的图片格式,优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;
    同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都非常优秀、稳定和统一。
    webp的优点:
    1. 同等质量但是图片更小
    2. 压缩后质量无明显变化
    3. 完美支持无损图像
 
    webp的缺点:
    1. 相比于jpg 编码速度慢10倍,解码速度慢1.5倍,但是由于文件体积的减少,加载速度会变快,渲染速度也变快了。
    2. 支持性上面,目前桌面浏览器chrome和opera浏览器,手机支持原生android和android系统上的chrome浏览器。
    3. 目前不被任何操作系统原生支持。
    
    webp应用:
    1. 浏览器场景
    javascript能力检测,对支持webp的用户输出webp图片
    使用webp支持插件
    2. app场景
    3. 后台场景(Webp的转换)

# [css] 假如css的分号写在声明块之外,将会发生什么呢?解释下原因
      
    <style>
        p {color: blue};
        .p1 {color: red}
        .p2 {color: green}
    </style>
    
    <p class="p1">红色字体</p>
    <p class="p2">绿色字体</p>

    现象是: 紧跟着 ; 的第一个声明块的样式不会生效,第二个及第二个以后的声明块的样式正常。

# [js] 使用delete删除数组,其长度会改变吗?
 
    delete(array)[index]--删除后数组的长度不会改变


        

# [软技能] 如果给你接手团队的管理,团队内部的流程很乱你该怎么办?
     引入合适的协同办公软件,建立奖励机制,提高员工积极性

user www-data; pid /run/nginx.pid; # 加载动态模块(必须放在最顶部) load_module modules/ngx_http_brotli_filter_module.so; load_module modules/ngx_http_brotli_static_module.so; events { worker_connections 2048; multi_accept on; use epoll; } http { # 基础设置 sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server_tokens off; client_max_body_size 20M; # 文件描述符缓存 open_file_cache max=10000 inactive=30s; open_file_cache_valid 60s; open_file_cache_min_uses 2; open_file_cache_errors off; # 大文件传输优化 directio 4m; output_buffers 4 512k; aio threads; # MIME类型 include /etc/nginx/mime.types; include /etc/nginx/conf.d/*.conf; default_type application/octet-stream; # 日志格式 log_format main &#39;$remote_addr - $remote_user [$time_local] &#39; &#39;"$request" $status $body_bytes_sent &#39; &#39;"$http_referer" "$http_user_agent"&#39;; log_format timing_debug &#39;$remote_addr - $remote_user [$time_local] &#39; &#39;"$request" $status $body_bytes_sent &#39; &#39;ReqTime=$request_time UpstreamTime=$upstream_response_time &#39; &#39;ConnectTime=$upstream_connect_time &#39; &#39;DNSResolve=$upstream_cache_status &#39; &#39;Proto=$server_protocol Host="$host" &#39; &#39;UA="$http_user_agent" &#39; &#39;Encoding=$sent_http_content_encoding&#39;; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log warn; access_log /var/log/nginx/time_monitor.log timing_debug; # SSL优化 ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; # 压缩配置 gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_min_length 1024; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml application/xml+rss image/svg+xml; brotli on; brotli_comp_level 6; brotli_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml application/xml+rss image/svg+xml; # 主服务器配置 server { listen 443 ssl http2; server_name login.coolla.online; # SSL证书配置 ssl_certificate /etc/letsencrypt/live/login.coolla.online/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/login.coolla.online/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; root /www/data1; index index.html; http2_max_concurrent_streams 128; # 压缩头设置 add_header Content-Encoding-Mirror "br,gzip"; # Certbot验证目录 location ^~ /.well-known/acme-challenge/ { allow all; root /var/www/certbot; default_type "text/plain"; } # API代理配置 location /api { proxy_pass http://172.31.85.246:8080/api; 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; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Authorization $http_authorization; proxy_set_header Cookie $http_cookie; proxy_pass_request_headers on; proxy_connect_timeout 60s; proxy_read_timeout 300s; # CORS配置 add_header &#39;Access-Control-Allow-Origin&#39; &#39;*&#39;; add_header &#39;Access-Control-Allow-Methods&#39; &#39;GET, POST, OPTIONS&#39;; add_header &#39;Access-Control-Allow-Headers&#39; &#39;DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range&#39;; add_header &#39;Access-Control-Expose-Headers&#39; &#39;Content-Length,Content-Range&#39;; if ($request_method = &#39;OPTIONS&#39;) { return 204; } } location / { try_files $uri $uri/ /index.html; } # 静态资源优化配置 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff2|html|json)$ { expires 1y; add_header Cache-Control "public, immutable, max-age=31536000"; access_log off; # 压缩文件支持 brotli_static on; gzip_static on; gunzip on; # 文件查找顺序:原始文件 > brotli > gzip try_files $uri $uri.br $uri.gz =404; # 文件缓存优化 open_file_cache max=5000 inactive=1h; open_file_cache_valid 60s; open_file_cache_min_uses 3; open_file_cache_errors off; # 性能优化 etag off; if_modified_since exact; tcp_nodelay on; } # 8080端口耗时监控端点 location = /api/time-monitor { internal; proxy_pass http://localhost:8080; proxy_set_header X-Request-Start "t=${msec}"; proxy_connect_timeout 2s; proxy_read_timeout 5s; proxy_send_timeout 3s; allow 127.0.0.1; allow 192.168.1.0/24; deny all; add_header X-Time-Monitor "active"; add_header Cache-Control "no-cache"; if ($arg_debug = "1") { add_header X-Debug-Info "Timing: $request_time/$upstream_response_time"; } } # 安全设置 location ~ /\. { deny all; access_log off; log_not_found off; } } # 8082端口监控服务 server { listen 8082; server_name _; root /www/manager; index index.html index; # 静态资源 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff2)$ { expires 1y; add_header Cache-Control "public, immutable, max-age=31536000"; access_log off; brotli_static on; gzip_static on; gunzip on; try_files $uri $uri.br $uri.gz =404; } location / { try_files $uri $uri/ /index.html; } location /prod-api/ { proxy_pass http://localhost:8080/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location ~ /\. { deny all; access_log off; log_not_found off; } } # HTTP重定向到HTTPS server { listen 80; server_name login.coolla.online; location ^~ /.well-known/acme-challenge/ { allow all; root /var/www/certbot; default_type "text/plain"; } location /api { proxy_pass http://localhost:8080/api; } location / { return 301 https://$host$request_uri; } location /error/ { alias /www/error/; index index.html; try_files $uri $uri/ /error/index.html; location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff2)$ { brotli_static on; gzip_static on; try_files $uri $uri.br $uri.gz =404; } } } # 默认服务器配置 server { listen 80 default_server; server_name _; location /error { alias /www/error/; index index.html; try_files $uri $uri/ /error/index.html; location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff2)$ { brotli_static on; gzip_static on; try_files $uri $uri.br $uri.gz =404; autoindex off; disable_symlinks off; if (!-f $request_filename) { return 404; } } } error_page 404 /404.html; location = /404.html { internal; root /usr/share/nginx/html; } error_page 500 502 503 504 /50x.html; location = /50x.html { internal; root /usr/share/nginx/html; } } } 这是我的配置文件#!/bin/bash # 日志函数定义 log_info() { echo "ℹ️ [$(date &#39;+%Y-%m-%d %H:%M:%S&#39;)] $1" } log_success() { echo "✅ [$(date &#39;+%Y-%m-%d %H:%M:%S&#39;)] $1" } log_error() { echo "❌ [$(date &#39;+%Y-%m-%d %H:%M:%S&#39;)] $1" >&2 exit 1 } # 配置变量 REPO_URL="https://gitee.com/bizbutler_enterprise/bizbutlerbackweb.git" TARGET_DIR="/www/wj/bizbutlerbackweb" GIT_USER="donghaige" GIT_TOKEN="5d87a6d59233aaac1f08a269f3584c2b" BRANCH="master" PROD_DIR="/www/data1" # Nginx配置 NGINX_SERVICE="nginx" NGINX_CONFIG_TEST="nginx -t" NGINX_RESTART="systemctl restart nginx" # 压缩配置 COMPRESS_EXTENSIONS=("js" "css" "html" "json" "svg" "webp" "woff2" "png" "jpg" "jpeg" "ico") BROTLI_LEVEL=11 GZIP_LEVEL=9 # 智能压缩函数 compress_static_assets() { local dir="$1" cd "$dir" || return 1 log_info "开始压缩静态资源..." # 清理旧压缩文件 find . -type f \( -name "*.br" -o -name "*.gz" \) -delete log_success "已清理旧压缩文件" # 压缩处理 for ext in "${COMPRESS_EXTENSIONS[@]}"; do log_info "处理 .$ext 文件..." # Brotli压缩 find . -type f -name "*.$ext" ! -name "*.br" -print0 | xargs -0 -r -P $(nproc) -I {} brotli -k -q $BROTLI_LEVEL "{}" # Gzip压缩 find . -type f -name "*.$ext" ! -name "*.gz" -print0 | xargs -0 -r -P $(nproc) -I {} gzip -k -$GZIP_LEVEL "{}" done # 统计结果 BR_COUNT=$(find . -type f -name "*.br" | wc -l) GZ_COUNT=$(find . -type f -name "*.gz" | wc -l) log_success "压缩完成: $BR_COUNT 个 .br 文件, $GZ_COUNT 个 .gz 文件" cd - >/dev/null || return 1 } log_info "======= 开始构建部署 =======" # 1. 清理并重新克隆代码 log_info "步骤1: 清理旧代码并重新克隆仓库 (分支: $BRANCH)" if [ -d "$TARGET_DIR" ]; then log_info "删除现有目录: $TARGET_DIR" rm -rf "$TARGET_DIR" || log_error "删除目录失败: $TARGET_DIR" fi mkdir -p "$TARGET_DIR" || log_error "创建目录失败: $TARGET_DIR" cd "$TARGET_DIR" || log_error "进入目录失败: $TARGET_DIR" REPO_AUTH_URL="https://${GIT_USER}:${GIT_TOKEN}@gitee.com/bizbutler_enterprise/bizbutlerbackweb.git" git clone -b "$BRANCH" "$REPO_AUTH_URL" . || log_error "克隆仓库失败" COMMIT_ID=$(git rev-parse --short HEAD) log_success "仓库重新克隆完成! 提交ID: $COMMIT_ID" # 2. 安装依赖 log_info "步骤2: 安装npm依赖" npm install || log_error "npm安装失败" log_success "依赖安装完成" # 3. 构建项目 log_info "步骤3: 构建项目" npm run build || log_error "项目构建失败" log_success "项目构建完成" # 4. 部署到生产环境 log_info "步骤4: 部署到生产环境" mkdir -p "$PROD_DIR" || log_error "创建生产目录失败: $PROD_DIR" rm -rf "$PROD_DIR"/* || log_error "清理生产目录失败" cp -r dist/* "$PROD_DIR" || log_error "文件复制失败" log_success "静态文件已复制到生产目录" # 5. 预压缩静态资源 compress_static_assets "$PROD_DIR" # 6. 设置文件权限 log_info "设置文件权限" chown -R www-data:www-data "$PROD_DIR" find "$PROD_DIR" -type f -exec chmod 644 {} \; find "$PROD_DIR" -type d -exec chmod 755 {} \; log_success "权限设置完成" # 7. 完成检查 FILE_COUNT=$(find "$PROD_DIR" -type f ! -name "*.br" ! -name "*.gz" | wc -l) log_info "生产目录检查:" log_info "- 原始文件数: $FILE_COUNT" log_info "- 压缩文件数: $(find "$PROD_DIR" -type f \( -name "*.br" -o -name "*.gz" \) | wc -l)" if [ "$FILE_COUNT" -eq 0 ]; then log_error "生产目录为空,部署失败" fi log_success "生产目录文件检查通过" # 8. Nginx 重启 log_info "步骤8: 重启Nginx服务" log_info "执行配置检查: $NGINX_CONFIG_TEST" if ! $NGINX_CONFIG_TEST; then log_error "Nginx配置测试失败" fi log_success "Nginx配置验证通过" log_info "执行服务重启: $NGINX_RESTART" if ! $NGINX_RESTART; then log_error "Nginx重启失败" fi if ! systemctl is-active --quiet "$NGINX_SERVICE"; then log_error "Nginx服务未运行!" fi log_info "Nginx进程信息:" pgrep -a nginx | head -5 log_success "Nginx重启成功! 新PID: $(systemctl show -p MainPID nginx | cut -d= -f2)" # 完成报告 log_success "======= 部署成功! =======" log_success "✅ 项目位置: $TARGET_DIR" log_success "✅ 生产目录: $PROD_DIR" log_success "✅ 提交版本: $COMMIT_ID" log_success "✅ 压缩文件: $(find "$PROD_DIR" -type f \( -name "*.br" -o -name "*.gz" \) | wc -l) 个" log_success "✅ Nginx状态: $(systemctl is-active $NGINX_SERVICE)" log_success "✅ 完成时间: $(date &#39;+%Y-%m-%d %H:%M:%S&#39;)" 这是我的脚本
最新发布
08-07
### 静态资源优化配置与部署流程 #### 1. Nginx 配置静态资源优化 Nginx 在处理静态资源时具有高性能优势,通过合理配置可以显著提升资源访问速度。以下是一个综合优化配置示例: ```nginx server { listen 80; server_name example.com; location ~* \.(js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$ { expires 30d; add_header Cache-Control "public, no-transform"; gzip_static on; add_header Vary Accept-Encoding; } location ~ \.br$ { add_header Content-Encoding br; add_header Vary Accept-Encoding; } gzip on; gzip_min_length 200; gzip_buffers 32 4k; gzip_http_version 1.1; gzip_comp_level 6; gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/font-woff; gzip_vary on; brotli on; brotli_comp_level 6; brotli_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/font-woff; brotli_static on; } ``` 该配置包括静态资源缓存、Gzip 压缩、Brotli 压缩等优化措施,确保资源传输更高效[^1]。 #### 2. 部署脚本 在部署流程中,自动化脚本可以提升部署效率并减少人为错误。以下是一个使用 Shell 编写的部署脚本示例: ```bash #!/bin/bash # 定义变量 STATIC_DIR="/var/www/html" NGINX_CONF="/etc/nginx/conf.d/default.conf" BACKUP_DIR="/var/www/backup" # 创建备份目录 mkdir -p $BACKUP_DIR # 备份当前配置 cp $NGINX_CONF $BACKUP_DIR/ # 替换 Nginx 配置 cat > $NGINX_CONF << EOF server { listen 80; server_name example.com; location ~* \.(js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$ { expires 30d; add_header Cache-Control "public, no-transform"; gzip_static on; add_header Vary Accept-Encoding; } location ~ \.br$ { add_header Content-Encoding br; add_header Vary Accept-Encoding; } gzip on; gzip_min_length 200; gzip_buffers 32 4k; gzip_http_version 1.1; gzip_comp_level 6; gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/font-woff; gzip_vary on; brotli on; brotli_comp_level 6; brotli_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/font-woff; brotli_static on; } EOF # 重启 Nginx systemctl restart nginx # 设置权限 chown -R nginx:nginx $STATIC_DIR chmod -R 755 $STATIC_DIR ``` 该脚本将自动备份 Nginx 配置、替换为优化后的配置,并设置静态资源目录权限[^2]。 #### 3. 压缩设置 Nginx 支持 Gzip 和 Brotli 两种主流压缩方式,两者可以同时启用以兼容不同客户端。Gzip 是广泛支持的压缩方式,而 Brotli 提供更高的压缩率,尤其适合现代浏览器。以下是如何在 Nginx 中启用 Brotli 的配置: ```nginx brotli on; brotli_comp_level 6; brotli_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/font-woff; brotli_static on; ``` 启用 Brotli 需要安装 Nginx 的 Brotli 模块,并确保服务器支持该功能。 #### 4. 缓存设置 浏览器缓存是提升静态资源访问速度的重要手段。通过 `Cache-Control` 和 `Expires` 头部,可以控制浏览器缓存策略。以下是一个典型的缓存配置: ```nginx location ~* \.(js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$ { expires 30d; add_header Cache-Control "public, no-transform"; } ``` 该配置将静态资源缓存时间设置为 30 天,并允许公共缓存,适用于 CDN 等场景。 #### 5. 权限管理 为了确保静态资源的安全性和可访问性,需对资源目录进行严格的权限控制。以下命令用于设置目录权限: ```bash chown -R nginx:nginx /var/www/html chmod -R 755 /var/www/html ``` 上述命令将静态资源目录的所有者设置为 `nginx` 用户组,并设置目录权限为 755,确保 Nginx 进程可读取文件[^2]。 #### 6. 部署流程 完整的静态资源优化部署流程如下: 1. **开发阶段**:使用 Webpack 或其他构建工具对静态资源进行压缩、合并、按需加载等优化。 2. **测试阶段**:本地或测试服务器部署,验证资源加载性能。 3. **打包阶段**:生成静态资源包,包含压缩后的 CSSJS、图片等文件。 4. **部署阶段**:执行部署脚本,替换 Nginx 配置,重启服务。 5. **监控阶段**:通过日志和性能监控工具(如 Google PageSpeed Insights)评估优化效果。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值